From 5d55b67c3aa9630bd77138598ea16af0f14c1d47 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Wed, 25 Mar 2020 17:59:03 +0400 Subject: [PATCH] Update comment decryption UI --- Makefile | 6 +- Telegram/BUILD | 78 ++- Wallet.makefile | 50 +- Wallet/BUILD | 212 +++++-- Wallet/Wallet.entitlements | 6 - Wallet/Wallet.mobileprovision | Bin 7449 -> 0 bytes .../bazel-utils/BUILD | 0 build-system/{ => bazel-utils}/defines.bzl | 0 .../{ => bazel-utils}/plist_fragment.bzl | 2 +- .../{ => bazel-utils}/unique_directories.bzl | 0 ...=> copy-provisioning-profiles-Telegram.sh} | 0 .../copy-provisioning-profiles-Wallet.sh | 104 ++++ build-system/generate-xcode-project.sh | 35 +- ...sh => prepare-build-variables-Telegram.sh} | 0 .../prepare-build-variables-Wallet.sh | 63 ++ build-system/prepare-build.sh | 25 +- build-system/xcode_version | 2 +- .../Sources/AnimatedStickerNode.swift | 2 +- .../Source/ActionSheetSwitchItem.swift | 1 - .../ContainedViewLayoutTransition.swift | 3 +- .../Source/ContextContentContainerNode.swift | 1 - .../Source/ContextContentSourceNode.swift | 1 - .../Source/ContextControllerSourceNode.swift | 1 - .../Display/Source/ContextGesture.swift | 3 +- submodules/Display/Source/Font.swift | 2 +- submodules/Display/Source/GridNode.swift | 12 +- submodules/Display/Source/ImageCorners.swift | 90 +-- submodules/Display/Source/KeyShortcut.swift | 5 +- submodules/Display/Source/ListView.swift | 20 +- .../Display/Source/NativeWindowHostView.swift | 29 +- .../Navigation/NavigationContainer.swift | 16 +- .../Navigation/NavigationController.swift | 9 +- .../Source/NavigationBackButtonNode.swift | 2 +- submodules/Display/Source/NavigationBar.swift | 4 +- .../Display/Source/NavigationButtonNode.swift | 15 +- .../Display/Source/NavigationTitleNode.swift | 2 +- .../Source/TransformImageArguments.swift | 2 +- submodules/Display/Source/UIKitUtils.swift | 2 +- .../Display/Source/ViewController.swift | 12 - .../Source/WallpaperBackgroundNode.swift | 1 - submodules/Display/Source/WindowContent.swift | 10 +- submodules/LocalAuth/Sources/LocalAuth.swift | 14 +- submodules/QrCode/Sources/QrCode.swift | 4 +- submodules/RMIntro/BUILD | 2 +- .../SwiftSignalKit/Source/Disposable.swift | 2 +- .../Source/Signal_Dispatch.swift | 8 +- .../SwiftSignalKit/Source/ThreadPool.swift | 6 +- .../Sources/ScreenCaptureDetection.swift | 8 +- .../Sources/SolidRoundedButtonNode.swift | 2 +- submodules/TonBinding/Sources/TON.h | 15 +- submodules/TonBinding/Sources/TON.mm | 60 +- .../WalletCore/Sources/WalletCore.swift | 45 +- submodules/WalletUI/BUILD | 4 + .../Items/ItemListMultilineTextItem.swift | 10 +- .../WalletUI/Sources/WalletAmountItem.swift | 1 - .../Sources/WalletConfgurationScreen.swift | 32 +- .../Sources/WalletCreateInvoiceScreen.swift | 15 +- .../Sources/WalletInfoEmptyNode.swift | 6 +- .../WalletUI/Sources/WalletInfoScreen.swift | 47 +- .../Sources/WalletInfoTransactionItem.swift | 10 +- .../WalletUI/Sources/WalletQrScanScreen.swift | 2 +- .../Sources/WalletReceiveScreen.swift | 13 +- .../WalletUI/Sources/WalletRefreshNode.swift | 12 +- .../WalletUI/Sources/WalletSendScreen.swift | 21 +- .../Sources/WalletSettingsScreen.swift | 9 - .../WalletUI/Sources/WalletSplashScreen.swift | 53 +- .../Sources/WalletTransactionInfoScreen.swift | 152 ++++- submodules/WalletUI/Sources/WalletUtils.swift | 1 - .../Sources/WalletWordDisplayScreen.swift | 9 +- submodules/lottie-ios/BUILD | 2 +- .../ton/tonlib-src/crypto/CMakeLists.txt | 3 +- submodules/ton/tonlib-src/crypto/Ed25519.cpp | 10 +- submodules/ton/tonlib-src/crypto/Ed25519.h | 4 +- .../tonlib-src/crypto/block/block-auto.cpp | 463 +++++++++++++- .../ton/tonlib-src/crypto/block/block-auto.h | 231 ++++++- .../tonlib-src/crypto/block/block-parse.cpp | 20 +- .../ton/tonlib-src/crypto/block/block-parse.h | 25 +- .../ton/tonlib-src/crypto/block/block.cpp | 58 +- .../ton/tonlib-src/crypto/block/block.h | 3 +- .../ton/tonlib-src/crypto/block/block.tlb | 14 +- .../tonlib-src/crypto/block/create-state.cpp | 49 ++ .../ton/tonlib-src/crypto/block/mc-config.cpp | 54 ++ .../ton/tonlib-src/crypto/block/mc-config.h | 17 + .../tonlib-src/crypto/block/transaction.cpp | 44 +- .../ton/tonlib-src/crypto/block/transaction.h | 1 + .../ton/tonlib-src/crypto/common/linalloc.hpp | 50 ++ .../ton/tonlib-src/crypto/common/refint.cpp | 18 + .../ton/tonlib-src/crypto/common/refint.h | 2 + .../ton/tonlib-src/crypto/fift/lib/Asm.fif | 173 ++++-- .../ton/tonlib-src/crypto/fift/lib/Fift.fif | 7 + .../ton/tonlib-src/crypto/fift/lib/Lists.fif | 36 ++ .../tonlib-src/crypto/fift/lib/TonUtil.fif | 63 +- .../ton/tonlib-src/crypto/fift/words.cpp | 34 +- .../ton/tonlib-src/crypto/func/builtins.cpp | 104 +++- .../ton/tonlib-src/crypto/func/optimize.cpp | 2 +- .../ton/tonlib-src/crypto/func/parse-func.cpp | 9 +- .../ton/tonlib-src/crypto/parser/srcread.cpp | 77 ++- .../ton/tonlib-src/crypto/parser/srcread.h | 27 +- .../crypto/smartcont/CreateState.fif | 41 +- .../crypto/smartcont/auto/config-code.cpp | 2 +- .../crypto/smartcont/auto/config-code.fif | 575 ++++++++++++++---- .../crypto/smartcont/auto/dns-auto-code.cpp | 2 +- .../crypto/smartcont/auto/dns-auto-code.fif | 9 +- .../crypto/smartcont/auto/dns-manual-code.cpp | 2 +- .../crypto/smartcont/auto/elector-code.cpp | 2 +- .../crypto/smartcont/auto/elector-code.fif | 12 +- .../crypto/smartcont/auto/multisig-code.cpp | 2 +- .../crypto/smartcont/auto/multisig-code.fif | 239 ++++---- .../crypto/smartcont/config-code.fc | 253 ++++++-- .../crypto/smartcont/gen-zerostate.fif | 11 + .../crypto/smartcont/multisig-code.fc | 22 +- .../ton/tonlib-src/crypto/smartcont/stdlib.fc | 8 +- .../tonlib-src/crypto/smartcont/wallet-v2.fif | 12 +- .../tonlib-src/crypto/smartcont/wallet-v3.fif | 12 +- .../tonlib-src/crypto/smartcont/wallet.fif | 12 +- .../crypto/smc-envelope/GenericAccount.cpp | 17 +- .../crypto/smc-envelope/GenericAccount.h | 7 +- .../crypto/smc-envelope/HighloadWallet.h | 2 +- .../crypto/smc-envelope/HighloadWalletV2.h | 2 +- .../crypto/smc-envelope/SmartContract.cpp | 16 +- .../crypto/smc-envelope/SmartContract.h | 5 + .../tonlib-src/crypto/smc-envelope/Wallet.h | 2 +- .../crypto/smc-envelope/WalletInterface.cpp | 38 ++ .../crypto/smc-envelope/WalletInterface.h | 2 +- .../tonlib-src/crypto/smc-envelope/WalletV3.h | 2 +- .../crypto/test/fift/test-stack-copy.fif | 20 + .../tonlib-src/crypto/test/fift/testcc.fif | 32 + .../ton/tonlib-src/crypto/test/test-db.cpp | 30 +- .../tonlib-src/crypto/test/test-smartcont.cpp | 66 +- submodules/ton/tonlib-src/crypto/test/vm.cpp | 29 +- .../ton/tonlib-src/crypto/tl/tlbc-data.h | 5 +- submodules/ton/tonlib-src/crypto/tl/tlbc.cpp | 31 +- .../ton/tonlib-src/crypto/vm/arithops.cpp | 4 +- submodules/ton/tonlib-src/crypto/vm/boc.cpp | 34 +- submodules/ton/tonlib-src/crypto/vm/boc.h | 24 +- .../ton/tonlib-src/crypto/vm/cellops.cpp | 17 +- submodules/ton/tonlib-src/crypto/vm/cellops.h | 5 +- .../crypto/vm/cells/CellBuilder.cpp | 11 +- .../tonlib-src/crypto/vm/cells/CellBuilder.h | 5 +- .../ton/tonlib-src/crypto/vm/continuation.cpp | 26 - .../ton/tonlib-src/crypto/vm/contops.cpp | 212 +++++-- submodules/ton/tonlib-src/crypto/vm/excno.hpp | 15 +- submodules/ton/tonlib-src/crypto/vm/vm.cpp | 76 ++- submodules/ton/tonlib-src/crypto/vm/vm.h | 20 +- .../ton/tonlib-src/tddb/td/db/RocksDb.cpp | 36 +- .../ton/tonlib-src/tddb/test/key_value.cpp | 6 +- .../tonlib-src/tdutils/td/utils/crypto.cpp | 12 +- .../ton/tonlib-src/tdutils/td/utils/crypto.h | 13 +- .../ton/tonlib-src/test/regression-tests.ans | 7 +- .../tl/generate/auto/tl/ton_api.cpp | 391 +++++++++++- .../tonlib-src/tl/generate/auto/tl/ton_api.h | 180 +++++- .../tl/generate/auto/tl/ton_api.hpp | 44 ++ .../tl/generate/auto/tl/ton_api_json.cpp | 248 +++++++- .../tl/generate/auto/tl/ton_api_json.h | 14 + .../tl/generate/auto/tl/tonlib_api.cpp | 106 +++- .../tl/generate/auto/tl/tonlib_api.h | 108 +++- .../tl/generate/auto/tl/tonlib_api.hpp | 16 +- .../tl/generate/auto/tl/tonlib_api_json.cpp | 118 +++- .../tl/generate/auto/tl/tonlib_api_json.h | 12 +- .../tonlib-src/tl/generate/scheme/ton_api.tl | 34 +- .../tonlib-src/tl/generate/scheme/ton_api.tlo | Bin 58212 -> 59624 bytes .../tl/generate/scheme/tonlib_api.tl | 13 +- .../tl/generate/scheme/tonlib_api.tlo | Bin 21096 -> 21792 bytes submodules/ton/tonlib-src/ton/ton-types.h | 10 +- .../ton/tonlib-src/tonlib/test/offline.cpp | 49 +- .../ton/tonlib-src/tonlib/test/online.cpp | 6 +- .../tonlib-src/tonlib/tonlib/TonlibClient.cpp | 215 +++++-- .../tonlib-src/tonlib/tonlib/TonlibClient.h | 7 +- .../tonlib/tonlib/keys/SimpleEncryption.cpp | 71 ++- .../tonlib/tonlib/keys/SimpleEncryption.h | 25 +- .../tonlib-src/tonlib/tonlib/tonlib-cli.cpp | 12 +- 171 files changed, 5267 insertions(+), 1448 deletions(-) delete mode 100644 Wallet/Wallet.entitlements delete mode 100644 Wallet/Wallet.mobileprovision rename Wallet/configuration.bzl => build-system/bazel-utils/BUILD (100%) rename build-system/{ => bazel-utils}/defines.bzl (100%) rename build-system/{ => bazel-utils}/plist_fragment.bzl (96%) rename build-system/{ => bazel-utils}/unique_directories.bzl (100%) rename build-system/{copy-provisioning-profiles.sh => copy-provisioning-profiles-Telegram.sh} (100%) create mode 100755 build-system/copy-provisioning-profiles-Wallet.sh rename build-system/{prepare-build-variables.sh => prepare-build-variables-Telegram.sh} (100%) create mode 100755 build-system/prepare-build-variables-Wallet.sh create mode 100644 submodules/ton/tonlib-src/crypto/common/linalloc.hpp create mode 100644 submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.cpp create mode 100644 submodules/ton/tonlib-src/crypto/test/fift/test-stack-copy.fif create mode 100644 submodules/ton/tonlib-src/crypto/test/fift/testcc.fif diff --git a/Makefile b/Makefile index d13b4c24ac..c56a98e210 100644 --- a/Makefile +++ b/Makefile @@ -384,7 +384,7 @@ project: check_env kill_xcode bazel_app_debug_arm64: APP_VERSION="${APP_VERSION}" \ - build-system/prepare-build.sh distribution + build-system/prepare-build.sh Telegram distribution "${BAZEL}" build Telegram/Telegram ${BAZEL_CACHE_FLAGS} ${BAZEL_COMMON_FLAGS} ${BAZEL_DEBUG_FLAGS} \ -c dbg \ --ios_multi_cpus=arm64 \ @@ -394,7 +394,7 @@ bazel_app_debug_arm64: bazel_app_arm64: APP_VERSION="${APP_VERSION}" \ BAZEL_CACHE_DIR="${BAZEL_CACHE_DIR}" \ - build-system/prepare-build.sh distribution + build-system/prepare-build.sh Telegram distribution "${BAZEL}" build Telegram/Telegram ${BAZEL_CACHE_FLAGS} ${BAZEL_COMMON_FLAGS} ${BAZEL_OPT_FLAGS} \ -c opt \ --ios_multi_cpus=arm64 \ @@ -408,7 +408,7 @@ bazel_app_arm64: bazel_prepare_development_build: APP_VERSION="${APP_VERSION}" \ BAZEL_CACHE_DIR="${BAZEL_CACHE_DIR}" \ - build-system/prepare-build.sh development + build-system/prepare-build.sh Telegram development bazel_project: kill_xcode bazel_prepare_development_build APP_VERSION="${APP_VERSION}" \ diff --git a/Telegram/BUILD b/Telegram/BUILD index 50b2dcff7d..c1bf60ae83 100644 --- a/Telegram/BUILD +++ b/Telegram/BUILD @@ -9,15 +9,11 @@ load("@build_bazel_rules_apple//apple:watchos.bzl", "watchos_extension", ) -load("@build_bazel_rules_apple//apple:versioning.bzl", - "apple_bundle_version", -) - load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library", ) -load("//build-system:plist_fragment.bzl", +load("//build-system/bazel-utils:plist_fragment.bzl", "plist_fragment", ) @@ -179,42 +175,42 @@ plist_fragment( template = """ CFBundleShortVersionString - {telegram_version} - CFBundleVersion - {telegram_build_number} - CFBundleURLTypes - - - CFBundleTypeRole - Viewer - CFBundleURLName - {telegram_bundle_id} - CFBundleURLSchemes - - telegram - - - - CFBundleTypeRole - Viewer - CFBundleURLName - {telegram_bundle_id}.ton - CFBundleURLSchemes - - ton - - - - CFBundleTypeRole - Viewer - CFBundleURLName - {telegram_bundle_id}.compatibility - CFBundleURLSchemes - - tg - - - + {telegram_version} + CFBundleVersion + {telegram_build_number} + CFBundleURLTypes + + + CFBundleTypeRole + Viewer + CFBundleURLName + {telegram_bundle_id} + CFBundleURLSchemes + + telegram + + + + CFBundleTypeRole + Viewer + CFBundleURLName + {telegram_bundle_id}.ton + CFBundleURLSchemes + + ton + + + + CFBundleTypeRole + Viewer + CFBundleURLName + {telegram_bundle_id}.compatibility + CFBundleURLSchemes + + tg + + + """.format( telegram_version = telegram_version, telegram_build_number = telegram_build_number, diff --git a/Wallet.makefile b/Wallet.makefile index 90d359969c..b2d9c44ab0 100644 --- a/Wallet.makefile +++ b/Wallet.makefile @@ -1,5 +1,9 @@ include Utils.makefile +APP_VERSION="1.0" +CORE_COUNT=$(shell sysctl -n hw.logicalcpu) +CORE_COUNT_MINUS_ONE=$(shell expr ${CORE_COUNT} \- 1) + WALLET_BUCK_OPTIONS=\ --config custom.appVersion="1.0" \ --config custom.developmentCodeSignIdentity="${DEVELOPMENT_CODE_SIGN_IDENTITY}" \ @@ -21,6 +25,23 @@ WALLET_BUCK_OPTIONS=\ BAZEL=$(shell which bazel) +ifneq ($(BAZEL_CACHE_DIR),) + export BAZEL_CACHE_FLAGS=\ + --disk_cache="${BAZEL_CACHE_DIR}" +endif + +BAZEL_COMMON_FLAGS=\ + --announce_rc \ + --features=swift.use_global_module_cache \ + +BAZEL_DEBUG_FLAGS=\ + --features=swift.enable_batch_mode \ + --swiftcopt=-j${CORE_COUNT_MINUS_ONE} \ + +BAZEL_OPT_FLAGS=\ + --swiftcopt=-whole-module-optimization \ + --swiftcopt='-num-threads' --swiftcopt='16' \ + wallet_deps: check_env $(BUCK) query "deps(//Wallet:AppPackage)" --output-attribute buck.type \ ${WALLET_BUCK_OPTIONS} ${BUCK_RELEASE_OPTIONS} @@ -51,5 +72,30 @@ wallet_package: wallet_app: build_wallet wallet_package -tulsi_project: - ${HOME}/Applications/Tulsi.app/Contents/MacOS/Tulsi -- --genconfig Wallet/Wallet.tulsiproj:Default --bazel "${BAZEL}" +bazel_wallet_debug_arm64: + WALLET_APP_VERSION="${APP_VERSION}" \ + build-system/prepare-build.sh Wallet distribution + "${BAZEL}" build Wallet/Wallet ${BAZEL_CACHE_FLAGS} ${BAZEL_COMMON_FLAGS} ${BAZEL_DEBUG_FLAGS} \ + -c dbg \ + --ios_multi_cpus=arm64 \ + --watchos_cpus=armv7k,arm64_32 \ + --verbose_failures + +bazel_wallet: + WALLET_APP_VERSION="${APP_VERSION}" \ + build-system/prepare-build.sh Wallet distribution + "${BAZEL}" build Wallet/Wallet ${BAZEL_CACHE_FLAGS} ${BAZEL_COMMON_FLAGS} ${BAZEL_OPT_FLAGS} \ + -c opt \ + --ios_multi_cpus=armv7,arm64 \ + --watchos_cpus=armv7k,arm64_32 \ + --verbose_failures + +bazel_wallet_prepare_development_build: + WALLET_APP_VERSION="${APP_VERSION}" \ + BAZEL_CACHE_DIR="${BAZEL_CACHE_DIR}" \ + build-system/prepare-build.sh Wallet development + +bazel_wallet_project: kill_xcode bazel_wallet_prepare_development_build + WALLET_APP_VERSION="${APP_VERSION}" \ + BAZEL_CACHE_DIR="${BAZEL_CACHE_DIR}" \ + build-system/generate-xcode-project.sh Wallet diff --git a/Wallet/BUILD b/Wallet/BUILD index a924e4a93e..b487d800c5 100644 --- a/Wallet/BUILD +++ b/Wallet/BUILD @@ -1,25 +1,132 @@ -load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application", "ios_framework") -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") +load("@build_bazel_rules_apple//apple:ios.bzl", + "ios_application", + "ios_extension", + "ios_framework", +) -version_info_plist_source = """ -echo \ -'' \ -'' \ -'' \ -'' \ -' CFBundleShortVersionString' \ -' {}' \ -' CFBundleVersion' \ -' {}' \ -'' \ -'' \ -> "$@" -""".format("1.0", "30") +load("@build_bazel_rules_swift//swift:swift.bzl", + "swift_library", +) + +load("//build-system/bazel-utils:plist_fragment.bzl", + "plist_fragment", +) + +load( + "//build-input/data:variables.bzl", + "wallet_build_number", + "wallet_version", + "wallet_bundle_id", + "wallet_team_id", +) + +config_setting( + name = "debug", + values = { + "compilation_mode": "dbg", + }, +) genrule( - name = "VersionInfoPlist", - outs = ["VersionInfo.plist"], - cmd = version_info_plist_source, + name = "empty", + outs = ["empty.swift"], + cmd = "touch $(OUTS)", +) + +swift_library( + name = "_LocalDebugOptions", + srcs = [":empty"], + copts = [ + "-Xfrontend", + "-serialize-debugging-options", + ], + deps = [ + ], + module_name = "_LocalDebugOptions", + tags = ["no-remote"], + visibility = ["//visibility:public"], +) + +debug_deps = select({ + ":debug": [":_LocalDebugOptions"], + "//conditions:default": [], +}) + +plist_fragment( + name = "WalletInfoPlist", + extension = "plist", + template = + """ + CFBundleShortVersionString + {wallet_version} + CFBundleVersion + {wallet_build_number} + CFBundleAllowMixedLocalizations + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + TON Wallet + CFBundleIdentifier + {wallet_bundle_id} + CFBundleName + TON Wallet + CFBundlePackageType + APPL + ITSAppUsesNonExemptEncryption + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSCameraUsageDescription + Please allow TON Wallet access to your camera for scanning QR codes. + NSFaceIDUsageDescription + For better security, please allow TON Wallet to use your Face ID to authenticate payments. + NSPhotoLibraryUsageDescription + Please allow TON Wallet access to your Photo Stream in case you need to scan a QR code from a picture. + UIDeviceFamily + + 1 + 2 + + UIFileSharingEnabled + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UIRequiresPersistentWiFi + + UIStatusBarStyle + UIStatusBarStyleLightContent + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + UIViewEdgeAntialiasing + + UIViewGroupOpacity + + """.format( + wallet_version = wallet_version, + wallet_build_number = wallet_build_number, + wallet_bundle_id = wallet_bundle_id, + ) ) filegroup( @@ -29,6 +136,13 @@ filegroup( ], exclude = ["Strings/**/.*"]), ) +filegroup( + name = "Icons", + srcs = glob([ + "Icons.xcassets/**/*", + ], exclude = ["Icons.xcassets/**/.*"]), +) + objc_library( name = "Main", srcs = [ @@ -36,73 +150,37 @@ objc_library( ], ) -ios_framework( - name = "AsyncDisplayKitFramework", - deps = ["//submodules/AsyncDisplayKit:AsyncDisplayKit"], - bundle_id = "org.telegram.Telegram.AsyncDisplayKit", - families = ["iphone", "ipad"], - minimum_os_version = "9.0", - infoplists = [ - "Info.plist" - ], -) - swift_library( name = "Lib", srcs = glob([ "Sources/**/*.swift", ]), data = [ - ":Strings", + ], deps = [ - "//submodules/GZip:GZip", - "//submodules/AsyncDisplayKit:AsyncDisplayKit", - "//submodules/SSignalKit/SSignalKit:SSignalKit", - "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", - "//submodules/ObjCRuntimeUtils:ObjCRuntimeUtils", - "//submodules/UIKitRuntimeUtils:UIKitRuntimeUtils", - "//submodules/Display:Display", - "//submodules/AlertUI:AlertUI", - "//submodules/ActivityIndicator:ActivityIndicator", - "//submodules/OverlayStatusController:OverlayStatusController", - "//submodules/openssl:openssl", - "//submodules/OpenSSLEncryptionProvider:OpenSSLEncryptionProvider", + "//submodules/WalletUI:WalletUI", "//submodules/WalletCore:WalletCore", "//submodules/BuildConfig:BuildConfig", - "//submodules/AppBundle:AppBundle", - "//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode", - "//submodules/Camera:Camera", - "//submodules/QrCode:QrCode", - "//submodules/MergeLists:MergeLists", - "//submodules/GlassButtonNode:GlassButtonNode", - "//submodules/UrlEscaping:UrlEscaping", - "//submodules/LocalAuth:LocalAuth", - "//submodules/ScreenCaptureDetection:ScreenCaptureDetection", - "//submodules/WalletUrl:WalletUrl", - "//submodules/ProgressNavigationButtonNode:ProgressNavigationButtonNode", - "//submodules/Markdown:Markdown", - "//submodules/StringPluralization:StringPluralization", - "//submodules/YuvConversion:YuvConversion", - "//submodules/rlottie:RLottieBinding", - "//submodules/AnimatedStickerNode:AnimatedStickerNode", - "//submodules/WalletUI:WalletUI", - "//submodules/FFMpegBinding:FFMpegBinding", + "//submodules/OverlayStatusController:OverlayStatusController", ], ) ios_application( name = "Wallet", - bundle_id = "{wallet_bundle_id}", + bundle_id = wallet_bundle_id, families = ["iphone", "ipad"], minimum_os_version = "9.0", - provisioning_profile = "Wallet.mobileprovision", + provisioning_profile = "//build-input/data/provisioning-profiles:Wallet.mobileprovision", infoplists = [ - ":Info.plist", - ":VersionInfoPlist", + ":WalletInfoPlist.plist", ], - frameworks = [ - ":AsyncDisplayKitFramework", + app_icons = [ + ":Icons", + ], + launch_storyboard = "LaunchScreen.xib", + strings = [ + ":Strings", ], deps = [ ":Main", diff --git a/Wallet/Wallet.entitlements b/Wallet/Wallet.entitlements deleted file mode 100644 index 6631ffa6f2..0000000000 --- a/Wallet/Wallet.entitlements +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Wallet/Wallet.mobileprovision b/Wallet/Wallet.mobileprovision deleted file mode 100644 index 879842ec7bf354601b1a3e8d9624afdcc90e2bf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7449 zcmc&(cX$(5wzq79v5j#E#i1Bv(=oC}&9(qLnNjn|>eUj2Wi%R%WQ~fYQH20D!Gw~{ zk|hak!C)3hC15&)r9B`d3n4(LVUs`t2_=+-l0bM@?j+=8|9Ic7zfYg%-h1vj=bn4Y z@6158xxG54kE|=NyPL&GORlfY?F`lCCMPo(oJ=UabEkrCDan01B|)`WYud>e^|e_G zQ){zc8~be3LovfdAn5XWOY=E}P(G9J;y$~}OP1yv4N_J~{Cxn=Mi0GxMD^?H|o%M`#cH4 zAX^jg`H27>QvhZxu%XaS+w*~#X6}!v17__moG!~qAL}M!Wk4J%R$(4uEITm-vq3rl zlr1x;RZKHRQ3O4f-7?j_g>vB-4Ni#K2`}w(xQKuzKsa2{HYQjgfOX_1Dk>I9g?hfp z*pVB%jVvKs6d;WdM)=CtJ7LJfsOH>qx zt#VRc0i0G85Noj)rlWDTYerluaguFtad($E6ab1eL)YqXdpbinWzU#0Kb1Tw%;6 z)A2B~jzT3m%I+}*Z9Ig+U5Fm=aoS~6*ydG|TCOPuo;{dZ)ja1y5PPN02W0#0?x<3X#*|esq%>&b=EPhToS2KY%~gpIZbiKNeP)KV^kA|h0V56Dpejzi^+r`U<(OWse*71xVOpRU2RZCwcEA($g@Xov%*~DI{4mVr%SdlYflELtMKZk= zD-d#v1YV(rT`i$Sp@3UWR8wKfidS$=QaBnE1~^rONE0?{5D~|$F0gXrVsWv%5+?=L zfL!ahhXjDXd}y_Yt;g zi?c+5vgIK}FIUkniOd{|Rda)sxm;*;i0$PC{3^9h62wYWu81t?HdMt!lu%5o1SDyd zxQ!}|@5O9xo>9gX6e&$8R1^=3cw#Bn>huOngs9yhRA>bXnrkV5VoDtp_DlUnDr(iq zg%xTm6;sJ+yC3GeMYxS9=D4eLm0q4&ja4bk-WZ#9s3=KXNkB$+5f_ixV7t++Ma8fd zMtpn}DKUsdFabrxFo+c$WPr8hYy?Iluo!kE{Ha{8l*q)enMCxcJc`S!Z5E3K4F`*g z16&=)D>YL3Dmo6c5t0lbq(q8nad4N~xKb>MC?XcLB4R-ht+8AQ%Va3m3E9ixB1KFX zw(wLDg-05}Wl>7uQH5>#<~gNUN!xjLH(n))Cj6j05#Kt9M8LCD40P3jTtG@dNVND4 zSLH^uk_hSGM@U>L6N!LNYK>APf{K)=j4MWEaU+OR%q$IAxJDAh0BM&w{lGV?td(*Q z?^eHsD}_L;xClMsw0YemE|Y?|aFdowRorgoP=MBH;i@RS9Qe0KMWHgG2QAn6z#a&b znL?9b9!|C);wY3T1b1Pic*Mvqf5lb zjruJ-phNRM3ipDz^-xuo<~Szta=FvO(*c>y@_-!LY8F6vj2}^v?RJMriMhhlW_O;Q zhlec9`3%@YNGlTOYUfQ^Dox-_!Wf8Ufg%o@n|;8Dz>X4$SPWNmxMwjOhwV-4TE0X| zYK;m-Tmn)CQBQ7!b6o?%ZJqO=Ce>C8XoO3|^va+&Oh>&)b%{=*_c_Gw5}knZ^ZB$sXj1v*a+t5HG((ZN zM@I2&8ZKKBBOH-vtVB?5#sUHj60k)q3Jy+$kz%LLr!9c0i^Y1smNZ~`yISwIOSP!c zC=aM&CbPYWPay6H8&(xm$W2(p&yoV1xvq8JZ$I0M)ct_7=F*jF)T#jj;lR-xr{R zEDWbz;Wn(2K9&xIn&3h+DL`i}IL+RQ918uRAgBg(VaOXG5~vEN2|Fw7bNO3w#J|G? z#{zx|i?KXJFo=-=tUY0KdV15@nlN4hEVckPma7f1wQp*HckLLh&=(*JX`i>y;PW

1|-FgQ$@mP+9xMB(9}h0!h#; z8VkBv0FU}2?TWYIv&X2PWOtgtJpbO=+to?kF4HwnFer@cG%r&i*_To;`eqFx1XqkecO0FNiVUB zbkP{almagYei~#d6rzq?5@_Av@(>1}qJ#gBb$MxmBm!kT0cR|`byRL_7Q*J}G$!F_Rk{O_x%Ym}mx;I8A(9YSKy1Nu(YUduwMm?to)V(tpWc0`Y zw?h$3)QcB#hC+iAlbJnon*8Sn*xOwDb)#?~L2<(EfR2;ENuO4|7iMxU}Zlp1Ihbk@v42{`-W_TvzOw zFL!xmOT9*#ey-2Ouiu~V*?xE7f_;}4!>Z#qi3|O7@pG3`PJ46DJY}p~IieEn`km}# zFFxL|{h&jB@yM(jrTDue&cD0O z+Ia5o4U1N%tETl95G!Y7;gibn*=JsmORqKvpW$!aKb&}GM~{h1rkdaB`QfZ<%Qww* z>NdTo+H!FE)%#2Pyxq7vv+lsMOHMz!6z=+{BZg& zKe%5md~VfUnR05E2~bgjU|=d60+(1nqJCK2kSBKjSi&=Lj2!^(Rfq?uju!}A8eAYF zDfj4!NuSfIlQ|D+SzQ+{o`3{yxz3$%Psr-(t|*(-bIAF|`IqZ|%APjsR!(VB@``!$ zcGBi^YZonBp78>-Gil_Ybt?7Nf(m=})By*1=lruuJ29!LrtK2*%%KpdWcEBH-Pusk^_ zbnTd!1P~9nOlnHkQI7??TF(S8hQhAIyC{GX5(9?|Bs0B>OpO09=r5gKv^S^W!*A10 z99Xz=Lnu$tJ;gZ?8kM#r@)D=~pg8sAnt#Uk-#d0k*59MLzU`ZyGphG}A8V`#opH`s z6*R8cKT|vDWdE9tjH(NB=UtDFd~oEo3HPh(hflfx_VF(dcT>N1`_Q$`uVru_4Ov)p zXTjeF&#{{~{rGUFB=7!v;_&A0-XG&y=9xO>WcS7EzZ0$a`r%O7;g9#FeRV0c|LlV) zy*IA>>;B1WOF#I07kgSXJX$sRlwCb?h;}9%?&kgCuPgK3DtrFWpH|PweD3e;#>Oi7 zf&Kc81ILe={nGV|e_=2CTvyf`-d{4nIrtS0>#VE#Nd0Z3@9^$&ddaHKqG)B-z8(F? z-7KBd67&sFO?`)$UOB-%=0RK*nCDO5J@^Cmm=7n_?}WN0LbfRfBtuD$Mfej_0Ms1e zBcNf>korOOd36I@A{>Nqhj)7}eXey~(74KV5e_PxQCU(+3`HSWvm}8oV01`Tf~5(>!^b8pog8IrFA4Z^ypnXNG=y zZPm?dySl&D=N;LWk=xMPV%~|qszw4*$ylio| zIb+IgJ#2?>EcdyxQ~XggqInZ!3>NZykSk3wODOtu!7)hP~7OaKL_J)EDU&6?4A1nDq5P&&c5ahff5Zych#D#<{ z!~cj5e^lEq&U-U`;JmW~WST3Tu1$!&$huOr!mKb}ozrL5`TG^rk7;k`L&=w)DZ8gh zKQ}WQZ{GY@!rL}kM?CN5BGE({jg8q$LG79 znEI#1w}zx_GrppHKI^7kFsN5WFH3IY{JVFSEIp#xw!2b8zS3m_^X^CQjAHuyo1SGr zb2p2QWdE)7b^$uP@4;UVZ`|7L^o0JOeN?(}^t(S~cT0LTb6sBVLi)tmth2V>Z#PuG zD$^TxuVurH_kOH(f~ zbE{qWtI%vpU*n4wDp=9Y*XAxhcRRB9R`}Bhq~1Mn#`GEe7M9A2Z@szrxj&COzV0ti zpW69DaPjp|?b#p2)cjK`%I-%WxeumYeL*;Vj-Gj}WZ$}fEK+B<9~C^XtnQRPIp;Z3 z_W|^=&2t8gku{v~4gTuN(arvUWlO#scIc)jdhOE2oSZf1rsN9_4LNZ-`!o0P6@v$L zzq|aMSAsPY_xBr@&VF_MJ#qPsi6u*W{a8AbWX|SQ-OZ{!a{fvK`@X(voP8J0i`*TZ zHp+D6Om<$kGuwiF)EiG1P2D}yczX51tz6{iQzxpIPFb$o-0y?GB7>hEc_2G?lXA%f z{9whj9L-y^Pn@~<;FI*U;`c+LJWg%$TmW5O0$-k>ni>B^h?3k6o7%sB)z_SZo@r~L z(o;B@ZG$uh)W2W|#y}(5iTIrUP~Q&U-j;VLcA!&%bnT?s90??XGCFr@{(zT~2I9H(IXO8wX&Ugf z_A%o*D6RR6UfSdH!#g@85CLK}$wh1~yt3)39_P{?Sr@3Hqff~)?%%6?abW50h@$LJ z?$kYwn&;I&tl2oL;ZOT?qhcS-xvus$I@&%pP{tMiub z%Z>lf8!v6kvYIOIcdJ_2`1Fy6&4<=rUW&b1P?YT~`sFa=t3{h8^!BakI?Waw^G3$& zb9WtwPMZD|d42D&`nUV?ZDQ^0pIDFfe8$>3ZCf~hs^xg~$-FPW7oC4S$Y;$UN4&S< l$eVJ>Ol)1<#0SAy{?hsX82)s_Q(s@YGilJW`*S9C{a;Jj4&DF& diff --git a/Wallet/configuration.bzl b/build-system/bazel-utils/BUILD similarity index 100% rename from Wallet/configuration.bzl rename to build-system/bazel-utils/BUILD diff --git a/build-system/defines.bzl b/build-system/bazel-utils/defines.bzl similarity index 100% rename from build-system/defines.bzl rename to build-system/bazel-utils/defines.bzl diff --git a/build-system/plist_fragment.bzl b/build-system/bazel-utils/plist_fragment.bzl similarity index 96% rename from build-system/plist_fragment.bzl rename to build-system/bazel-utils/plist_fragment.bzl index 4b28670773..ed1bfb0f28 100644 --- a/build-system/plist_fragment.bzl +++ b/build-system/bazel-utils/plist_fragment.bzl @@ -1,4 +1,4 @@ -load("//build-system:defines.bzl", +load("//build-system/bazel-utils:defines.bzl", "string_value", ) diff --git a/build-system/unique_directories.bzl b/build-system/bazel-utils/unique_directories.bzl similarity index 100% rename from build-system/unique_directories.bzl rename to build-system/bazel-utils/unique_directories.bzl diff --git a/build-system/copy-provisioning-profiles.sh b/build-system/copy-provisioning-profiles-Telegram.sh similarity index 100% rename from build-system/copy-provisioning-profiles.sh rename to build-system/copy-provisioning-profiles-Telegram.sh diff --git a/build-system/copy-provisioning-profiles-Wallet.sh b/build-system/copy-provisioning-profiles-Wallet.sh new file mode 100755 index 0000000000..aecceef4d3 --- /dev/null +++ b/build-system/copy-provisioning-profiles-Wallet.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +copy_provisioning_profiles () { + if [ "$CODESIGNING_DATA_PATH" = "" ]; then + >&2 echo "CODESIGNING_DATA_PATH not defined" + exit 1 + fi + + + PROFILES_TYPE="$1" + case "$PROFILES_TYPE" in + development) + EXPECTED_VARIABLES=(\ + WALLET_DEVELOPMENT_PROVISIONING_PROFILE_APP \ + ) + ;; + distribution) + EXPECTED_VARIABLES=(\ + WALLET_DISTRIBUTION_PROVISIONING_PROFILE_APP \ + ) + ;; + *) + echo "Unknown build provisioning type: $PROFILES_TYPE" + exit 1 + ;; + esac + + EXPECTED_VARIABLE_NAMES=(\ + Wallet \ + ) + + local SEARCH_NAMES=() + + local MISSING_VARIABLES="0" + for VARIABLE_NAME in ${EXPECTED_VARIABLES[@]}; do + if [ "${!VARIABLE_NAME}" = "" ]; then + echo "$VARIABLE_NAME not defined" + MISSING_VARIABLES="1" + fi + done + + if [ "$MISSING_VARIABLES" == "1" ]; then + exit 1 + fi + + local VARIABLE_COUNT=${#EXPECTED_VARIABLES[@]} + for (( i=0; i<$VARIABLE_COUNT; i=i+1 )); do + VARIABLE_NAME="${EXPECTED_VARIABLES[$(($i))]}" + SEARCH_NAMES=("${SEARCH_NAMES[@]}" "${EXPECTED_VARIABLE_NAMES[$i]}" "${!VARIABLE_NAME}") + done + + local DATA_PATH="build-input/data" + + local OUTPUT_DIRECTORY="$DATA_PATH/provisioning-profiles" + rm -rf "$OUTPUT_DIRECTORY" + mkdir -p "$OUTPUT_DIRECTORY" + + local BUILD_PATH="$OUTPUT_DIRECTORY/BUILD" + touch "$BUILD_PATH" + + echo "exports_files([" >> "$BUILD_PATH" + + local ELEMENT_COUNT=${#SEARCH_NAMES[@]} + local REMAINDER=$(($ELEMENT_COUNT % 2)) + + if [ $REMAINDER != 0 ]; then + >&2 echo "Expecting key-value pairs" + exit 1 + fi + + for PROFILE in `find "$CODESIGNING_DATA_PATH" -type f -name "*.mobileprovision"`; do + PROFILE_DATA=$(security cms -D -i "$PROFILE") + PROFILE_NAME=$(/usr/libexec/PlistBuddy -c "Print :Name" /dev/stdin <<< $(echo $PROFILE_DATA)) + for (( i=0; i<$ELEMENT_COUNT; i=i+2 )); do + ID=${SEARCH_NAMES[$i]} + SEARCH_NAME=${SEARCH_NAMES[$(($i + 1))]} + if [ "$PROFILE_NAME" = "$SEARCH_NAME" ]; then + VARIABLE_NAME="FOUND_PROFILE_$ID" + if [ "${!VARIABLE_NAME}" = "" ]; then + eval "FOUND_PROFILE_$ID=\"$PROFILE\"" + else + >&2 echo "Found multiple profiles with name \"$SEARCH_NAME\"" + exit 1 + fi + fi + done + done + + for (( i=0; i<$ELEMENT_COUNT; i=i+2 )); do + ID=${SEARCH_NAMES[$i]} + SEARCH_NAME=${SEARCH_NAMES[$(($i + 1))]} + VARIABLE_NAME="FOUND_PROFILE_$ID" + FOUND_PROFILE="${!VARIABLE_NAME}" + if [ "$FOUND_PROFILE" = "" ]; then + >&2 echo "Profile \"$SEARCH_NAME\" not found" + exit 1 + fi + + cp "$FOUND_PROFILE" "$OUTPUT_DIRECTORY/$ID.mobileprovision" + echo " \"$ID.mobileprovision\"," >> $BUILD_PATH + done + + echo "])" >> "$BUILD_PATH" +} diff --git a/build-system/generate-xcode-project.sh b/build-system/generate-xcode-project.sh index 3fbd6091d0..2297776f25 100755 --- a/build-system/generate-xcode-project.sh +++ b/build-system/generate-xcode-project.sh @@ -4,7 +4,7 @@ set -e APP_TARGET="$1" if [ "$APP_TARGET" == "" ]; then - echo "Usage: sh generate-xcode-project.sh app_target" + echo "Usage: sh generate-xcode-project.sh app_target_folder" exit 1 fi @@ -22,31 +22,6 @@ if [ "$INSTALLED_XCODE_VERSION" != "$XCODE_VERSION" ]; then exit 1 fi -EXPECTED_VARIABLES=(\ - BUILD_NUMBER \ - APP_VERSION \ - BUNDLE_ID \ - DEVELOPMENT_TEAM \ - API_ID \ - API_HASH \ - APP_CENTER_ID \ - IS_INTERNAL_BUILD \ - IS_APPSTORE_BUILD \ - APPSTORE_ID \ - APP_SPECIFIC_URL_SCHEME \ -) - -MISSING_VARIABLES="0" -for VARIABLE_NAME in ${EXPECTED_VARIABLES[@]}; do - if [ "${!VARIABLE_NAME}" = "" ]; then - echo "$VARIABLE_NAME not defined" - MISSING_VARIABLES="1" - fi -done -if [ "$MISSING_VARIABLES" == "1" ]; then - exit 1 -fi - GEN_DIRECTORY="build-input/gen/project" rm -rf "$GEN_DIRECTORY" mkdir -p "$GEN_DIRECTORY" @@ -84,18 +59,16 @@ fi --bazel "$BAZEL" \ --outputfolder "$GEN_DIRECTORY" \ --target "$APP_TARGET":"$APP_TARGET" \ - --target "$APP_TARGET":Main \ - --target "$APP_TARGET":Lib \ PATCH_OPTIONS="BazelBuildOptionsDebug BazelBuildOptionsRelease" for NAME in $PATCH_OPTIONS; do - sed -i "" -e '1h;2,$H;$!d;g' -e 's/\("'"$NAME"'" : {\n[ ]*"p" : "$(inherited)\)/\1'" ${BAZEL_OPTIONS[*]}"'/' "$GEN_DIRECTORY/$APP_TARGET.tulsiproj/Configs/$APP_TARGET.tulsigen" + sed -i "" -e '1h;2,$H;$!d;g' -e 's/\("'"$NAME"'" : {\n[ ]*"p" : "$(inherited)\)/\1'" ${BAZEL_OPTIONS[*]}"'/' "$GEN_DIRECTORY/${APP_TARGET}.tulsiproj/Configs/${APP_TARGET}.tulsigen" done -sed -i "" -e '1h;2,$H;$!d;g' -e 's/\("sourceFilters" : \[\n[ ]*\)"\.\/\.\.\."/\1"$APP_TARGET\/...", "submodules\/..."/' "$GEN_DIRECTORY/$APP_TARGET.tulsiproj/Configs/$APP_TARGET.tulsigen" +sed -i "" -e '1h;2,$H;$!d;g' -e 's/\("sourceFilters" : \[\n[ ]*\)"\.\/\.\.\."/\1"'"${APP_TARGET}"'\/...", "submodules\/..."/' "$GEN_DIRECTORY/${APP_TARGET}.tulsiproj/Configs/${APP_TARGET}.tulsigen" "$TULSI" -- \ --verbose \ - --genconfig "$GEN_DIRECTORY/$APP_TARGET.tulsiproj:$APP_TARGET" \ + --genconfig "$GEN_DIRECTORY/${APP_TARGET}.tulsiproj:${APP_TARGET}" \ --bazel "$BAZEL" \ --outputfolder "$GEN_DIRECTORY" \ diff --git a/build-system/prepare-build-variables.sh b/build-system/prepare-build-variables-Telegram.sh similarity index 100% rename from build-system/prepare-build-variables.sh rename to build-system/prepare-build-variables-Telegram.sh diff --git a/build-system/prepare-build-variables-Wallet.sh b/build-system/prepare-build-variables-Wallet.sh new file mode 100755 index 0000000000..d13544f966 --- /dev/null +++ b/build-system/prepare-build-variables-Wallet.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +set -e + +prepare_build_variables () { + BUILD_TYPE="$1" + case "$BUILD_TYPE" in + development) + APS_ENVIRONMENT="development" + ;; + distribution) + APS_ENVIRONMENT="production" + ;; + *) + echo "Unknown build provisioning type: $BUILD_TYPE" + exit 1 + ;; + esac + + local BAZEL="$(which bazel)" + if [ "$BAZEL" = "" ]; then + echo "bazel not found in PATH" + exit 1 + fi + + local EXPECTED_VARIABLES=(\ + BUILD_NUMBER \ + WALLET_APP_VERSION \ + WALLET_BUNDLE_ID \ + WALLET_DEVELOPMENT_TEAM \ + ) + + local MISSING_VARIABLES="0" + for VARIABLE_NAME in ${EXPECTED_VARIABLES[@]}; do + if [ "${!VARIABLE_NAME}" = "" ]; then + echo "$VARIABLE_NAME not defined" + MISSING_VARIABLES="1" + fi + done + + if [ "$MISSING_VARIABLES" == "1" ]; then + exit 1 + fi + + local VARIABLES_DIRECTORY="build-input/data" + mkdir -p "$VARIABLES_DIRECTORY" + local VARIABLES_PATH="$VARIABLES_DIRECTORY/variables.bzl" + rm -f "$VARIABLES_PATH" + + echo "wallet_build_number = \"$BUILD_NUMBER\"" >> "$VARIABLES_PATH" + echo "wallet_version = \"$WALLET_APP_VERSION\"" >> "$VARIABLES_PATH" + echo "wallet_bundle_id = \"$WALLET_BUNDLE_ID\"" >> "$VARIABLES_PATH" + echo "wallet_api_id = \"$WALLET_API_ID\"" >> "$VARIABLES_PATH" + echo "wallet_team_id = \"$WALLET_DEVELOPMENT_TEAM\"" >> "$VARIABLES_PATH" + + echo "telegram_api_id = \"1\"" >> "$VARIABLES_PATH" + echo "telegram_api_hash = \"1\"" >> "$VARIABLES_PATH" + echo "telegram_app_center_id = \"1\"" >> "$VARIABLES_PATH" + echo "telegram_appstore_id = \"1\"" >> "$VARIABLES_PATH" + echo "telegram_is_internal_build = \"false\"" >> "$VARIABLES_PATH" + echo "telegram_is_appstore_build = \"true\"" >> "$VARIABLES_PATH" + echo "telegram_app_specific_url_scheme = \"\"" >> "$VARIABLES_PATH" +} diff --git a/build-system/prepare-build.sh b/build-system/prepare-build.sh index c65df066f1..a98a5aa107 100755 --- a/build-system/prepare-build.sh +++ b/build-system/prepare-build.sh @@ -2,7 +2,13 @@ set -e -BUILD_TYPE="$1" +APP_TARGET="$1" +if [ "$APP_TARGET" == "" ]; then + echo "Usage: sh prepare-build.sh app_target development|distribution" + exit 1 +fi + +BUILD_TYPE="$2" case "$BUILD_TYPE" in development) PROFILES_TYPE="development" @@ -18,13 +24,26 @@ esac BASE_PATH=$(dirname $0) +COPY_PROVISIONING_PROFILES_SCRIPT="$BASE_PATH/copy-provisioning-profiles-$APP_TARGET.sh" +PREPARE_BUILD_VARIABLES_SCRIPT="$BASE_PATH/prepare-build-variables-$APP_TARGET.sh" + +if [ ! -f "$COPY_PROVISIONING_PROFILES_SCRIPT" ]; then + echo "$COPY_PROVISIONING_PROFILES_SCRIPT not found" + exit 1 +fi + +if [ ! -f "$PREPARE_BUILD_VARIABLES_SCRIPT" ]; then + echo "$PREPARE_BUILD_VARIABLES_SCRIPT not found" + exit 1 +fi + DATA_DIRECTORY="build-input/data" rm -rf "$DATA_DIRECTORY" mkdir -p "$DATA_DIRECTORY" touch "$DATA_DIRECTORY/BUILD" -source "$BASE_PATH/copy-provisioning-profiles.sh" -source "$BASE_PATH/prepare-build-variables.sh" +source "$COPY_PROVISIONING_PROFILES_SCRIPT" +source "$PREPARE_BUILD_VARIABLES_SCRIPT" echo "Copying provisioning profiles..." copy_provisioning_profiles "$PROFILES_TYPE" diff --git a/build-system/xcode_version b/build-system/xcode_version index f226094f1f..1c7134df6c 100644 --- a/build-system/xcode_version +++ b/build-system/xcode_version @@ -1 +1 @@ -11.3.1 \ No newline at end of file +11.4 diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift index cbff90d2f2..d072e2a7f2 100644 --- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift +++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift @@ -543,7 +543,7 @@ public final class AnimatedStickerNode: ASDisplayNode { let frameSourceHolder = self.frameSource self.queue.async { [weak self] in var maybeFrameSource: AnimatedStickerFrameSource? - var notifyUpdated: (() -> Void)? + let notifyUpdated: (() -> Void)? = nil if let directData = directData { maybeFrameSource = AnimatedStickerDirectFrameSource(queue: queue, data: directData.0, width: directData.2, height: directData.3) } else if let (cachedData, cachedDataComplete) = cachedData { diff --git a/submodules/Display/Source/ActionSheetSwitchItem.swift b/submodules/Display/Source/ActionSheetSwitchItem.swift index 110a4b4277..d2ca7393ad 100644 --- a/submodules/Display/Source/ActionSheetSwitchItem.swift +++ b/submodules/Display/Source/ActionSheetSwitchItem.swift @@ -42,7 +42,6 @@ public class ActionSheetSwitchNode: ActionSheetItemNode { override public init(theme: ActionSheetControllerTheme) { self.theme = theme - let defaultFont = Font.regular(floor(theme.baseFontSize * 20.0 / 17.0)) self.button = HighlightTrackingButton() self.button.isAccessibilityElement = false diff --git a/submodules/Display/Source/ContainedViewLayoutTransition.swift b/submodules/Display/Source/ContainedViewLayoutTransition.swift index 14f4bbf4bf..ec5b1a9ca0 100644 --- a/submodules/Display/Source/ContainedViewLayoutTransition.swift +++ b/submodules/Display/Source/ContainedViewLayoutTransition.swift @@ -152,8 +152,7 @@ public extension ContainedViewLayoutTransition { if let completion = completion { completion(true) } - case let .animated(duration, curve): - let previousBounds = node.bounds + case .animated: let previousCenter = node.frame.center node.position = frame.center node.bounds = CGRect(origin: node.bounds.origin, size: frame.size) diff --git a/submodules/Display/Source/ContextContentContainerNode.swift b/submodules/Display/Source/ContextContentContainerNode.swift index add4037501..441e100efd 100644 --- a/submodules/Display/Source/ContextContentContainerNode.swift +++ b/submodules/Display/Source/ContextContentContainerNode.swift @@ -1,6 +1,5 @@ import Foundation import AsyncDisplayKit -import Display public final class ContextContentContainerNode: ASDisplayNode { public var contentNode: ContextContentNode? diff --git a/submodules/Display/Source/ContextContentSourceNode.swift b/submodules/Display/Source/ContextContentSourceNode.swift index 7b2204cedc..b4818eb462 100644 --- a/submodules/Display/Source/ContextContentSourceNode.swift +++ b/submodules/Display/Source/ContextContentSourceNode.swift @@ -1,6 +1,5 @@ import Foundation import AsyncDisplayKit -import Display public final class ContextExtractedContentContainingNode: ASDisplayNode { public let contentNode: ContextExtractedContentNode diff --git a/submodules/Display/Source/ContextControllerSourceNode.swift b/submodules/Display/Source/ContextControllerSourceNode.swift index a9219fa485..7252986d5e 100644 --- a/submodules/Display/Source/ContextControllerSourceNode.swift +++ b/submodules/Display/Source/ContextControllerSourceNode.swift @@ -1,6 +1,5 @@ import Foundation import AsyncDisplayKit -import Display public final class ContextControllerSourceNode: ASDisplayNode { private var contextGesture: ContextGesture? diff --git a/submodules/Display/Source/ContextGesture.swift b/submodules/Display/Source/ContextGesture.swift index 5a758cc8c8..052d2be0d3 100644 --- a/submodules/Display/Source/ContextGesture.swift +++ b/submodules/Display/Source/ContextGesture.swift @@ -1,7 +1,6 @@ import Foundation import UIKit import AsyncDisplayKit -import Display public enum ContextGestureTransition { case begin @@ -207,7 +206,7 @@ public final class ContextGesture: UIGestureRecognizer, UIGestureRecognizerDeleg override public func touchesCancelled(_ touches: Set, with event: UIEvent) { super.touchesCancelled(touches, with: event) - if let touch = touches.first, !self.currentProgress.isZero, self.isValidated { + if let _ = touches.first, !self.currentProgress.isZero, self.isValidated { let previousProgress = self.currentProgress self.currentProgress = 0.0 self.activationProgress?(0.0, .ended(previousProgress)) diff --git a/submodules/Display/Source/Font.swift b/submodules/Display/Source/Font.swift index 73f987b832..0a9779afb6 100644 --- a/submodules/Display/Source/Font.swift +++ b/submodules/Display/Source/Font.swift @@ -34,7 +34,7 @@ public struct Font { public static func with(size: CGFloat, design: Design = .regular, traits: Traits = []) -> UIFont { if #available(iOS 13.0, *) { - var descriptor = UIFont.systemFont(ofSize: size).fontDescriptor + let descriptor = UIFont.systemFont(ofSize: size).fontDescriptor var symbolicTraits = descriptor.symbolicTraits if traits.contains(.bold) { symbolicTraits.insert(.traitBold) diff --git a/submodules/Display/Source/GridNode.swift b/submodules/Display/Source/GridNode.swift index 754fe54029..916d9d194b 100644 --- a/submodules/Display/Source/GridNode.swift +++ b/submodules/Display/Source/GridNode.swift @@ -179,13 +179,13 @@ private struct WrappedGridSection: Equatable, Hashable { self.section = section } - var hashValue: Int { - return self.section.hashValue - } - static func ==(lhs: WrappedGridSection, rhs: WrappedGridSection) -> Bool { return lhs.section.isEqual(to: rhs.section) } + + func hash(into hasher: inout Hasher) { + hasher.combine(self.section.hashValue) + } } public struct GridNodeVisibleItems { @@ -200,10 +200,6 @@ public struct GridNodeVisibleItems { private struct WrappedGridItemNode: Hashable { let node: ASDisplayNode - var hashValue: Int { - return node.hashValue - } - static func ==(lhs: WrappedGridItemNode, rhs: WrappedGridItemNode) -> Bool { return lhs.node === rhs.node } diff --git a/submodules/Display/Source/ImageCorners.swift b/submodules/Display/Source/ImageCorners.swift index 948a4d385d..62dbc83251 100644 --- a/submodules/Display/Source/ImageCorners.swift +++ b/submodules/Display/Source/ImageCorners.swift @@ -6,79 +6,24 @@ import SwiftSignalKit private enum Corner: Hashable { case TopLeft(Int), TopRight(Int), BottomLeft(Int), BottomRight(Int) - var hashValue: Int { - switch self { - case let .TopLeft(radius): - return radius | (1 << 24) - case let .TopRight(radius): - return radius | (2 << 24) - case let .BottomLeft(radius): - return radius | (3 << 24) - case let .BottomRight(radius): - return radius | (4 << 24) - } - } - var radius: Int { switch self { - case let .TopLeft(radius): - return radius - case let .TopRight(radius): - return radius - case let .BottomLeft(radius): - return radius - case let .BottomRight(radius): - return radius + case let .TopLeft(radius): + return radius + case let .TopRight(radius): + return radius + case let .BottomLeft(radius): + return radius + case let .BottomRight(radius): + return radius } } } -private func ==(lhs: Corner, rhs: Corner) -> Bool { - switch lhs { - case let .TopLeft(lhsRadius): - switch rhs { - case let .TopLeft(rhsRadius) where rhsRadius == lhsRadius: - return true - default: - return false - } - case let .TopRight(lhsRadius): - switch rhs { - case let .TopRight(rhsRadius) where rhsRadius == lhsRadius: - return true - default: - return false - } - case let .BottomLeft(lhsRadius): - switch rhs { - case let .BottomLeft(rhsRadius) where rhsRadius == lhsRadius: - return true - default: - return false - } - case let .BottomRight(lhsRadius): - switch rhs { - case let .BottomRight(rhsRadius) where rhsRadius == lhsRadius: - return true - default: - return false - } - } -} - private enum Tail: Hashable { case BottomLeft(Int) case BottomRight(Int) - var hashValue: Int { - switch self { - case let .BottomLeft(radius): - return radius | (1 << 24) - case let .BottomRight(radius): - return radius | (2 << 24) - } - } - var radius: Int { switch self { case let .BottomLeft(radius): @@ -89,25 +34,6 @@ private enum Tail: Hashable { } } -private func ==(lhs: Tail, rhs: Tail) -> Bool { - switch lhs { - case let .BottomLeft(lhsRadius): - switch rhs { - case let .BottomLeft(rhsRadius) where rhsRadius == lhsRadius: - return true - default: - return false - } - case let .BottomRight(lhsRadius): - switch rhs { - case let .BottomRight(rhsRadius) where rhsRadius == lhsRadius: - return true - default: - return false - } - } -} - private var cachedCorners = Atomic<[Corner: DrawingContext]>(value: [:]) private func cornerContext(_ corner: Corner) -> DrawingContext { diff --git a/submodules/Display/Source/KeyShortcut.swift b/submodules/Display/Source/KeyShortcut.swift index 4687d9b23d..2499500ddc 100644 --- a/submodules/Display/Source/KeyShortcut.swift +++ b/submodules/Display/Source/KeyShortcut.swift @@ -13,8 +13,9 @@ public struct KeyShortcut: Hashable { self.action = action } - public var hashValue: Int { - return input.hashValue ^ modifiers.hashValue + public func hash(into hasher: inout Hasher) { + hasher.combine(self.input) + hasher.combine(self.modifiers) } public static func ==(lhs: KeyShortcut, rhs: KeyShortcut) -> Bool { diff --git a/submodules/Display/Source/ListView.swift b/submodules/Display/Source/ListView.swift index 72927aca54..221957c580 100644 --- a/submodules/Display/Source/ListView.swift +++ b/submodules/Display/Source/ListView.swift @@ -882,8 +882,6 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture var completeHeight: CGFloat = 0.0 var topItemFound = false var bottomItemFound = false - var topItemEdge: CGFloat = 0.0 - var bottomItemEdge: CGFloat = 0.0 for i in 0 ..< self.itemNodes.count { if let index = itemNodes[i].index { @@ -900,25 +898,15 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture effectiveInsets.top = max(effectiveInsets.top, self.visibleSize.height - additionalInverseTopInset) } - if topItemFound { - topItemEdge = itemNodes[0].apparentFrame.origin.y - } - - var bottomItemNode: ListViewItemNode? for i in (0 ..< self.itemNodes.count).reversed() { if let index = itemNodes[i].index { if index == self.items.count - 1 { - bottomItemNode = itemNodes[i] bottomItemFound = true } break } } - if bottomItemFound { - bottomItemEdge = itemNodes[itemNodes.count - 1].apparentFrame.maxY - } - if topItemFound && bottomItemFound { for itemNode in self.itemNodes { completeHeight += itemNode.apparentBounds.height @@ -1119,7 +1107,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } } if topItemIndexAndMinY.0 == 0 { - var offsetValue: CGFloat = -(topItemIndexAndMinY.1 - self.insets.top) + let offsetValue: CGFloat = -(topItemIndexAndMinY.1 - self.insets.top) offset = .known(offsetValue) } else if topItemIndexAndMinY.0 == -1 { offset = .none @@ -1950,7 +1938,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture private func fillMissingNodes(synchronous: Bool, synchronousLoads: Bool, animated: Bool, inputAnimatedInsertIndices: Set, insertDirectionHints: [Int: ListViewItemOperationDirectionHint], inputState: ListViewState, inputPreviousNodes: [Int: QueueLocalObject], inputOperations: [ListViewStateOperation], inputCompletion: @escaping (ListViewState, [ListViewStateOperation]) -> Void) { let animatedInsertIndices = inputAnimatedInsertIndices var state = inputState - var previousNodes = inputPreviousNodes + let previousNodes = inputPreviousNodes var operations = inputOperations let completion = inputCompletion let updateAnimation: ListViewItemUpdateAnimation = animated ? .System(duration: insertionAnimationDuration) : .None @@ -2680,7 +2668,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture self.visibleSize = updateSizeAndInsets.size var offsetFix: CGFloat - var insetDeltaOffsetFix: CGFloat = 0.0 + let insetDeltaOffsetFix: CGFloat = 0.0 if self.isTracking || isExperimentalSnapToScrollToItem { offsetFix = 0.0 } else if self.snapToBottomInsetUntilFirstInteraction { @@ -4009,7 +3997,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture } public func cancelSelection() { - if let selectionTouchLocation = self.selectionTouchLocation { + if let _ = self.selectionTouchLocation { self.clearHighlightAnimated(true) self.selectionTouchLocation = nil } diff --git a/submodules/Display/Source/NativeWindowHostView.swift b/submodules/Display/Source/NativeWindowHostView.swift index b408471db7..035d3ac0e7 100644 --- a/submodules/Display/Source/NativeWindowHostView.swift +++ b/submodules/Display/Source/NativeWindowHostView.swift @@ -23,6 +23,8 @@ public enum WindowUserInterfaceStyle { self = .light case .dark: self = .dark + @unknown default: + self = .dark } } } @@ -188,33 +190,6 @@ private final class WindowRootViewController: UIViewController, UIViewController private var previewingContext: AnyObject? private func updatePreviewingRegistration() { - var shouldRegister = false - - var isVoiceOverRunning = false - if #available(iOSApplicationExtension 10.0, iOS 10.0, *) { - isVoiceOverRunning = UIAccessibility.isVoiceOverRunning - } - if !isVoiceOverRunning { - shouldRegister = true - } - - shouldRegister = false - - if shouldRegister != self.registeredForPreviewing { - self.registeredForPreviewing = shouldRegister - if shouldRegister { - if #available(iOSApplicationExtension 9.0, iOS 9.0, *) { - self.previewingContext = self.registerForPreviewing(with: self, sourceView: self.view) - } - } else if let previewingContext = self.previewingContext { - self.previewingContext = nil - if let previewingContext = previewingContext as? UIViewControllerPreviewing { - if #available(iOSApplicationExtension 9.0, iOS 9.0, *) { - self.unregisterForPreviewing(withContext: previewingContext) - } - } - } - } } private weak var previousPreviewingHostView: (UIView & PreviewingHostView)? diff --git a/submodules/Display/Source/Navigation/NavigationContainer.swift b/submodules/Display/Source/Navigation/NavigationContainer.swift index b5be8762d8..f8c5e7dea3 100644 --- a/submodules/Display/Source/Navigation/NavigationContainer.swift +++ b/submodules/Display/Source/Navigation/NavigationContainer.swift @@ -41,7 +41,7 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate { update(strongSelf) } })) - if let localIsReady = localIsReady { + if let _ = localIsReady { self.isReady = true } else { localIsReady = false @@ -170,12 +170,9 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate { let topController = self.controllers[self.controllers.count - 1] let bottomController = self.controllers[self.controllers.count - 2] - if let topController = topController as? ViewController { - if !topController.attemptNavigation({ [weak self] in - //let _ = self?.popViewController(animated: true) - }) { - return - } + if !topController.attemptNavigation({ + }) { + return } topController.viewWillDisappear(true) @@ -221,12 +218,11 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate { if velocity > 1000 || navigationTransitionCoordinator.progress > 0.2 { navigationTransitionCoordinator.animateCompletion(velocity, completion: { [weak self] in - guard let strongSelf = self, let layout = strongSelf.state.layout, let transition = strongSelf.state.transition, let top = strongSelf.state.top else { + guard let strongSelf = self, let _ = strongSelf.state.layout, let _ = strongSelf.state.transition, let top = strongSelf.state.top else { return } let topController = top.value - let bottomController = transition.previous.value if viewTreeContainsFirstResponder(view: top.value.view) { strongSelf.ignoreInputHeight = true @@ -349,7 +345,7 @@ final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelegate { var updatedStatusBarStyle = self.statusBarStyle if let top = self.state.top { var updatedLayout = layout - if let topTransition = self.state.transition, top.value.view.disableAutomaticKeyboardHandling.isEmpty { + if let _ = self.state.transition, top.value.view.disableAutomaticKeyboardHandling.isEmpty { if !viewTreeContainsFirstResponder(view: top.value.view) { updatedLayout = updatedLayout.withUpdatedInputHeight(nil) } diff --git a/submodules/Display/Source/Navigation/NavigationController.swift b/submodules/Display/Source/Navigation/NavigationController.swift index 1240f957d3..e2d395ffbf 100644 --- a/submodules/Display/Source/Navigation/NavigationController.swift +++ b/submodules/Display/Source/Navigation/NavigationController.swift @@ -155,7 +155,7 @@ open class NavigationController: UINavigationController, ContainableController, private var _viewControllers: [ViewController] = [] override open var viewControllers: [UIViewController] { get { - return self._viewControllers.map { $0 as! ViewController } + return self._viewControllers.map { $0 as UIViewController } } set(value) { self.setViewControllers(value, animated: false) } @@ -287,7 +287,6 @@ open class NavigationController: UINavigationController, ContainableController, } public func updateTheme(_ theme: NavigationControllerTheme) { - let statusBarStyleUpdated = self.theme.statusBar != theme.statusBar self.theme = theme if let rootContainer = self.rootContainer { switch rootContainer { @@ -790,7 +789,7 @@ open class NavigationController: UINavigationController, ContainableController, } let rootModalFrame: NavigationModalFrame - var modalFrameTransition: ContainedViewLayoutTransition = transition + let modalFrameTransition: ContainedViewLayoutTransition = transition var forceStatusBarAnimation = false if let current = self.rootModalFrame { rootModalFrame = current @@ -1165,7 +1164,7 @@ open class NavigationController: UINavigationController, ContainableController, self.overlayContainers.append(container) } container.isReadyUpdated = { [weak self, weak container] in - guard let strongSelf = self, let container = container else { + guard let strongSelf = self, let _ = container else { return } strongSelf.updateContainersNonReentrant(transition: .immediate) @@ -1245,7 +1244,7 @@ open class NavigationController: UINavigationController, ContainableController, self.view.setNeedsLayout() } - private func requestLayout(transition: ContainedViewLayoutTransition) { + public func requestLayout(transition: ContainedViewLayoutTransition) { if self.isViewLoaded, let validLayout = self.validLayout { self.containerLayoutUpdated(validLayout, transition: transition) } diff --git a/submodules/Display/Source/NavigationBackButtonNode.swift b/submodules/Display/Source/NavigationBackButtonNode.swift index b6082776f2..3a6e5176c4 100644 --- a/submodules/Display/Source/NavigationBackButtonNode.swift +++ b/submodules/Display/Source/NavigationBackButtonNode.swift @@ -69,7 +69,7 @@ public class NavigationBackButtonNode: ASControlNode { } public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { - self.label.updateLayout(CGSize(width: max(0.0, constrainedSize.width - self.arrow.frame.size.width - self.arrowSpacing), height: constrainedSize.height)) + let _ = self.label.updateLayout(CGSize(width: max(0.0, constrainedSize.width - self.arrow.frame.size.width - self.arrowSpacing), height: constrainedSize.height)) return CGSize(width: self.arrow.frame.size.width + self.arrowSpacing + self.label.calculatedSize.width, height: max(self.arrow.frame.size.height, self.label.calculatedSize.height)) } diff --git a/submodules/Display/Source/NavigationBar.swift b/submodules/Display/Source/NavigationBar.swift index f59718cc6e..217c0d133a 100644 --- a/submodules/Display/Source/NavigationBar.swift +++ b/submodules/Display/Source/NavigationBar.swift @@ -1059,7 +1059,7 @@ open class NavigationBar: ASDisplayNode { node.updateManualText(self.backButtonNode.manualText) node.color = accentColor if let (size, defaultHeight, _, _, _, _) = self.validLayout { - node.updateLayout(constrainedSize: CGSize(width: size.width, height: defaultHeight)) + let _ = node.updateLayout(constrainedSize: CGSize(width: size.width, height: defaultHeight)) node.frame = self.backButtonNode.frame } return node @@ -1082,7 +1082,7 @@ open class NavigationBar: ASDisplayNode { node.updateItems(items) node.color = accentColor if let (size, defaultHeight, _, _, _, _) = self.validLayout { - node.updateLayout(constrainedSize: CGSize(width: size.width, height: defaultHeight)) + let _ = node.updateLayout(constrainedSize: CGSize(width: size.width, height: defaultHeight)) node.frame = self.backButtonNode.frame } return node diff --git a/submodules/Display/Source/NavigationButtonNode.swift b/submodules/Display/Source/NavigationButtonNode.swift index 62217eeac6..22e369a229 100644 --- a/submodules/Display/Source/NavigationButtonNode.swift +++ b/submodules/Display/Source/NavigationButtonNode.swift @@ -62,22 +62,15 @@ private final class NavigationButtonItemNode: ImmediateTextNode { } set(value) { _image = value - if let value = value { + if let _ = value { if self.imageNode == nil { let imageNode = ASImageNode() imageNode.displayWithoutProcessing = true imageNode.displaysAsynchronously = false self.imageNode = imageNode - if false, value.size == CGSize(width: 30.0, height: 30.0) { - if self.imageRippleNode.supernode == nil { - self.addSubnode(self.imageRippleNode) - self.imageRippleNode.image = generateFilledCircleImage(diameter: 30.0, color: self.rippleColor) - } - } else { - if self.imageRippleNode.supernode != nil { - self.imageRippleNode.image = nil - self.imageRippleNode.removeFromSupernode() - } + if self.imageRippleNode.supernode != nil { + self.imageRippleNode.image = nil + self.imageRippleNode.removeFromSupernode() } self.addSubnode(imageNode) diff --git a/submodules/Display/Source/NavigationTitleNode.swift b/submodules/Display/Source/NavigationTitleNode.swift index ef3db73f23..fb87efe9a6 100644 --- a/submodules/Display/Source/NavigationTitleNode.swift +++ b/submodules/Display/Source/NavigationTitleNode.swift @@ -48,7 +48,7 @@ public class NavigationTitleNode: ASDisplayNode { } public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize { - self.label.updateLayout(constrainedSize) + let _ = self.label.updateLayout(constrainedSize) return self.label.calculatedSize } diff --git a/submodules/Display/Source/TransformImageArguments.swift b/submodules/Display/Source/TransformImageArguments.swift index ae8051f6ea..fd3b359d7e 100644 --- a/submodules/Display/Source/TransformImageArguments.swift +++ b/submodules/Display/Source/TransformImageArguments.swift @@ -54,7 +54,7 @@ public struct TransformImageArguments: Equatable { } public static func ==(lhs: TransformImageArguments, rhs: TransformImageArguments) -> Bool { - var result = lhs.imageSize == rhs.imageSize && lhs.boundingSize == rhs.boundingSize && lhs.corners == rhs.corners && lhs.emptyColor == rhs.emptyColor + let result = lhs.imageSize == rhs.imageSize && lhs.boundingSize == rhs.boundingSize && lhs.corners == rhs.corners && lhs.emptyColor == rhs.emptyColor if result { if let lhsCustom = lhs.custom, let rhsCustom = rhs.custom { return lhsCustom.serialized().isEqual(rhsCustom.serialized()) diff --git a/submodules/Display/Source/UIKitUtils.swift b/submodules/Display/Source/UIKitUtils.swift index 19ad82264e..bb506e410b 100644 --- a/submodules/Display/Source/UIKitUtils.swift +++ b/submodules/Display/Source/UIKitUtils.swift @@ -316,7 +316,7 @@ public func assertNotOnMainThread(_ file: String = #file, line: Int = #line) { } public extension UIImage { - public func precomposed() -> UIImage { + func precomposed() -> UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) self.draw(at: CGPoint()) let result = UIGraphicsGetImageFromCurrentImageContext()! diff --git a/submodules/Display/Source/ViewController.swift b/submodules/Display/Source/ViewController.swift index 2ab2e83846..78c06097ed 100644 --- a/submodules/Display/Source/ViewController.swift +++ b/submodules/Display/Source/ViewController.swift @@ -562,18 +562,6 @@ public enum TabBarItemContextActionType { @available(iOSApplicationExtension 9.0, iOS 9.0, *) open func registerForPreviewing(with delegate: UIViewControllerPreviewingDelegate, sourceView: UIView, theme: PeekControllerTheme, onlyNative: Bool) { - if false, self.traitCollection.forceTouchCapability == .available { - let _ = super.registerForPreviewing(with: delegate, sourceView: sourceView) - } else if !onlyNative { - if self.previewingContext == nil { - let previewingContext = SimulatedViewControllerPreviewing(theme: theme, delegate: delegate, sourceView: sourceView, node: self.displayNode, present: { [weak self] c, a in - self?.presentInGlobalOverlay(c, with: a) - }, customPresent: { [weak self] c, n in - return self?.customPresentPreviewingController?(c, n) - }) - self.previewingContext = previewingContext - } - } } @available(iOSApplicationExtension 9.0, iOS 9.0, *) diff --git a/submodules/Display/Source/WallpaperBackgroundNode.swift b/submodules/Display/Source/WallpaperBackgroundNode.swift index 203f3632de..65de835a13 100644 --- a/submodules/Display/Source/WallpaperBackgroundNode.swift +++ b/submodules/Display/Source/WallpaperBackgroundNode.swift @@ -42,7 +42,6 @@ public final class WallpaperBackgroundNode: ASDisplayNode { public var rotation: CGFloat = 0.0 { didSet { - let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut) var fromValue: CGFloat = 0.0 if let value = (self.layer.value(forKeyPath: "transform.rotation.z") as? NSNumber)?.floatValue { fromValue = CGFloat(value) diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index ba17a06b9a..1c89b1b330 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -338,10 +338,10 @@ public class Window1 { } strongSelf._rootController?.displayNode.accessibilityElementsHidden = strongSelf.presentationContext.hasOpaqueOverlay || strongSelf.topPresentationContext.hasOpaqueOverlay } - self.presentationContext.updateHasOpaqueOverlay = { [weak self] value in + self.presentationContext.updateHasOpaqueOverlay = { value in updateOpaqueOverlays() } - self.topPresentationContext.updateHasOpaqueOverlay = { [weak self] value in + self.topPresentationContext.updateHasOpaqueOverlay = { value in updateOpaqueOverlays() } @@ -846,7 +846,7 @@ public class Window1 { } private func layoutSubviews(force: Bool) { - if self.tracingStatusBarsInvalidated, let keyboardManager = keyboardManager { + if self.tracingStatusBarsInvalidated, let _ = keyboardManager { self.tracingStatusBarsInvalidated = false var supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all) @@ -1226,11 +1226,11 @@ public class Window1 { if let navigationController = self._rootController as? NavigationController { if !excludeNavigationSubControllers { for case let controller as ContainableController in navigationController.viewControllers { - !f(controller) + let _ = f(controller) } } if let controller = navigationController.topOverlayController { - !f(controller) + let _ = f(controller) } } for (controller, _) in self.presentationContext.controllers { diff --git a/submodules/LocalAuth/Sources/LocalAuth.swift b/submodules/LocalAuth/Sources/LocalAuth.swift index 6b7ef0aebf..da84d38257 100644 --- a/submodules/LocalAuth/Sources/LocalAuth.swift +++ b/submodules/LocalAuth/Sources/LocalAuth.swift @@ -13,12 +13,14 @@ public struct LocalAuth { if context.canEvaluatePolicy(LAPolicy(rawValue: Int(kLAPolicyDeviceOwnerAuthenticationWithBiometrics))!, error: nil) { if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { switch context.biometryType { - case .faceID: - return .faceId - case .touchID: - return .touchId - case .none: - return nil + case .faceID: + return .faceId + case .touchID: + return .touchId + case .none: + return nil + @unknown default: + return nil } } else { return .touchId diff --git a/submodules/QrCode/Sources/QrCode.swift b/submodules/QrCode/Sources/QrCode.swift index 44c53e7c60..5e26ae2357 100644 --- a/submodules/QrCode/Sources/QrCode.swift +++ b/submodules/QrCode/Sources/QrCode.swift @@ -13,12 +13,12 @@ public enum QrCodeIcon { } private func floorToContextPixels(_ value: CGFloat, scale: CGFloat? = UIScreenScale) -> CGFloat { - var scale = scale ?? UIScreenScale + let scale = scale ?? UIScreenScale return floor(value * scale) / scale } private func roundToContextPixels(_ value: CGFloat, scale: CGFloat? = UIScreenScale) -> CGFloat { - var scale = scale ?? UIScreenScale + let scale = scale ?? UIScreenScale return round(value * scale) / scale } diff --git a/submodules/RMIntro/BUILD b/submodules/RMIntro/BUILD index 646805cab6..ac8505a76a 100644 --- a/submodules/RMIntro/BUILD +++ b/submodules/RMIntro/BUILD @@ -1,4 +1,4 @@ -load("//build-system:unique_directories.bzl", "unique_directories") +load("//build-system/bazel-utils:unique_directories.bzl", "unique_directories") private_headers = glob([ "Sources/**/*.h", diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift index 5287ac158b..8a9b9ce65a 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Disposable.swift @@ -152,7 +152,7 @@ public final class DisposableSet : Disposable { public func remove(_ disposable: Disposable) { pthread_mutex_lock(&self.lock) - if let index = self.disposables.index(where: { $0 === disposable }) { + if let index = self.disposables.firstIndex(where: { $0 === disposable }) { self.disposables.remove(at: index) } pthread_mutex_unlock(&self.lock) diff --git a/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Dispatch.swift b/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Dispatch.swift index 2a921b2e37..f4392f460a 100644 --- a/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Dispatch.swift +++ b/submodules/SSignalKit/SwiftSignalKit/Source/Signal_Dispatch.swift @@ -30,19 +30,19 @@ public func deliverOn(_ threadPool: ThreadPool) -> (Signal) -> Signa let queue = threadPool.nextQueue() return signal.start(next: { next in queue.addTask(ThreadPoolTask { state in - if !state.cancelled.with { $0 } { + if !state.cancelled.with({ $0 }) { subscriber.putNext(next) } }) }, error: { error in queue.addTask(ThreadPoolTask { state in - if !state.cancelled.with { $0 } { + if !state.cancelled.with({ $0 }) { subscriber.putError(error) } }) }, completed: { queue.addTask(ThreadPoolTask { state in - if !state.cancelled.with { $0 } { + if !state.cancelled.with({ $0 }) { subscriber.putCompletion() } }) @@ -97,7 +97,7 @@ public func runOn(_ threadPool: ThreadPool) -> (Signal) -> Signal Bool { pthread_mutex_lock(&threadPool.mutex); if queue != nil { - if let index = threadPool.takenQueues.index(of: queue) { + if let index = threadPool.takenQueues.firstIndex(of: queue) { threadPool.takenQueues.remove(at: index) } @@ -97,7 +97,7 @@ public func ==(lhs: ThreadPoolQueue, rhs: ThreadPoolQueue) -> Bool { task = queue.popFirstTask() threadPool.takenQueues.append(queue) - if let index = threadPool.queues.index(of: queue) { + if let index = threadPool.queues.firstIndex(of: queue) { threadPool.queues.remove(at: index) } diff --git a/submodules/ScreenCaptureDetection/Sources/ScreenCaptureDetection.swift b/submodules/ScreenCaptureDetection/Sources/ScreenCaptureDetection.swift index 26f6bfba5b..3da80a4947 100644 --- a/submodules/ScreenCaptureDetection/Sources/ScreenCaptureDetection.swift +++ b/submodules/ScreenCaptureDetection/Sources/ScreenCaptureDetection.swift @@ -83,10 +83,10 @@ public final class ScreenCaptureDetectionManager { public init(check: @escaping () -> Bool) { self.observer = NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: .main, using: { [weak self] _ in - guard let strongSelf = self else { + guard let _ = self else { return } - check() + let _ = check() }) self.screenRecordingDisposable = screenRecordingActive().start(next: { [weak self] value in @@ -116,7 +116,9 @@ public final class ScreenCaptureDetectionManager { } deinit { - NotificationCenter.default.removeObserver(self.observer) + if let observer = self.observer { + NotificationCenter.default.removeObserver(observer) + } self.screenRecordingDisposable?.dispose() self.screenRecordingCheckTimer?.invalidate() self.screenRecordingCheckTimer = nil diff --git a/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift b/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift index 2bfd0b4880..d8756f5bba 100644 --- a/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift +++ b/submodules/SolidRoundedButtonNode/Sources/SolidRoundedButtonNode.swift @@ -154,7 +154,7 @@ public final class SolidRoundedButtonNode: ASDisplayNode { } let spacingOffset: CGFloat = 9.0 - var verticalInset: CGFloat = self.subtitle == nil ? floor((buttonFrame.height - titleSize.height) / 2.0) : floor((buttonFrame.height - titleSize.height) / 2.0) - spacingOffset + let verticalInset: CGFloat = self.subtitle == nil ? floor((buttonFrame.height - titleSize.height) / 2.0) : floor((buttonFrame.height - titleSize.height) / 2.0) - spacingOffset let titleFrame = CGRect(origin: CGPoint(x: buttonFrame.minX + nextContentOrigin, y: buttonFrame.minY + verticalInset), size: titleSize) transition.updateFrame(node: self.titleNode, frame: titleFrame) diff --git a/submodules/TonBinding/Sources/TON.h b/submodules/TonBinding/Sources/TON.h index f29b344a57..5e95749e2a 100644 --- a/submodules/TonBinding/Sources/TON.h +++ b/submodules/TonBinding/Sources/TON.h @@ -59,11 +59,20 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface TONTransactionMessageContentsEncryptedText : NSObject +@interface TONEncryptedData : NSObject +@property (nonatomic, strong, readonly) NSString * _Nonnull sourceAddress; @property (nonatomic, strong, readonly) NSData * _Nonnull data; -- (instancetype)initWithData:(NSData * _Nonnull)data; +- (instancetype)initWithSourceAddress:(NSString * _Nonnull)sourceAddress data:(NSData * _Nonnull)data; + +@end + +@interface TONTransactionMessageContentsEncryptedText : NSObject + +@property (nonatomic, strong, readonly) TONEncryptedData * _Nonnull encryptedData; + +- (instancetype)initWithEncryptedData:(TONEncryptedData * _Nonnull)encryptedData; @end @@ -168,7 +177,7 @@ NS_ASSUME_NONNULL_BEGIN - (SSignal *)deleteKey:(TONKey *)key; - (SSignal *)deleteAllKeys; - (SSignal *)getTransactionListWithAddress:(NSString * _Nonnull)address lt:(int64_t)lt hash:(NSData * _Nonnull)hash; -- (SSignal *)decryptMessagesWithKey:(TONKey * _Nonnull)key localPassword:(NSData * _Nonnull)localPassword messages:(NSArray * _Nonnull)messages; +- (SSignal *)decryptMessagesWithKey:(TONKey * _Nonnull)key localPassword:(NSData * _Nonnull)localPassword messages:(NSArray * _Nonnull)messages; - (NSData *)encrypt:(NSData *)decryptedData secret:(NSData *)data; - (NSData * __nullable)decrypt:(NSData *)encryptedData secret:(NSData *)data; diff --git a/submodules/TonBinding/Sources/TON.mm b/submodules/TonBinding/Sources/TON.mm index 4b7fdb6bc6..99c53cbbda 100644 --- a/submodules/TonBinding/Sources/TON.mm +++ b/submodules/TonBinding/Sources/TON.mm @@ -46,8 +46,8 @@ static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::obj if (message == nullptr) { return nil; } - NSString *source = readString(message->source_); - NSString *destination = readString(message->destination_); + NSString *source = readString(message->source_->account_address_); + NSString *destination = readString(message->destination_->account_address_); id contents = nil; if (message->msg_data_->get_id() == tonlib_api::msg_dataRaw::ID) { @@ -71,7 +71,8 @@ static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::obj } } else if (message->msg_data_->get_id() == tonlib_api::msg_dataEncryptedText::ID) { auto msgData = tonlib_api::move_object_as(message->msg_data_); - contents = [[TONTransactionMessageContentsEncryptedText alloc] initWithData:makeData(msgData->text_)]; + TONEncryptedData *encryptedData = [[TONEncryptedData alloc] initWithSourceAddress:source data:makeData(msgData->text_)]; + contents = [[TONTransactionMessageContentsEncryptedText alloc] initWithEncryptedData:encryptedData]; } else { contents = [[TONTransactionMessageContentsRawData alloc] initWithData:[NSData data]]; } @@ -150,10 +151,10 @@ static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::obj @implementation TONTransactionMessageContentsEncryptedText -- (instancetype)initWithData:(NSData * _Nonnull)data { +- (instancetype)initWithEncryptedData:(TONEncryptedData * _Nonnull)encryptedData { self = [super init]; if (self != nil) { - _data = data; + _encryptedData = encryptedData; } return self; } @@ -274,6 +275,19 @@ static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::obj @end +@implementation TONEncryptedData + +- (instancetype)initWithSourceAddress:(NSString * _Nonnull)sourceAddress data:(NSData * _Nonnull)data { + self = [super init]; + if (self != nil) { + _sourceAddress = sourceAddress; + _data = data; + } + return self; +} + +@end + using tonlib_api::make_object; @interface TONReceiveThreadParams : NSObject @@ -752,6 +766,7 @@ typedef enum { std::vector > inputMessages; inputMessages.push_back(make_object( make_object(address.UTF8String), + makeString([NSData data]), amount, tonlib_api::move_object_as(inputMessageData) )); @@ -812,6 +827,7 @@ typedef enum { std::vector > inputMessages; inputMessages.push_back(make_object( make_object(address.UTF8String), + makeString([NSData data]), amount, tonlib_api::move_object_as(inputMessageData) )); @@ -1093,7 +1109,7 @@ typedef enum { }] startOn:[SQueue mainQueue]] deliverOn:[SQueue mainQueue]]; } -- (SSignal *)decryptMessagesWithKey:(TONKey * _Nonnull)key localPassword:(NSData * _Nonnull)localPassword messages:(NSArray * _Nonnull)messages { +- (SSignal *)decryptMessagesWithKey:(TONKey * _Nonnull)key localPassword:(NSData * _Nonnull)localPassword messages:(NSArray * _Nonnull)messages { return [[[[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { NSData *publicKeyData = [key.publicKey dataUsingEncoding:NSUTF8StringEncoding]; if (publicKeyData == nil) { @@ -1108,24 +1124,24 @@ typedef enum { if (object->get_id() == tonlib_api::error::ID) { auto error = tonlib_api::move_object_as(object); [subscriber putError:[[TONError alloc] initWithText:[[NSString alloc] initWithUTF8String:error->message_.c_str()]]]; - } else if (object->get_id() == tonlib_api::msg_dataArray::ID) { - auto result = tonlib_api::move_object_as(object); + } else if (object->get_id() == tonlib_api::msg_dataDecryptedArray::ID) { + auto result = tonlib_api::move_object_as(object); if (result->elements_.size() != messages.count) { [subscriber putError:[[TONError alloc] initWithText:@"API interaction error"]]; } else { NSMutableArray > *resultMessages = [[NSMutableArray alloc] init]; int index = 0; for (auto &it : result->elements_) { - if (it->get_id() == tonlib_api::msg_dataDecryptedText::ID) { - auto dataDecryptedText = tonlib_api::move_object_as(it); + if (it->data_->get_id() == tonlib_api::msg_dataDecryptedText::ID) { + auto dataDecryptedText = tonlib_api::move_object_as(it->data_); NSString *decryptedString = readString(dataDecryptedText->text_); if (decryptedString != nil) { [resultMessages addObject:[[TONTransactionMessageContentsPlainText alloc] initWithText:decryptedString]]; } else { - [resultMessages addObject:[[TONTransactionMessageContentsEncryptedText alloc] initWithData:messages[index]]]; + [resultMessages addObject:[[TONTransactionMessageContentsEncryptedText alloc] initWithEncryptedData:messages[index]]]; } } else { - [resultMessages addObject:[[TONTransactionMessageContentsEncryptedText alloc] initWithData:messages[index]]]; + [resultMessages addObject:[[TONTransactionMessageContentsEncryptedText alloc] initWithEncryptedData:messages[index]]]; } index++; } @@ -1137,10 +1153,20 @@ typedef enum { } }]; - std::vector> inputData; - for (NSData *message in messages) { - inputData.push_back(make_object( - makeString(message) + std::vector> inputData; + for (TONEncryptedData *message in messages) { + NSData *sourceAddressData = [message.sourceAddress dataUsingEncoding:NSUTF8StringEncoding]; + if (sourceAddressData == nil) { + continue; + } + + inputData.push_back(make_object( + make_object( + makeString(sourceAddressData) + ), + make_object( + makeString(message.data) + ) )); } @@ -1152,7 +1178,7 @@ typedef enum { ), makeSecureString(localPassword) ), - make_object( + make_object( std::move(inputData) ) ); diff --git a/submodules/WalletCore/Sources/WalletCore.swift b/submodules/WalletCore/Sources/WalletCore.swift index 2d14b36514..df045129e9 100644 --- a/submodules/WalletCore/Sources/WalletCore.swift +++ b/submodules/WalletCore/Sources/WalletCore.swift @@ -196,7 +196,7 @@ public final class TonInstance { assertionFailure() return } - let cancel = keychain.encrypt(key.secret).start(next: { encryptedSecretData in + let _ = keychain.encrypt(key.secret).start(next: { encryptedSecretData in let _ = self.exportKey(key: key, localPassword: localPassword).start(next: { wordList in subscriber.putNext((WalletInfo(publicKey: WalletPublicKey(rawValue: key.publicKey), encryptedSecret: encryptedSecretData), wordList)) subscriber.putCompletion() @@ -231,7 +231,7 @@ public final class TonInstance { subscriber.putError(.generic) return } - let cancel = keychain.encrypt(key.secret).start(next: { encryptedSecretData in + let _ = keychain.encrypt(key.secret).start(next: { encryptedSecretData in subscriber.putNext(WalletInfo(publicKey: WalletPublicKey(rawValue: key.publicKey), encryptedSecret: encryptedSecretData)) subscriber.putCompletion() }, error: { _ in @@ -427,20 +427,22 @@ public final class TonInstance { } } - fileprivate func decryptWalletTransactions(decryptionKey: WalletTransactionDecryptionKey, encryptedMessages: [Data]) -> Signal<[WalletTransactionMessageContents], DecryptWalletTransactionsError> { + fileprivate func decryptWalletTransactions(decryptionKey: WalletTransactionDecryptionKey, encryptedMessages: [WalletTransactionEncryptedMessageData]) -> Signal<[WalletTransactionMessageContents], DecryptWalletTransactionsError> { return Signal { subscriber in let disposable = MetaDisposable() self.impl.with { impl in impl.withInstance { ton in - let cancel = ton.decryptMessages(with: TONKey(publicKey: decryptionKey.walletInfo.publicKey.rawValue, secret: decryptionKey.decryptedSecret), localPassword: decryptionKey.localPassword, messages: encryptedMessages).start(next: { result in + let cancel = ton.decryptMessages(with: TONKey(publicKey: decryptionKey.walletInfo.publicKey.rawValue, secret: decryptionKey.decryptedSecret), localPassword: decryptionKey.localPassword, messages: encryptedMessages.map { data in + TONEncryptedData(sourceAddress: data.sourceAddress, data: data.data) + }).start(next: { result in guard let result = result as? [TONTransactionMessageContents] else { subscriber.putError(.generic) return } subscriber.putNext(result.map(WalletTransactionMessageContents.init(tonTransactionMessageContents:))) }, error: { error in - if let error = error as? TONError { + if let _ = error as? TONError { subscriber.putError(.generic) } else { subscriber.putError(.generic) @@ -735,7 +737,7 @@ public struct CombinedWalletState: Codable, Equatable { return CombinedWalletState( walletState: self.walletState, timestamp: self.timestamp, - topTransactions: self.topTransactions, + topTransactions: topTransactions, pendingTransactions: self.pendingTransactions ) } @@ -1093,7 +1095,6 @@ public func sendGramsFromWallet(storage: WalletStorageInterface, tonInstance: To } }) |> mapToSignal { _ -> Signal in - return .complete() } |> then(.single(PendingWalletTransaction(timestamp: Int64(Date().timeIntervalSince1970), validUntilTimestamp: preparedQuery.validUntil, bodyHash: preparedQuery.bodyHash, address: toAddress, value: amount, comment: comment))) |> mapToSignal { result in @@ -1134,16 +1135,26 @@ public enum WalletTransactionMessageContentsDecodingError: Error { case generic } +public struct WalletTransactionEncryptedMessageData: Codable, Equatable { + public let sourceAddress: String + public let data: Data + + public init(sourceAddress: String, data: Data) { + self.sourceAddress = sourceAddress + self.data = data + } +} + public enum WalletTransactionMessageContents: Codable, Equatable { enum Key: CodingKey { case raw case plainText - case encryptedText + case encryptedData } case raw(Data) case plainText(String) - case encryptedText(Data) + case encryptedText(WalletTransactionEncryptedMessageData) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: Key.self) @@ -1151,22 +1162,22 @@ public enum WalletTransactionMessageContents: Codable, Equatable { self = .raw(data) } else if let plainText = try? container.decode(String.self, forKey: .plainText) { self = .plainText(plainText) - } else if let encryptedText = try? container.decode(Data.self, forKey: .encryptedText) { - self = .encryptedText(encryptedText) + } else if let encryptedData = try? container.decode(WalletTransactionEncryptedMessageData.self, forKey: .encryptedData) { + self = .encryptedText(encryptedData) } else { throw WalletTransactionMessageContentsDecodingError.generic } } public func encode(to encoder: Encoder) throws { - var container = try encoder.container(keyedBy: Key.self) + var container = encoder.container(keyedBy: Key.self) switch self { case let .raw(data): try container.encode(data, forKey: .raw) case let .plainText(text): try container.encode(text, forKey: .plainText) case let .encryptedText(data): - try container.encode(data, forKey: .encryptedText) + try container.encode(data, forKey: .encryptedData) } } } @@ -1178,7 +1189,7 @@ private extension WalletTransactionMessageContents { } else if let plainText = tonTransactionMessageContents as? TONTransactionMessageContentsPlainText { self = .plainText(plainText.text) } else if let encryptedText = tonTransactionMessageContents as? TONTransactionMessageContentsEncryptedText { - self = .encryptedText(encryptedText.data) + self = .encryptedText(WalletTransactionEncryptedMessageData(sourceAddress: encryptedText.encryptedData.sourceAddress, data: encryptedText.encryptedData.data)) } else { self = .raw(Data()) } @@ -1383,7 +1394,7 @@ public func decryptWalletTransactions(decryptionKey: WalletTransactionDecryption case inMessage case outMessage(Int) } - var encryptedMessages: [(Int, EncryptedMessagePath, Data)] = [] + var encryptedMessages: [(Int, EncryptedMessagePath, WalletTransactionEncryptedMessageData)] = [] for i in 0 ..< transactions.count { if let inMessage = transactions[i].inMessage { switch inMessage.contents { @@ -1506,7 +1517,7 @@ private func getWalletTransactionsOnce(address: String, previousId: WalletTransa case inMessage case outMessage(Int) } - var encryptedMessages: [(Int, EncryptedMessagePath, Data)] = [] + var encryptedMessages: [(Int, EncryptedMessagePath, WalletTransactionEncryptedMessageData)] = [] for i in 0 ..< transactions.count { if let inMessage = transactions[i].inMessage { switch inMessage.contents { @@ -1591,7 +1602,7 @@ public enum LocalWalletConfigurationSource: Codable, Equatable { } public func encode(to encoder: Encoder) throws { - var container = try encoder.container(keyedBy: Key.self) + var container = encoder.container(keyedBy: Key.self) switch self { case let .url(url): try container.encode(url, forKey: .url) diff --git a/submodules/WalletUI/BUILD b/submodules/WalletUI/BUILD index 3933e3e274..a5159bc357 100644 --- a/submodules/WalletUI/BUILD +++ b/submodules/WalletUI/BUILD @@ -20,6 +20,10 @@ swift_library( srcs = glob([ "Sources/**/*.swift", ]), + data = [ + ":WalletUIResources", + ":WalletUIAssets", + ], deps = [ "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", diff --git a/submodules/WalletUI/Sources/ItemList/Items/ItemListMultilineTextItem.swift b/submodules/WalletUI/Sources/ItemList/Items/ItemListMultilineTextItem.swift index 93e3f4c752..d47d0e0e0c 100644 --- a/submodules/WalletUI/Sources/ItemList/Items/ItemListMultilineTextItem.swift +++ b/submodules/WalletUI/Sources/ItemList/Items/ItemListMultilineTextItem.swift @@ -182,16 +182,8 @@ class ItemListMultilineTextItemNode: ListViewItemNode { } var baseFont = titleFont - var linkFont = titleFont - var boldFont = titleBoldFont - var italicFont = titleItalicFont - var boldItalicFont = titleBoldItalicFont if case .monospace = item.font { baseFont = Font.monospace(17.0) - linkFont = Font.monospace(17.0) - boldFont = Font.semiboldMonospace(17.0) - italicFont = Font.italicMonospace(17.0) - boldItalicFont = Font.semiboldItalicMonospace(17.0) } let string = NSAttributedString(string: item.text, font: baseFont, textColor: textColor) @@ -365,7 +357,7 @@ class ItemListMultilineTextItemNode: ListViewItemNode { private func linkItemAtPoint(_ point: CGPoint) -> String? { let textNodeFrame = self.textNode.frame - if let (_, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { + if let (_, _) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) { return nil } return nil diff --git a/submodules/WalletUI/Sources/WalletAmountItem.swift b/submodules/WalletUI/Sources/WalletAmountItem.swift index 39049b3362..2706ecadd5 100644 --- a/submodules/WalletUI/Sources/WalletAmountItem.swift +++ b/submodules/WalletUI/Sources/WalletAmountItem.swift @@ -182,7 +182,6 @@ class WalletAmountItemNode: ListViewItemNode, UITextFieldDelegate, ItemListItemN } let leftInset: CGFloat = 16.0 + params.leftInset - var rightInset: CGFloat = 16.0 + params.rightInset let separatorHeight = UIScreenPixel diff --git a/submodules/WalletUI/Sources/WalletConfgurationScreen.swift b/submodules/WalletUI/Sources/WalletConfgurationScreen.swift index f0a723ebb1..ff6847ad08 100644 --- a/submodules/WalletUI/Sources/WalletConfgurationScreen.swift +++ b/submodules/WalletUI/Sources/WalletConfgurationScreen.swift @@ -108,7 +108,7 @@ private enum WalletConfigurationScreenEntry: ItemListNodeEntry, Equatable { }) case let .modeInfo(theme, text): return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section) - case let .configUrl(theme, strings, placeholder, text): + case let .configUrl(theme, _, placeholder, text): return ItemListMultilineInputItem(theme: theme, text: text, placeholder: placeholder, maxLength: nil, sectionId: self.section, style: .blocks, capitalization: false, autocorrection: false, returnKeyType: .done, minimalHeight: nil, textUpdated: { value in arguments.updateState { state in var state = state @@ -211,12 +211,9 @@ func walletConfigurationScreen(context: WalletContext, currentConfiguration: Loc } var presentControllerImpl: ((ViewController, Any?) -> Void)? - var pushImpl: ((ViewController) -> Void)? var dismissImpl: (() -> Void)? var dismissInputImpl: (() -> Void)? - var ensureItemVisibleImpl: ((WalletConfigurationScreenEntryTag, Bool) -> Void)? - weak var currentStatusController: ViewController? let arguments = WalletConfigurationScreenArguments(updateState: { f in updateState(f) }, dismissInput: { @@ -237,9 +234,6 @@ func walletConfigurationScreen(context: WalletContext, currentConfiguration: Loc let signal = combineLatest(queue: .mainQueue(), .single(context.presentationData), statePromise.get()) |> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState, Any)) in - let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Wallet_Navigation_Cancel), style: .regular, enabled: true, action: { - dismissImpl?() - }) let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Wallet_Configuration_Apply), style: .bold, enabled: !state.isEmpty, action: { let state = stateValue.with { $0 } let source: LocalWalletConfigurationSource @@ -346,9 +340,6 @@ func walletConfigurationScreen(context: WalletContext, currentConfiguration: Loc presentControllerImpl = { [weak controller] c, a in controller?.present(c, in: .window(.root), with: a) } - pushImpl = { [weak controller] c in - controller?.push(c) - } dismissImpl = { [weak controller] in controller?.view.endEditing(true) let _ = controller?.dismiss() @@ -356,26 +347,5 @@ func walletConfigurationScreen(context: WalletContext, currentConfiguration: Loc dismissInputImpl = { [weak controller] in controller?.view.endEditing(true) } - ensureItemVisibleImpl = { [weak controller] targetTag, animated in - controller?.afterLayout({ - guard let controller = controller else { - return - } - var resultItemNode: ListViewItemNode? - let state = stateValue.with({ $0 }) - let _ = controller.frameForItemNode({ itemNode in - if let itemNode = itemNode as? ItemListItemNode { - if let tag = itemNode.tag, tag.isEqual(to: targetTag) { - resultItemNode = itemNode as? ListViewItemNode - return true - } - } - return false - }) - if let resultItemNode = resultItemNode { - controller.ensureItemNodeVisible(resultItemNode, animated: animated) - } - }) - } return controller } diff --git a/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift b/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift index e8efb2c6a2..57106500c8 100644 --- a/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift +++ b/submodules/WalletUI/Sources/WalletCreateInvoiceScreen.swift @@ -142,7 +142,7 @@ private enum WalletCreateInvoiceScreenEntry: ItemListNodeEntry { arguments.updateText(WalletCreateInvoiceScreenEntryTag.comment, text) }, shouldUpdateText: { text in let textLength: Int = text.data(using: .utf8, allowLossyConversion: true)?.count ?? 0 - return text.count <= walletTextLimit + return textLength <= walletTextLimit }, updatedFocus: { focus in arguments.updateState { state in var state = state @@ -171,7 +171,7 @@ private struct WalletCreateInvoiceScreenState: Equatable { private func walletCreateInvoiceScreenEntries(presentationData: WalletPresentationData, address: String, state: WalletCreateInvoiceScreenState) -> [WalletCreateInvoiceScreenEntry] { var entries: [WalletCreateInvoiceScreenEntry] = [] - entries.append(.amount(presentationData.theme, state.amount ?? "")) + entries.append(.amount(presentationData.theme, state.amount)) entries.append(.amountInfo(presentationData.theme, presentationData.strings.Wallet_Receive_CreateInvoiceInfo)) entries.append(.commentHeader(presentationData.theme, presentationData.strings.Wallet_Receive_CommentHeader)) entries.append(.comment(presentationData.theme, presentationData.strings.Wallet_Receive_CommentInfo, state.comment)) @@ -196,13 +196,10 @@ func walletCreateInvoiceScreen(context: WalletContext, address: String) -> ViewC statePromise.set(stateValue.modify { f($0) }) } - var presentControllerImpl: ((ViewController, Any?) -> Void)? var pushImpl: ((ViewController) -> Void)? - var dismissImpl: (() -> Void)? var dismissInputImpl: (() -> Void)? var ensureItemVisibleImpl: ((WalletCreateInvoiceScreenEntryTag, Bool) -> Void)? - weak var currentStatusController: ViewController? let arguments = WalletCreateInvoiceScreenArguments(context: context, updateState: { f in updateState(f) }, updateText: { tag, value in @@ -250,16 +247,9 @@ func walletCreateInvoiceScreen(context: WalletContext, address: String) -> ViewC return state } } - presentControllerImpl = { [weak controller] c, a in - controller?.present(c, in: .window(.root), with: a) - } pushImpl = { [weak controller] c in controller?.push(c) } - dismissImpl = { [weak controller] in - controller?.view.endEditing(true) - let _ = controller?.dismiss() - } dismissInputImpl = { [weak controller] in controller?.view.endEditing(true) } @@ -269,7 +259,6 @@ func walletCreateInvoiceScreen(context: WalletContext, address: String) -> ViewC return } var resultItemNode: ListViewItemNode? - let state = stateValue.with({ $0 }) let _ = controller.frameForItemNode({ itemNode in if let itemNode = itemNode as? ItemListItemNode { if let tag = itemNode.tag, tag.isEqual(to: targetTag) { diff --git a/submodules/WalletUI/Sources/WalletInfoEmptyNode.swift b/submodules/WalletUI/Sources/WalletInfoEmptyNode.swift index 5aad2c0147..f9fde449bc 100644 --- a/submodules/WalletUI/Sources/WalletInfoEmptyNode.swift +++ b/submodules/WalletUI/Sources/WalletInfoEmptyNode.swift @@ -89,7 +89,7 @@ final class WalletInfoEmptyItemNode: ListViewItemNode { super.didLoad() let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) - recognizer.tapActionAtPoint = { [weak self] point in + recognizer.tapActionAtPoint = { point in return .waitForSingleTap } self.addressNode.view.addGestureRecognizer(recognizer) @@ -98,7 +98,7 @@ final class WalletInfoEmptyItemNode: ListViewItemNode { @objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: - if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { + if let (gesture, _) = recognizer.lastRecognizedGestureAndLocation { switch gesture { case .longTap: self.item?.displayAddressContextMenu(self, self.addressNode.frame) @@ -129,7 +129,7 @@ final class WalletInfoEmptyItemNode: ListViewItemNode { let contentVerticalOrigin: CGFloat = 10.0 let sideInset: CGFloat = 16.0 - var iconOffset = CGPoint() + let iconOffset = CGPoint() let title = item.strings.Wallet_Info_WalletCreated let text = item.strings.Wallet_Info_Address diff --git a/submodules/WalletUI/Sources/WalletInfoScreen.swift b/submodules/WalletUI/Sources/WalletInfoScreen.swift index dc9f7c7320..2f8b803232 100644 --- a/submodules/WalletUI/Sources/WalletInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletInfoScreen.swift @@ -122,7 +122,7 @@ public final class WalletInfoScreen: ViewController { strongSelf.push(walletSendScreen(context: strongSelf.context, randomId: randomId, walletInfo: walletInfo)) } }, receiveAction: { [weak self] in - guard let strongSelf = self, let walletInfo = strongSelf.walletInfo else { + guard let strongSelf = self, let _ = strongSelf.walletInfo else { return } strongSelf.push(WalletReceiveScreen(context: strongSelf.context, mode: .receive(address: strongSelf.address))) @@ -221,7 +221,6 @@ final class WalletInfoBalanceNode: ASDisplayNode { let balanceIntegralTextFrame = CGRect(origin: balanceOrigin, size: balanceIntegralTextSize) let apparentBalanceIntegralTextFrame = CGRect(origin: balanceIntegralTextFrame.origin, size: CGSize(width: balanceIntegralTextFrame.width * integralScale, height: balanceIntegralTextFrame.height * integralScale)) var balanceFractionalTextFrame = CGRect(origin: CGPoint(x: balanceIntegralTextFrame.maxX, y: balanceIntegralTextFrame.maxY - balanceFractionalTextSize.height), size: balanceFractionalTextSize) - let apparentBalanceFractionalTextFrame = CGRect(origin: balanceFractionalTextFrame.origin, size: CGSize(width: balanceFractionalTextFrame.width * fractionalScale, height: balanceFractionalTextFrame.height * fractionalScale)) balanceFractionalTextFrame.origin.x -= (balanceFractionalTextFrame.width / 4.0) * scaleTransition + 0.25 * (balanceFractionalTextFrame.width / 2.0) * (1.0 - scaleTransition) balanceFractionalTextFrame.origin.y += balanceFractionalTextFrame.height * 0.5 * (0.8 - fractionalScale) @@ -332,21 +331,9 @@ private final class WalletInfoHeaderNode: ASDisplayNode { func update(size: CGSize, navigationHeight: CGFloat, offset: CGFloat, transition: ContainedViewLayoutTransition, isScrolling: Bool) { let sideInset: CGFloat = 16.0 - let buttonSideInset: CGFloat = 48.0 - let titleSpacing: CGFloat = 10.0 - let termsSpacing: CGFloat = 10.0 let buttonHeight: CGFloat = 50.0 let balanceSubtitleSpacing: CGFloat = 0.0 - let alphaTransition: ContainedViewLayoutTransition - if transition.isAnimated { - alphaTransition = transition - } else if isScrolling { - alphaTransition = .animated(duration: 0.2, curve: .easeInOut) - } else { - alphaTransition = transition - } - let minOffset = navigationHeight let maxOffset = size.height @@ -438,11 +425,11 @@ private final class WalletInfoHeaderNode: ASDisplayNode { transition.updateAlpha(node: self.receiveGramsButtonNode, alpha: buttonAlpha, beginWithCurrentState: true) transition.updateFrame(node: self.receiveButtonNode, frame: leftButtonFrame) transition.updateAlpha(node: self.receiveButtonNode, alpha: buttonAlpha, beginWithCurrentState: true) - self.receiveGramsButtonNode.updateLayout(width: fullButtonFrame.width, transition: transition) - self.receiveButtonNode.updateLayout(width: leftButtonFrame.width, transition: transition) + let _ = self.receiveGramsButtonNode.updateLayout(width: fullButtonFrame.width, transition: transition) + let _ = self.receiveButtonNode.updateLayout(width: leftButtonFrame.width, transition: transition) transition.updateFrame(node: self.sendButtonNode, frame: sendButtonFrame) transition.updateAlpha(node: self.sendButtonNode, alpha: buttonAlpha, beginWithCurrentState: true) - self.sendButtonNode.updateLayout(width: sendButtonFrame.width, transition: transition) + let _ = self.sendButtonNode.updateLayout(width: sendButtonFrame.width, transition: transition) } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { @@ -610,6 +597,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.listNode.verticalScrollIndicatorFollowsOverscroll = true self.listNode.isHidden = false self.listNode.view.disablesInteractiveModalDismiss = true + //self.listNode.keepMinimalScrollHeightWithTopInset = 0.0 super.init() @@ -628,7 +616,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { } self.listNode.updateFloatingHeaderOffset = { [weak self] offset, listTransition in - guard let strongSelf = self, let (layout, navigationHeight) = strongSelf.validLayout else { + guard let strongSelf = self, let (_, navigationHeight) = strongSelf.validLayout else { return } @@ -662,7 +650,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.listNode.didEndScrolling = { [weak self] in canBeginRefresh = true - guard let strongSelf = self, let (_, navigationHeight) = strongSelf.validLayout else { + guard let strongSelf = self, let (_, _) = strongSelf.validLayout else { return } switch strongSelf.listNode.visibleContentOffset() { @@ -765,7 +753,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { return } strongSelf.headerNode.refreshNode.refreshProgress = progress - if strongSelf.headerNode.isRefreshing, strongSelf.isReady, let (layout, navigationHeight) = strongSelf.validLayout { + if strongSelf.headerNode.isRefreshing, strongSelf.isReady, let (_, _) = strongSelf.validLayout { strongSelf.headerNode.refreshNode.update(state: .refreshing) } }) @@ -951,7 +939,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { strongSelf.headerNode.timestamp = Int32(clamping: combinedState.timestamp) } - if strongSelf.isReady, let (layout, navigationHeight) = strongSelf.validLayout { + if strongSelf.isReady, let (_, navigationHeight) = strongSelf.validLayout { strongSelf.headerNode.update(size: strongSelf.headerNode.bounds.size, navigationHeight: navigationHeight, offset: strongSelf.listOffset ?? 0.0, transition: .immediate, isScrolling: false) } @@ -960,7 +948,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { strongSelf.headerNode.isRefreshing = false - if strongSelf.isReady, let (layout, navigationHeight) = strongSelf.validLayout { + if strongSelf.isReady, let (_, navigationHeight) = strongSelf.validLayout { strongSelf.headerNode.update(size: strongSelf.headerNode.bounds.size, navigationHeight: navigationHeight, offset: strongSelf.listOffset ?? 0.0, transition: .animated(duration: 0.2, curve: .easeInOut), isScrolling: false) } @@ -999,7 +987,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.headerNode.timestamp = Int32(clamping: combinedState.timestamp) - if self.isReady, let (layout, navigationHeight) = self.validLayout { + if self.isReady, let (_, navigationHeight) = self.validLayout { self.headerNode.update(size: self.headerNode.bounds.size, navigationHeight: navigationHeight, offset: self.listOffset ?? 0.0, transition: .immediate, isScrolling: false) } @@ -1033,7 +1021,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.headerNode.isRefreshing = false } - if self.isReady, let (layout, navigationHeight) = self.validLayout { + if self.isReady, let (_, navigationHeight) = self.validLayout { self.headerNode.update(size: self.headerNode.bounds.size, navigationHeight: navigationHeight, offset: self.listOffset ?? 0.0, transition: .animated(duration: 0.2, curve: .easeInOut), isScrolling: false) } } else { @@ -1090,10 +1078,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { return } strongSelf.transactionsLoaded(isReload: false, isEmpty: false, transactions: transactions, pendingTransactions: []) - }, error: { [weak self] _ in - guard let strongSelf = self else { - return - } + }, error: { _ in })) } @@ -1133,7 +1118,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { var existingIds = Set() for entry in updatedEntries { switch entry { - case let .transaction(_, transaction): + case .transaction: existingIds.insert(entry.stableId) case .empty: break @@ -1152,7 +1137,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.replaceEntries(updatedEntries) - if !self.transactionDecryptionKeyRequested { + if !self.transactionDecryptionKeyRequested && false { var encryptedTransactions: [WalletTransactionId: WalletTransaction] = [:] for entry in updatedEntries { switch entry { @@ -1233,7 +1218,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { } private func dequeueTransaction() { - guard let layout = self.validLayout, let transaction = self.enqueuedTransactions.first else { + guard let _ = self.validLayout, let transaction = self.enqueuedTransactions.first else { return } diff --git a/submodules/WalletUI/Sources/WalletInfoTransactionItem.swift b/submodules/WalletUI/Sources/WalletInfoTransactionItem.swift index 2240a179a7..7d19d7c4e5 100644 --- a/submodules/WalletUI/Sources/WalletInfoTransactionItem.swift +++ b/submodules/WalletUI/Sources/WalletInfoTransactionItem.swift @@ -98,6 +98,7 @@ class WalletInfoTransactionItem: ListViewItem { private let titleFont = Font.medium(17.0) private let textFont = Font.monospace(15.0) private let descriptionFont = Font.regular(15.0) +private let descriptionMonospaceFont = Font.monospace(15.0) private let dateFont = Font.regular(14.0) private let directionFont = Font.regular(15.0) @@ -222,6 +223,7 @@ class WalletInfoTransactionItemNode: ListViewItemNode { } var text: String = "" var description: String = "" + var descriptionIsMonospace = false if transferredValue <= 0 { sign = "" title = "\(formatBalanceText(-transferredValue, decimalSeparator: item.dateTimeFormat.decimalSeparator))" @@ -246,7 +248,8 @@ class WalletInfoTransactionItemNode: ListViewItemNode { case .raw: break case .encryptedText: - description.append("") + description.append("Encrypted Comment") + descriptionIsMonospace = true case let .plainText(text): description.append(text) } @@ -279,7 +282,8 @@ class WalletInfoTransactionItemNode: ListViewItemNode { case .raw: description = "" case .encryptedText: - description = "" + description = "Encrypted Comment" + descriptionIsMonospace = true case let .plainText(text): description = text } @@ -326,7 +330,7 @@ class WalletInfoTransactionItemNode: ListViewItemNode { let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: text, font: textFont, textColor: item.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - leftInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (descriptionLayout, descriptionApply) = makeDescriptionLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: description, font: descriptionFont, textColor: item.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - leftInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (descriptionLayout, descriptionApply) = makeDescriptionLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: description, font: descriptionIsMonospace ? descriptionMonospaceFont : descriptionFont, textColor: item.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - leftInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let (feesLayout, feesApply) = makeFeesLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: feeText, font: descriptionFont, textColor: item.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - leftInset, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) diff --git a/submodules/WalletUI/Sources/WalletQrScanScreen.swift b/submodules/WalletUI/Sources/WalletQrScanScreen.swift index e9df176be9..e997ce7ce5 100644 --- a/submodules/WalletUI/Sources/WalletQrScanScreen.swift +++ b/submodules/WalletUI/Sources/WalletQrScanScreen.swift @@ -18,7 +18,7 @@ private func generateFrameImage() -> UIImage? { context.setLineWidth(4.0) context.setLineCap(.round) - var path = CGMutablePath(); + let path = CGMutablePath() path.move(to: CGPoint(x: 2.0, y: 2.0 + 26.0)) path.addArc(tangent1End: CGPoint(x: 2.0, y: 2.0), tangent2End: CGPoint(x: 2.0 + 26.0, y: 2.0), radius: 6.0) path.addLine(to: CGPoint(x: 2.0 + 26.0, y: 2.0)) diff --git a/submodules/WalletUI/Sources/WalletReceiveScreen.swift b/submodules/WalletUI/Sources/WalletReceiveScreen.swift index 881944e045..8415854ac9 100644 --- a/submodules/WalletUI/Sources/WalletReceiveScreen.swift +++ b/submodules/WalletUI/Sources/WalletReceiveScreen.swift @@ -232,15 +232,14 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { } let textFont = Font.regular(16.0) - let textColor = self.presentationData.theme.list.itemPrimaryTextColor let secondaryTextColor = self.presentationData.theme.list.itemSecondaryTextColor let url = urlForMode(self.mode) switch self.mode { - case let .receive(address): + case .receive: self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Wallet_Receive_ShareUrlInfo, font: textFont, textColor: secondaryTextColor) self.buttonNode.title = self.presentationData.strings.Wallet_Receive_ShareAddress self.secondaryButtonNode.setTitle(self.presentationData.strings.Wallet_Receive_CreateInvoice, with: Font.regular(17.0), with: self.presentationData.theme.list.itemAccentColor, for: .normal) - case let .invoice(address, amount, comment): + case .invoice: self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Wallet_Receive_ShareUrlInfo, font: textFont, textColor: secondaryTextColor, paragraphAlignment: .center) self.buttonNode.title = self.presentationData.strings.Wallet_Receive_ShareInvoiceUrl } @@ -255,7 +254,7 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { super.didLoad() let addressGestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapAddressGesture(_:))) - addressGestureRecognizer.tapActionAtPoint = { [weak self] point in + addressGestureRecognizer.tapActionAtPoint = { point in return .waitForSingleTap } self.urlTextNode.view.addGestureRecognizer(addressGestureRecognizer) @@ -264,7 +263,7 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { @objc func tapLongTapOrDoubleTapAddressGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: - if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { + if let (gesture, _) = recognizer.lastRecognizedGestureAndLocation { switch gesture { case .longTap: self.displayCopyContextMenu?(self, self.urlTextNode.frame, urlForMode(self.mode)) @@ -299,7 +298,7 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { let makeImageLayout = self.qrImageNode.asyncLayout() let imageSide: CGFloat = 215.0 - var imageSize = CGSize(width: imageSide, height: imageSide) + let imageSize = CGSize(width: imageSide, height: imageSide) let imageApply = makeImageLayout(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: nil)) let _ = imageApply() @@ -353,6 +352,6 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { let buttonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: layout.size.height - bottomInset - buttonHeight + buttonOffset), size: CGSize(width: buttonWidth, height: buttonHeight)) transition.updateFrame(node: self.buttonNode, frame: buttonFrame) - self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) + let _ = self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) } } diff --git a/submodules/WalletUI/Sources/WalletRefreshNode.swift b/submodules/WalletUI/Sources/WalletRefreshNode.swift index f09e55a3a8..b8874faa59 100644 --- a/submodules/WalletUI/Sources/WalletRefreshNode.swift +++ b/submodules/WalletUI/Sources/WalletRefreshNode.swift @@ -93,12 +93,7 @@ private func lastUpdateTimestampString(strings: WalletStrings, dateTimeFormat: W if dayDifference == 0 || dayDifference == -1 { let day: RelativeTimestampFormatDay if dayDifference == 0 { - if expanded { - day = .today - } else { - let minutes = difference / (60 * 60) - return strings.Wallet_Updated_HoursAgo(minutes) - } + day = .today } else { day = .yesterday } @@ -226,13 +221,10 @@ final class WalletRefreshNode: ASDisplayNode { let previousState = self.state self.state = state - var pullProgress: CGFloat = 0.0 - let title: String switch state { - case let .pullToRefresh(ts, progress): + case let .pullToRefresh(ts, _): title = lastUpdateTimestampString(strings: self.strings, dateTimeFormat: dateTimeFormat, statusTimestamp: ts, relativeTo: Int32(Date().timeIntervalSince1970)) - pullProgress = progress case .refreshing: if ignoreProgressValue { title = self.strings.Wallet_Info_Updating diff --git a/submodules/WalletUI/Sources/WalletSendScreen.swift b/submodules/WalletUI/Sources/WalletSendScreen.swift index ed82929010..6018eff219 100644 --- a/submodules/WalletUI/Sources/WalletSendScreen.swift +++ b/submodules/WalletUI/Sources/WalletSendScreen.swift @@ -64,7 +64,7 @@ private enum WalletSendScreenEntry: ItemListNodeEntry { case addressInfo(WalletTheme, String) case commentHeader(WalletTheme, String) case comment(WalletTheme, String, String, Bool) - case commendEncryption(WalletTheme, String, Bool) + case commentEncryption(WalletTheme, String, Bool) var section: ItemListSectionId { switch self { @@ -72,7 +72,7 @@ private enum WalletSendScreenEntry: ItemListNodeEntry { return WalletSendScreenSection.amount.rawValue case .addressHeader, .address, .addressInfo: return WalletSendScreenSection.address.rawValue - case .commentHeader, .comment, .commendEncryption: + case .commentHeader, .comment, .commentEncryption: return WalletSendScreenSection.comment.rawValue } } @@ -93,7 +93,7 @@ private enum WalletSendScreenEntry: ItemListNodeEntry { return 5 case .comment: return 6 - case .commendEncryption: + case .commentEncryption: return 7 } } @@ -142,8 +142,8 @@ private enum WalletSendScreenEntry: ItemListNodeEntry { } else { return false } - case let .commendEncryption(lhsTheme, lhsText, lhsValue): - if case let .commendEncryption(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsText == rhsText { + case let .commentEncryption(lhsTheme, lhsText, lhsValue): + if case let .commentEncryption(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsText == rhsText, lhsValue == rhsValue { return true } else { return false @@ -268,7 +268,7 @@ private enum WalletSendScreenEntry: ItemListNodeEntry { arguments.proceed() } }) - case let .commendEncryption(theme, text, value): + case let .commentEncryption(theme, text, value): return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.updateIsEncrypted(value) }) @@ -291,7 +291,7 @@ private func walletSendScreenEntries(presentationData: WalletPresentationData, b let amount = amountValue(state.amount) let balance = max(0, balance ?? 0) - entries.append(.amount(presentationData.theme, state.amount ?? "")) + entries.append(.amount(presentationData.theme, state.amount)) entries.append(.balance(presentationData.theme, presentationData.strings.Wallet_Send_Balance("").0, formatBalanceText(balance, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator), balance == 0 || (amount > 0 && balance < amount))) entries.append(.addressHeader(presentationData.theme, presentationData.strings.Wallet_Send_AddressHeader)) @@ -300,7 +300,7 @@ private func walletSendScreenEntries(presentationData: WalletPresentationData, b entries.append(.commentHeader(presentationData.theme, presentationData.strings.Wallet_Receive_CommentHeader)) entries.append(.comment(presentationData.theme, presentationData.strings.Wallet_Receive_CommentInfo, state.comment, sendEnabled)) - entries.append(.commendEncryption(presentationData.theme, presentationData.strings.Wallet_Send_EncryptComment, state.isCommentEncrypted)) + entries.append(.commentEncryption(presentationData.theme, presentationData.strings.Wallet_Send_EncryptComment, state.isCommentEncrypted)) return entries } @@ -478,7 +478,7 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo |> deliverOnMainQueue).start(next: { serverSalt in if let serverSalt = serverSalt { if let commentData = state.comment.data(using: .utf8) { - pushImpl?(WalletSplashScreen(context: context, mode: .sending(walletInfo: walletInfo, address: state.address, amount: amount, comment: commentData, encryptComment: state.isCommentEncrypted && !verificationResult.canNotEncryptComment, randomId: randomId, serverSalt: serverSalt), walletCreatedPreloadState: nil)) + pushImpl?(WalletSplashScreen(context: context, mode: .sending(WalletSplashModeSending(walletInfo: walletInfo, address: state.address, amount: amount, comment: commentData, encryptComment: state.isCommentEncrypted && !verificationResult.canNotEncryptComment, randomId: randomId, serverSalt: serverSalt)), walletCreatedPreloadState: nil)) } } }) @@ -624,7 +624,7 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo controller?.push(c) } popImpl = { [weak controller] in - (controller?.navigationController as? NavigationController)?.popViewController(animated: true) + let _ = (controller?.navigationController as? NavigationController)?.popViewController(animated: true) } dismissImpl = { [weak controller] in controller?.view.endEditing(true) @@ -658,7 +658,6 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo } var resultItemNode: ListViewItemNode? - let state = stateValue.with({ $0 }) let _ = controller.frameForItemNode({ itemNode in if let itemNode = itemNode as? ItemListItemNode { if let tag = itemNode.tag, tag.isEqual(to: targetTag) { diff --git a/submodules/WalletUI/Sources/WalletSettingsScreen.swift b/submodules/WalletUI/Sources/WalletSettingsScreen.swift index 564e68073e..b704870310 100644 --- a/submodules/WalletUI/Sources/WalletSettingsScreen.swift +++ b/submodules/WalletUI/Sources/WalletSettingsScreen.swift @@ -105,12 +105,7 @@ private func walletSettingsControllerEntries(presentationData: WalletPresentatio public func walletSettingsController(context: WalletContext, walletInfo: WalletInfo) -> ViewController { let statePromise = ValuePromise(WalletSettingsControllerState(), ignoreRepeated: true) - let stateValue = Atomic(value: WalletSettingsControllerState()) - let updateState: ((WalletSettingsControllerState) -> WalletSettingsControllerState) -> Void = { f in - statePromise.set(stateValue.modify { f($0) }) - } - var dismissImpl: (() -> Void)? var presentControllerImpl: ((ViewController, Any?) -> Void)? var pushControllerImpl: ((ViewController) -> Void)? @@ -181,10 +176,6 @@ public func walletSettingsController(context: WalletContext, walletInfo: WalletI let controller = ItemListController(theme: context.presentationData.theme, strings: context.presentationData.strings, updatedPresentationData: .single((context.presentationData.theme, context.presentationData.strings)), state: signal, tabBarItem: nil) controller.navigationPresentation = .modal controller.enableInteractiveDismiss = true - dismissImpl = { [weak controller] in - controller?.view.endEditing(true) - controller?.dismiss() - } presentControllerImpl = { [weak controller] c, a in controller?.present(c, in: .window(.root), with: a) } diff --git a/submodules/WalletUI/Sources/WalletSplashScreen.swift b/submodules/WalletUI/Sources/WalletSplashScreen.swift index 1d1d1804e2..32ad6c5069 100644 --- a/submodules/WalletUI/Sources/WalletSplashScreen.swift +++ b/submodules/WalletUI/Sources/WalletSplashScreen.swift @@ -17,12 +17,40 @@ public enum WalletSecureStorageResetReason { case changed } +public struct WalletSplashModeSending { + public let walletInfo: WalletInfo + public let address: String + public let amount: Int64 + public let comment: Data + public let encryptComment: Bool + public let randomId: Int64 + public let serverSalt: Data + + public init( + walletInfo: WalletInfo, + address: String, + amount: Int64, + comment: Data, + encryptComment: Bool, + randomId: Int64, + serverSalt: Data + ) { + self.walletInfo = walletInfo + self.address = address + self.amount = amount + self.comment = comment + self.encryptComment = encryptComment + self.randomId = randomId + self.serverSalt = serverSalt + } +} + public enum WalletSplashMode { case intro case created(walletInfo: WalletInfo, words: [String]?) case success(walletInfo: WalletInfo) case restoreFailed - case sending(walletInfo: WalletInfo, address: String, amount: Int64, comment: Data, encryptComment: Bool, randomId: Int64, serverSalt: Data) + case sending(WalletSplashModeSending) case sent(walletInfo: WalletInfo, amount: Int64) case secureStorageNotAvailable case secureStorageReset(WalletSecureStorageResetReason) @@ -81,15 +109,16 @@ public final class WalletSplashScreen: ViewController { self.navigationBar?.intrinsicCanTransitionInline = false switch self.mode { - case let .intro: self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_ImportExisting, style: .plain, target: self, action: #selector(self.importPressed)), animated: false) - case let .sending(walletInfo, address, amount, comment, encryptComment, randomId, serverSalt): + case .intro: + self.navigationItem.setRightBarButton(UIBarButtonItem(title: self.presentationData.strings.Wallet_Intro_ImportExisting, style: .plain, target: self, action: #selector(self.importPressed)), animated: false) + case let .sending(sending): self.navigationItem.setLeftBarButton(UIBarButtonItem(customDisplayNode: ASDisplayNode())!, animated: false) - let _ = (self.context.keychain.decrypt(walletInfo.encryptedSecret) + let _ = (self.context.keychain.decrypt(sending.walletInfo.encryptedSecret) |> deliverOnMainQueue).start(next: { [weak self] decryptedSecret in guard let strongSelf = self else { return } - strongSelf.sendGrams(walletInfo: walletInfo, decryptedSecret: decryptedSecret, address: address, amount: amount, comment: comment, encryptComment: encryptComment, forceIfDestinationNotInitialized: true, randomId: randomId, serverSalt: serverSalt) + strongSelf.sendGrams(walletInfo: sending.walletInfo, decryptedSecret: decryptedSecret, address: sending.address, amount: sending.amount, comment: sending.comment, encryptComment: sending.encryptComment, forceIfDestinationNotInitialized: true, randomId: sending.randomId, serverSalt: sending.serverSalt) }, error: { [weak self] error in guard let strongSelf = self else { return @@ -242,7 +271,7 @@ public final class WalletSplashScreen: ViewController { let controller = textAlertController(alertContext: AlertControllerContext(theme: theme.alert, themeSignal: .single(theme.alert)), title: strongSelf.presentationData.strings.Wallet_Send_UninitializedTitle, text: text, actions: [ TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Wallet_Navigation_Cancel, action: { if let navigationController = strongSelf.navigationController as? NavigationController { - navigationController.popViewController(animated: true) + let _ = navigationController.popViewController(animated: true) } }), TextAlertAction(type: .defaultAction, title: "Send Anyway", action: { @@ -258,7 +287,7 @@ public final class WalletSplashScreen: ViewController { let theme = strongSelf.presentationData.theme let controller = textAlertController(alertContext: AlertControllerContext(theme: theme.alert, themeSignal: .single(theme.alert)), title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Wallet_Alert_OK, action: { if let navigationController = strongSelf.navigationController as? NavigationController { - navigationController.popViewController(animated: true) + let _ = navigationController.popViewController(animated: true) } })]) strongSelf.present(controller, in: .window(.root)) @@ -286,14 +315,14 @@ public final class WalletSplashScreen: ViewController { return true } - let _ = (walletAddress(publicKey: sending.0.publicKey, tonInstance: self.context.tonInstance) + let _ = (walletAddress(publicKey: sending.walletInfo.publicKey, tonInstance: self.context.tonInstance) |> deliverOnMainQueue).start(next: { [weak self] address in guard let strongSelf = self else { return } if !controllers.contains(where: { $0 is WalletInfoScreen }) { - let infoScreen = WalletInfoScreen(context: strongSelf.context, walletInfo: sending.0, address: address, enableDebugActions: false) + let infoScreen = WalletInfoScreen(context: strongSelf.context, walletInfo: sending.walletInfo, address: address, enableDebugActions: false) infoScreen.navigationPresentation = .modal controllers.append(infoScreen) } @@ -498,14 +527,14 @@ public final class WalletSplashScreen: ViewController { return true } - let _ = (walletAddress(publicKey: sending.0.publicKey, tonInstance: strongSelf.context.tonInstance) + let _ = (walletAddress(publicKey: sending.walletInfo.publicKey, tonInstance: strongSelf.context.tonInstance) |> deliverOnMainQueue).start(next: { [weak self] address in guard let strongSelf = self else { return } if !controllers.contains(where: { $0 is WalletInfoScreen }) { - let infoScreen = WalletInfoScreen(context: strongSelf.context, walletInfo: sending.0, address: address, enableDebugActions: false) + let infoScreen = WalletInfoScreen(context: strongSelf.context, walletInfo: sending.walletInfo, address: address, enableDebugActions: false) infoScreen.navigationPresentation = .modal controllers.append(infoScreen) } @@ -891,7 +920,7 @@ private final class WalletSplashScreenNode: ViewControllerTracingNode { let buttonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: layout.size.height - bottomInset - buttonHeight), size: CGSize(width: buttonWidth, height: buttonHeight)) transition.updateFrame(node: self.buttonNode, frame: buttonFrame) - self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) + let _ = self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) var maxContentVerticalOrigin = buttonFrame.minY - 12.0 - contentHeight diff --git a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift index 5aea1460da..c4ca2a8bde 100644 --- a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift @@ -69,6 +69,33 @@ private func stringForAddress(strings: WalletStrings, address: WalletTransaction } } +private extension WalletInfoTransaction { + var isEncrypted: Bool { + switch self { + case .pending: + return false + case let .completed(transaction): + if let inMessage = transaction.inMessage { + switch inMessage.contents { + case .encryptedText: + return true + default: + break + } + } + for message in transaction.outMessages { + switch message.contents { + case .encryptedText: + return true + default: + break + } + } + return false + } + } +} + private func extractAddress(_ walletTransaction: WalletInfoTransaction) -> WalletTransactionAddress { switch walletTransaction { case let .completed(walletTransaction): @@ -90,17 +117,17 @@ private func extractAddress(_ walletTransaction: WalletInfoTransaction) -> Walle return .unknown } } - return .none case let .pending(pending): return .list([pending.address]) } } -private func extractDescription(_ walletTransaction: WalletInfoTransaction) -> String { +private func extractDescription(_ walletTransaction: WalletInfoTransaction) -> (string: String, isEncrypted: Bool) { switch walletTransaction { case let .completed(walletTransaction): let transferredValue = walletTransaction.transferredValueWithoutFees var text = "" + var isEncrypted = false if transferredValue <= 0 { for message in walletTransaction.outMessages { if !text.isEmpty { @@ -110,7 +137,8 @@ private func extractDescription(_ walletTransaction: WalletInfoTransaction) -> S case .raw: break case .encryptedText: - text.append("") + text.append("Encrypted Comment") + isEncrypted = true case let .plainText(plainText): text.append(plainText) } @@ -121,15 +149,16 @@ private func extractDescription(_ walletTransaction: WalletInfoTransaction) -> S case .raw: text = "" case .encryptedText: - text = "" + text = "Encrypted Comment" + isEncrypted = true case let .plainText(plainText): text = plainText } } } - return text + return (text, isEncrypted) case let .pending(pending): - return String(data: pending.comment, encoding: .utf8) ?? "" + return (String(data: pending.comment, encoding: .utf8) ?? "", false) } } @@ -160,7 +189,7 @@ private func messageBubbleImage(incoming: Bool, fillColor: UIColor, strokeColor: final class WalletTransactionInfoScreen: ViewController { private let context: WalletContext private let walletInfo: WalletInfo? - private let walletTransaction: WalletInfoTransaction + private var walletTransaction: WalletInfoTransaction private let walletState: Signal<(CombinedWalletState, Bool), NoError> private var presentationData: WalletPresentationData @@ -234,6 +263,39 @@ final class WalletTransactionInfoScreen: ViewController { } } } + (self.displayNode as! WalletTransactionInfoScreenNode).requestDecryption = { [weak self] in + guard let strongSelf = self, let walletInfo = strongSelf.walletInfo, case let .completed(walletTransaction) = strongSelf.walletTransaction else { + return + } + let keychain = strongSelf.context.keychain + let _ = (strongSelf.context.getServerSalt() + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } + |> mapToSignal { serverSalt -> Signal in + guard let serverSalt = serverSalt else { + return .single(nil) + } + return walletTransactionDecryptionKey(keychain: keychain, walletInfo: walletInfo, localPassword: serverSalt) + } + |> deliverOnMainQueue).start(next: { decryptionKey in + guard let strongSelf = self else { + return + } + if let decryptionKey = decryptionKey { + let _ = (decryptWalletTransactions(decryptionKey: decryptionKey, transactions: [walletTransaction], tonInstance: strongSelf.context.tonInstance) + |> deliverOnMainQueue).start(next: { result in + guard let strongSelf = self, let updatedTransaction = result.first else { + return + } + strongSelf.walletTransaction = .completed(updatedTransaction) + (strongSelf.displayNode as! WalletTransactionInfoScreenNode).updateTransaction(strongSelf.walletTransaction) + (strongSelf.navigationController as? NavigationController)?.requestLayout(transition: .immediate) + }) + } + }) + } (self.displayNode as! WalletTransactionInfoScreenNode).displayFeesTooltip = { [weak self] node, rect in guard let strongSelf = self else { return @@ -255,7 +317,7 @@ final class WalletTransactionInfoScreen: ViewController { } } strongSelf.present(controller, in: .window(.root), with: TooltipControllerPresentationArguments(sourceViewAndRect: { - if let strongSelf = self { + if let _ = self { return (node.view, rect.insetBy(dx: 0.0, dy: -4.0)) } return nil @@ -286,7 +348,8 @@ final class WalletTransactionInfoScreen: ViewController { let minHeight: CGFloat = 424.0 let maxHeight: CGFloat = min(596.0, layout.size.height) - let text = NSAttributedString(string: extractDescription(self.walletTransaction), font: Font.regular(17.0), textColor: .black) + let (plainText, textIsEncrypted) = extractDescription(self.walletTransaction) + let text = NSAttributedString(string: plainText, font: textIsEncrypted ? Font.monospace(17.0) : Font.regular(17.0), textColor: .black) let makeTextLayout = TextNode.asyncLayout(self.measureTextNode) let (textLayout, _) = makeTextLayout(TextNodeLayoutArguments(attributedString: text, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: layout.size.width - 36.0 * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -296,7 +359,13 @@ final class WalletTransactionInfoScreen: ViewController { let minOverscroll: CGFloat = 42.0 let maxOverscroll: CGFloat = 148.0 - let contentHeight = minHeight + textHeight + var contentHeight = minHeight + textHeight + + if textIsEncrypted { + let (decryptTextLayout, _) = TextNode.asyncLayout(nil)(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "Decrypt", font: Font.regular(17.0), textColor: presentationData.theme.list.itemAccentColor), maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: layout.size.width - 40.0, height: .greatestFiniteMagnitude), alignment: .center, insets: UIEdgeInsets())) + contentHeight += 10.0 + decryptTextLayout.size.height + 10.0 + } + let difference = contentHeight - maxHeight if difference < 0.0 { resultHeight = contentHeight @@ -329,7 +398,7 @@ private let fractionalFont = Font.medium(24.0) private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate { private let context: WalletContext private var presentationData: WalletPresentationData - private let walletTransaction: WalletInfoTransaction + private var walletTransaction: WalletInfoTransaction private let incoming: Bool private let titleNode: ImmediateTextNode @@ -345,12 +414,15 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, private let commentBackgroundNode: ASImageNode private let commentTextNode: ImmediateTextNode private let commentSeparatorNode: ASDisplayNode + private let commentDecryptButtonTitle: ImmediateTextNode + private let commentDecryptButton: HighlightableButtonNode private let addressTextNode: ImmediateTextNode private let buttonNode: SolidRoundedButtonNode private var validLayout: (ContainerViewLayout, CGFloat)? var send: ((String) -> Void)? + var requestDecryption: (() -> Void)? var displayFeesTooltip: ((ASDisplayNode, CGRect) -> Void)? var displayCopyContextMenu: ((ASDisplayNode, CGRect, String) -> Void)? @@ -401,6 +473,15 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self.commentSeparatorNode = ASDisplayNode() self.commentSeparatorNode.backgroundColor = self.presentationData.theme.list.itemPlainSeparatorColor + self.commentDecryptButtonTitle = ImmediateTextNode() + self.commentDecryptButtonTitle.attributedText = NSAttributedString(string: "Decrypt", font: Font.regular(17.0), textColor: presentationData.theme.list.itemAccentColor) + self.commentDecryptButtonTitle.textAlignment = .natural + self.commentDecryptButtonTitle.maximumNumberOfLines = 0 + self.commentDecryptButtonTitle.isUserInteractionEnabled = false + + self.commentDecryptButton = HighlightableButtonNode() + self.commentDecryptButton.hitTestSlop = UIEdgeInsets(top: -10.0, left: -10.0, bottom: -10.0, right: -10.0) + self.addressTextNode = ImmediateTextNode() self.addressTextNode.maximumNumberOfLines = 4 self.addressTextNode.textAlignment = .justified @@ -438,8 +519,12 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self.addSubnode(self.timeNode) self.addSubnode(self.amountNode) self.addSubnode(self.commentSeparatorNode) + self.commentDecryptButton.addSubnode(self.commentDecryptButtonTitle) + self.scrollNode.addSubnode(self.commentDecryptButton) self.addSubnode(self.addressTextNode) self.addSubnode(self.buttonNode) + + self.commentDecryptButton.isHidden = !walletTransaction.isEncrypted let titleFont = Font.semibold(17.0) let subtitleFont = Font.regular(13.0) @@ -485,7 +570,8 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, commentBackgroundColor = UIColor(rgb: 0xf1f1f4) } self.commentBackgroundNode.image = messageBubbleImage(incoming: transferredValue > 0, fillColor: commentBackgroundColor, strokeColor: presentationData.theme.transaction.descriptionBackgroundColor) - self.commentTextNode.attributedText = NSAttributedString(string: extractDescription(walletTransaction), font: Font.regular(17.0), textColor: presentationData.theme.transaction.descriptionTextColor) + let (plainText, textIsEncrypted) = extractDescription(walletTransaction) + self.commentTextNode.attributedText = NSAttributedString(string: plainText, font: textIsEncrypted ? Font.monospace(17.0) : Font.regular(17.0), textColor: presentationData.theme.transaction.descriptionTextColor) let address = extractAddress(walletTransaction) var singleAddress: String? @@ -501,6 +587,21 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self?.send?(address) } } + + self.commentDecryptButton.addTarget(self, action: #selector(self.decryptCommentPressed), forControlEvents: .touchUpInside) + } + + @objc private func decryptCommentPressed() { + self.requestDecryption?() + } + + func updateTransaction(_ walletTransaction: WalletInfoTransaction) { + self.walletTransaction = walletTransaction + + let (plainText, textIsEncrypted) = extractDescription(walletTransaction) + self.commentTextNode.attributedText = NSAttributedString(string: plainText, font: textIsEncrypted ? Font.monospace(17.0) : Font.regular(17.0), textColor: presentationData.theme.transaction.descriptionTextColor) + + self.commentDecryptButton.isHidden = !walletTransaction.isEncrypted } override func didLoad() { @@ -509,15 +610,17 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self.scrollNode.view.delegate = self self.scrollNode.view.alwaysBounceVertical = true self.scrollNode.view.showsVerticalScrollIndicator = false + self.scrollNode.view.delaysContentTouches = false + self.scrollNode.view.canCancelContentTouches = true let commentGestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapCommentGesture(_:))) - commentGestureRecognizer.tapActionAtPoint = { [weak self] point in + commentGestureRecognizer.tapActionAtPoint = { point in return .waitForSingleTap } self.commentBackgroundNode.view.addGestureRecognizer(commentGestureRecognizer) let addressGestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapAddressGesture(_:))) - addressGestureRecognizer.tapActionAtPoint = { [weak self] point in + addressGestureRecognizer.tapActionAtPoint = { point in return .waitForSingleTap } self.addressTextNode.view.addGestureRecognizer(addressGestureRecognizer) @@ -526,10 +629,10 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, @objc func tapLongTapOrDoubleTapCommentGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: - if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { + if let (gesture, _) = recognizer.lastRecognizedGestureAndLocation { switch gesture { case .longTap: - let description = extractDescription(self.walletTransaction) + let (description, _) = extractDescription(self.walletTransaction) if !description.isEmpty { self.displayCopyContextMenu?(self, self.commentBackgroundNode.convert(self.commentBackgroundNode.bounds, to: self), description) } @@ -545,7 +648,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, @objc func tapLongTapOrDoubleTapAddressGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { switch recognizer.state { case .ended: - if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { + if let (gesture, _) = recognizer.lastRecognizedGestureAndLocation { switch gesture { case .longTap: let address = extractAddress(self.walletTransaction) @@ -668,7 +771,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, let buttonHeight: CGFloat = 50.0 let buttonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: layout.size.height - bottomInset - buttonHeight), size: CGSize(width: buttonWidth, height: buttonHeight)) transition.updateFrame(node: self.buttonNode, frame: buttonFrame) - self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) + let _ = self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) let addressSize = self.addressTextNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude)) let addressFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - addressSize.width) / 2.0), y: buttonFrame.minY - addressSize.height - 34.0), size: addressSize) @@ -695,7 +798,18 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, } transition.updateFrame(node: self.commentBackgroundNode, frame: commentBackgroundFrame) - let contentHeight = commentOrigin.y + commentBackgroundFrame.height + var commentMaxY = commentOrigin.y + commentBackgroundFrame.height + + let decryptSize = self.commentDecryptButtonTitle.updateLayout(CGSize(width: layout.size.width - 40.0, height: .greatestFiniteMagnitude)) + let decryptButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - decryptSize.width) / 2.0), y: commentMaxY + 10.0), size: decryptSize) + transition.updateFrame(node: self.commentDecryptButton, frame: decryptButtonFrame) + transition.updateFrame(node: self.commentDecryptButtonTitle, frame: CGRect(origin: CGPoint(), size: decryptSize)) + + if self.walletTransaction.isEncrypted { + commentMaxY = decryptButtonFrame.maxY + 10.0 + } + + let contentHeight = commentMaxY self.scrollNode.view.contentSize = CGSize(width: layout.size.width, height: contentHeight) let isScrollEnabled = contentHeight - scrollFrame.height > 20.0 diff --git a/submodules/WalletUI/Sources/WalletUtils.swift b/submodules/WalletUI/Sources/WalletUtils.swift index 357bba47a5..2b55bffe44 100644 --- a/submodules/WalletUI/Sources/WalletUtils.swift +++ b/submodules/WalletUI/Sources/WalletUtils.swift @@ -82,7 +82,6 @@ func isValidAmount(_ amount: String) -> Bool { return false } var hasDecimalSeparator = false - var hasLeadingZero = false var index = 0 for c in amount { if c == "." || c == "," { diff --git a/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift b/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift index bbc72168fc..34cb938aa6 100644 --- a/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift +++ b/submodules/WalletUI/Sources/WalletWordDisplayScreen.swift @@ -321,11 +321,8 @@ private final class WalletWordDisplayScreenNode: ViewControllerTracingNode, UISc contentHeight = textFrame.maxY + textSpacing - let rowWidth = layout.size.width - buttonSideInset * 2.0 let rowCount = self.wordNodes.count / 2 - let indexWidth: CGFloat = 16.0 - var wordSizes: [(CGSize, CGSize)] = [] var columnIndexWidth: [CGFloat] = [0.0, 0.0] var columnWordWidth: [CGFloat] = [0.0, 0.0] @@ -371,16 +368,14 @@ private final class WalletWordDisplayScreenNode: ViewControllerTracingNode, UISc } } - let minimalFullscreenBottomInset: CGFloat = 74.0 let minimalScrollBottomInset: CGFloat = 30.0 - let fullscreenBottomInset = layout.intrinsicInsets.bottom + minimalFullscreenBottomInset let scrollBottomInset = layout.intrinsicInsets.bottom + minimalScrollBottomInset let buttonWidth = layout.size.width - buttonSideInset * 2.0 let buttonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: max(contentHeight + buttonSpacing, layout.size.height - scrollBottomInset - buttonHeight)), size: CGSize(width: buttonWidth, height: buttonHeight)) transition.updateFrame(node: self.buttonNode, frame: buttonFrame) - self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) + let _ = self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) self.scrollNode.view.contentSize = CGSize(width: layout.size.width, height: max(layout.size.height, buttonFrame.maxY + scrollBottomInset)) @@ -395,7 +390,7 @@ private final class WalletWordDisplayScreenNode: ViewControllerTracingNode, UISc if let path = getAppBundle().path(forResource: "WalletApologiesAccepted", ofType: "tgs") { let toastNode = ToastNode(theme: self.presentationData.theme, animationPath: path, text: self.presentationData.strings.Wallet_Words_NotDoneResponse) self.toastNode = toastNode - if let (layout, navigationHeight) = self.validLayout { + if let (layout, _) = self.validLayout { toastNode.update(layout: layout, transition: .immediate) } self.addSubnode(toastNode) diff --git a/submodules/lottie-ios/BUILD b/submodules/lottie-ios/BUILD index 9d59ea6e57..1e431e1a40 100644 --- a/submodules/lottie-ios/BUILD +++ b/submodules/lottie-ios/BUILD @@ -1,4 +1,4 @@ -load("//build-system:unique_directories.bzl", "unique_directories") +load("//build-system/bazel-utils:unique_directories.bzl", "unique_directories") private_headers = glob([ "lottie-ios/**/*.h", diff --git a/submodules/ton/tonlib-src/crypto/CMakeLists.txt b/submodules/ton/tonlib-src/crypto/CMakeLists.txt index 37f427cae2..7be5475bcd 100644 --- a/submodules/ton/tonlib-src/crypto/CMakeLists.txt +++ b/submodules/ton/tonlib-src/crypto/CMakeLists.txt @@ -48,6 +48,7 @@ set(TON_CRYPTO_SOURCE common/refint.h common/bigexp.h common/util.h + common/linalloc.hpp ellcurve/Ed25519.h ellcurve/Fp25519.h @@ -390,7 +391,7 @@ endif() add_executable(create-state block/create-state.cpp) target_include_directories(create-state PUBLIC $ $) -target_link_libraries(create-state PUBLIC ton_crypto fift-lib ton_block) +target_link_libraries(create-state PUBLIC ton_crypto fift-lib ton_block tonlib) if (WINGETOPT_FOUND) target_link_libraries_system(create-state wingetopt) endif() diff --git a/submodules/ton/tonlib-src/crypto/Ed25519.cpp b/submodules/ton/tonlib-src/crypto/Ed25519.cpp index 6a21f83f66..11e20f66e6 100644 --- a/submodules/ton/tonlib-src/crypto/Ed25519.cpp +++ b/submodules/ton/tonlib-src/crypto/Ed25519.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include "crypto/Ed25519.h" @@ -310,6 +310,10 @@ Result Ed25519::compute_shared_secret(const PublicKey &public_key, return std::move(result); } +int Ed25519::version() { + return OPENSSL_VERSION_NUMBER; +} + #else Result Ed25519::generate_private_key() { @@ -387,6 +391,10 @@ Result Ed25519::compute_shared_secret(const PublicKey &public_key, return std::move(shared_secret); } +int Ed25519::version() { + return 0; +} + #endif } // namespace td diff --git a/submodules/ton/tonlib-src/crypto/Ed25519.h b/submodules/ton/tonlib-src/crypto/Ed25519.h index 21dcf7dd37..a3340d2eca 100644 --- a/submodules/ton/tonlib-src/crypto/Ed25519.h +++ b/submodules/ton/tonlib-src/crypto/Ed25519.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once @@ -65,6 +65,8 @@ class Ed25519 { static Result generate_private_key(); static Result compute_shared_secret(const PublicKey &public_key, const PrivateKey &private_key); + + static int version(); }; } // namespace td diff --git a/submodules/ton/tonlib-src/crypto/block/block-auto.cpp b/submodules/ton/tonlib-src/crypto/block/block-auto.cpp index d2bf8aea89..ba3817074a 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-auto.cpp +++ b/submodules/ton/tonlib-src/crypto/block/block-auto.cpp @@ -14,6 +14,7 @@ // uses built-in type `uint` // uses built-in type `bits` // uses built-in type `int8` +// uses built-in type `uint8` // uses built-in type `uint13` // uses built-in type `uint15` // uses built-in type `int16` @@ -23,6 +24,7 @@ // uses built-in type `uint63` // uses built-in type `int64` // uses built-in type `uint64` +// uses built-in type `uint256` // uses built-in type `int257` // uses built-in type `bits256` @@ -10686,38 +10688,42 @@ int BlockInfo::check_tag(const vm::CellSlice& cs) const { } bool BlockInfo::skip(vm::CellSlice& cs) const { - int not_master, after_merge, vert_seqno_incr, seq_no, vert_seq_no, prev_seq_no; + int not_master, after_merge, vert_seqno_incr, flags, seq_no, vert_seq_no, prev_seq_no; return cs.advance(64) && cs.fetch_bool_to(not_master) && cs.fetch_bool_to(after_merge) && cs.advance(5) && cs.fetch_bool_to(vert_seqno_incr) - && cs.advance(8) + && cs.fetch_uint_to(8, flags) + && flags <= 1 && cs.fetch_uint_to(32, seq_no) && cs.fetch_uint_to(32, vert_seq_no) && vert_seqno_incr <= vert_seq_no && add_r1(prev_seq_no, 1, seq_no) && cs.advance(392) + && (!(flags & 1) || cs.advance(104)) && (!not_master || cs.advance_refs(1)) && cs.advance_refs(1) && (!vert_seqno_incr || cs.advance_refs(1)); } bool BlockInfo::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const { - int not_master, after_merge, vert_seqno_incr, seq_no, vert_seq_no, prev_seq_no; + int not_master, after_merge, vert_seqno_incr, flags, seq_no, vert_seq_no, prev_seq_no; return cs.fetch_ulong(32) == 0x9bc7a987U && cs.advance(32) && cs.fetch_bool_to(not_master) && cs.fetch_bool_to(after_merge) && cs.advance(5) && cs.fetch_bool_to(vert_seqno_incr) - && cs.advance(8) + && cs.fetch_uint_to(8, flags) + && flags <= 1 && cs.fetch_uint_to(32, seq_no) && cs.fetch_uint_to(32, vert_seq_no) && vert_seqno_incr <= vert_seq_no && add_r1(prev_seq_no, 1, seq_no) && t_ShardIdent.validate_skip(ops, cs, weak) && cs.advance(288) + && (!(flags & 1) || t_GlobalVersion.validate_skip(ops, cs, weak)) && (!not_master || t_BlkMasterInfo.validate_skip_ref(ops, cs, weak)) && BlkPrevInfo{after_merge}.validate_skip_ref(ops, cs, weak) && (!vert_seqno_incr || t_BlkPrevInfo_0.validate_skip_ref(ops, cs, weak)); @@ -10736,6 +10742,7 @@ bool BlockInfo::unpack(vm::CellSlice& cs, BlockInfo::Record& data) const { && cs.fetch_bool_to(data.key_block) && cs.fetch_bool_to(data.vert_seqno_incr) && cs.fetch_uint_to(8, data.flags) + && data.flags <= 1 && cs.fetch_uint_to(32, data.seq_no) && cs.fetch_uint_to(32, data.vert_seq_no) && data.vert_seqno_incr <= data.vert_seq_no @@ -10748,6 +10755,7 @@ bool BlockInfo::unpack(vm::CellSlice& cs, BlockInfo::Record& data) const { && cs.fetch_uint_to(32, data.gen_catchain_seqno) && cs.fetch_uint_to(32, data.min_ref_mc_seqno) && cs.fetch_uint_to(32, data.prev_key_block_seqno) + && (!(data.flags & 1) || cs.fetch_subslice_to(104, data.gen_software)) && (!data.not_master || cs.fetch_ref_to(data.master_ref)) && cs.fetch_ref_to(data.prev_ref) && (!data.vert_seqno_incr || cs.fetch_ref_to(data.prev_vert_ref)); @@ -10772,6 +10780,7 @@ bool BlockInfo::pack(vm::CellBuilder& cb, const BlockInfo::Record& data) const { && cb.store_ulong_rchk_bool(data.key_block, 1) && cb.store_ulong_rchk_bool(data.vert_seqno_incr, 1) && cb.store_ulong_rchk_bool(data.flags, 8) + && data.flags <= 1 && cb.store_ulong_rchk_bool(data.seq_no, 32) && cb.store_ulong_rchk_bool(data.vert_seq_no, 32) && data.vert_seqno_incr <= data.vert_seq_no @@ -10784,6 +10793,7 @@ bool BlockInfo::pack(vm::CellBuilder& cb, const BlockInfo::Record& data) const { && cb.store_ulong_rchk_bool(data.gen_catchain_seqno, 32) && cb.store_ulong_rchk_bool(data.min_ref_mc_seqno, 32) && cb.store_ulong_rchk_bool(data.prev_key_block_seqno, 32) + && (!(data.flags & 1) || cb.append_cellslice_chk(data.gen_software, 104)) && (!data.not_master || cb.store_ref_bool(data.master_ref)) && cb.store_ref_bool(data.prev_ref) && (!data.vert_seqno_incr || cb.store_ref_bool(data.prev_vert_ref)); @@ -10814,6 +10824,7 @@ bool BlockInfo::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { && pp.field_int(vert_seqno_incr, "vert_seqno_incr") && cs.fetch_uint_to(8, flags) && pp.field_int(flags, "flags") + && flags <= 1 && cs.fetch_uint_to(32, seq_no) && pp.field_int(seq_no, "seq_no") && cs.fetch_uint_to(32, vert_seq_no) @@ -10829,6 +10840,7 @@ bool BlockInfo::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { && pp.fetch_uint_field(cs, 32, "gen_catchain_seqno") && pp.fetch_uint_field(cs, 32, "min_ref_mc_seqno") && pp.fetch_uint_field(cs, 32, "prev_key_block_seqno") + && (!(flags & 1) || (pp.field("gen_software") && t_GlobalVersion.print_skip(pp, cs))) && (!not_master || (pp.field("master_ref") && t_BlkMasterInfo.print_ref(pp, cs.fetch_ref()))) && pp.field("prev_ref") && BlkPrevInfo{after_merge}.print_ref(pp, cs.fetch_ref()) @@ -14057,6 +14069,309 @@ bool GlobalVersion::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { const GlobalVersion t_GlobalVersion; +// +// code for type `ConfigProposalSetup` +// +constexpr unsigned char ConfigProposalSetup::cons_tag[1]; + +int ConfigProposalSetup::check_tag(const vm::CellSlice& cs) const { + return cs.prefetch_ulong(8) == 0x36 ? cfg_vote_cfg : -1; +} + +bool ConfigProposalSetup::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const { + return cs.fetch_ulong(8) == 0x36 + && cs.advance(160); +} + +bool ConfigProposalSetup::unpack(vm::CellSlice& cs, ConfigProposalSetup::Record& data) const { + return cs.fetch_ulong(8) == 0x36 + && cs.fetch_uint_to(8, data.min_tot_rounds) + && cs.fetch_uint_to(8, data.max_tot_rounds) + && cs.fetch_uint_to(8, data.min_wins) + && cs.fetch_uint_to(8, data.max_losses) + && cs.fetch_uint_to(32, data.min_store_sec) + && cs.fetch_uint_to(32, data.max_store_sec) + && cs.fetch_uint_to(32, data.bit_price) + && cs.fetch_uint_to(32, data.cell_price); +} + +bool ConfigProposalSetup::cell_unpack(Ref cell_ref, ConfigProposalSetup::Record& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool ConfigProposalSetup::pack(vm::CellBuilder& cb, const ConfigProposalSetup::Record& data) const { + return cb.store_long_bool(0x36, 8) + && cb.store_ulong_rchk_bool(data.min_tot_rounds, 8) + && cb.store_ulong_rchk_bool(data.max_tot_rounds, 8) + && cb.store_ulong_rchk_bool(data.min_wins, 8) + && cb.store_ulong_rchk_bool(data.max_losses, 8) + && cb.store_ulong_rchk_bool(data.min_store_sec, 32) + && cb.store_ulong_rchk_bool(data.max_store_sec, 32) + && cb.store_ulong_rchk_bool(data.bit_price, 32) + && cb.store_ulong_rchk_bool(data.cell_price, 32); +} + +bool ConfigProposalSetup::cell_pack(Ref& cell_ref, const ConfigProposalSetup::Record& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigProposalSetup::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { + return cs.fetch_ulong(8) == 0x36 + && pp.open("cfg_vote_cfg") + && pp.fetch_uint_field(cs, 8, "min_tot_rounds") + && pp.fetch_uint_field(cs, 8, "max_tot_rounds") + && pp.fetch_uint_field(cs, 8, "min_wins") + && pp.fetch_uint_field(cs, 8, "max_losses") + && pp.fetch_uint_field(cs, 32, "min_store_sec") + && pp.fetch_uint_field(cs, 32, "max_store_sec") + && pp.fetch_uint_field(cs, 32, "bit_price") + && pp.fetch_uint_field(cs, 32, "cell_price") + && pp.close(); +} + +const ConfigProposalSetup t_ConfigProposalSetup; + +// +// code for type `ConfigVotingSetup` +// +constexpr unsigned char ConfigVotingSetup::cons_tag[1]; + +int ConfigVotingSetup::check_tag(const vm::CellSlice& cs) const { + return cs.prefetch_ulong(8) == 0x91 ? cfg_vote_setup : -1; +} + +bool ConfigVotingSetup::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const { + return cs.fetch_ulong(8) == 0x91 + && t_ConfigProposalSetup.validate_skip_ref(ops, cs, weak) + && t_ConfigProposalSetup.validate_skip_ref(ops, cs, weak); +} + +bool ConfigVotingSetup::unpack(vm::CellSlice& cs, ConfigVotingSetup::Record& data) const { + return cs.fetch_ulong(8) == 0x91 + && cs.fetch_ref_to(data.normal_params) + && cs.fetch_ref_to(data.critical_params); +} + +bool ConfigVotingSetup::unpack_cfg_vote_setup(vm::CellSlice& cs, Ref& normal_params, Ref& critical_params) const { + return cs.fetch_ulong(8) == 0x91 + && cs.fetch_ref_to(normal_params) + && cs.fetch_ref_to(critical_params); +} + +bool ConfigVotingSetup::cell_unpack(Ref cell_ref, ConfigVotingSetup::Record& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool ConfigVotingSetup::cell_unpack_cfg_vote_setup(Ref cell_ref, Ref& normal_params, Ref& critical_params) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack_cfg_vote_setup(cs, normal_params, critical_params) && cs.empty_ext(); +} + +bool ConfigVotingSetup::pack(vm::CellBuilder& cb, const ConfigVotingSetup::Record& data) const { + return cb.store_long_bool(0x91, 8) + && cb.store_ref_bool(data.normal_params) + && cb.store_ref_bool(data.critical_params); +} + +bool ConfigVotingSetup::pack_cfg_vote_setup(vm::CellBuilder& cb, Ref normal_params, Ref critical_params) const { + return cb.store_long_bool(0x91, 8) + && cb.store_ref_bool(normal_params) + && cb.store_ref_bool(critical_params); +} + +bool ConfigVotingSetup::cell_pack(Ref& cell_ref, const ConfigVotingSetup::Record& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigVotingSetup::cell_pack_cfg_vote_setup(Ref& cell_ref, Ref normal_params, Ref critical_params) const { + vm::CellBuilder cb; + return pack_cfg_vote_setup(cb, std::move(normal_params), std::move(critical_params)) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigVotingSetup::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { + return cs.fetch_ulong(8) == 0x91 + && pp.open("cfg_vote_setup") + && pp.field("normal_params") + && t_ConfigProposalSetup.print_ref(pp, cs.fetch_ref()) + && pp.field("critical_params") + && t_ConfigProposalSetup.print_ref(pp, cs.fetch_ref()) + && pp.close(); +} + +const ConfigVotingSetup t_ConfigVotingSetup; + +// +// code for type `ConfigProposal` +// +constexpr unsigned char ConfigProposal::cons_tag[1]; + +int ConfigProposal::check_tag(const vm::CellSlice& cs) const { + return cs.prefetch_ulong(8) == 0xf3 ? cfg_proposal : -1; +} + +bool ConfigProposal::skip(vm::CellSlice& cs) const { + return cs.advance(40) + && t_Maybe_Ref_Cell.skip(cs) + && t_Maybe_uint256.skip(cs); +} + +bool ConfigProposal::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const { + return cs.fetch_ulong(8) == 0xf3 + && cs.advance(32) + && t_Maybe_Ref_Cell.validate_skip(ops, cs, weak) + && t_Maybe_uint256.validate_skip(ops, cs, weak); +} + +bool ConfigProposal::unpack(vm::CellSlice& cs, ConfigProposal::Record& data) const { + return cs.fetch_ulong(8) == 0xf3 + && cs.fetch_int_to(32, data.param_id) + && t_Maybe_Ref_Cell.fetch_to(cs, data.param_value) + && t_Maybe_uint256.fetch_to(cs, data.if_hash_equal); +} + +bool ConfigProposal::unpack_cfg_proposal(vm::CellSlice& cs, int& param_id, Ref& param_value, Ref& if_hash_equal) const { + return cs.fetch_ulong(8) == 0xf3 + && cs.fetch_int_to(32, param_id) + && t_Maybe_Ref_Cell.fetch_to(cs, param_value) + && t_Maybe_uint256.fetch_to(cs, if_hash_equal); +} + +bool ConfigProposal::cell_unpack(Ref cell_ref, ConfigProposal::Record& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool ConfigProposal::cell_unpack_cfg_proposal(Ref cell_ref, int& param_id, Ref& param_value, Ref& if_hash_equal) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack_cfg_proposal(cs, param_id, param_value, if_hash_equal) && cs.empty_ext(); +} + +bool ConfigProposal::pack(vm::CellBuilder& cb, const ConfigProposal::Record& data) const { + return cb.store_long_bool(0xf3, 8) + && cb.store_long_rchk_bool(data.param_id, 32) + && t_Maybe_Ref_Cell.store_from(cb, data.param_value) + && t_Maybe_uint256.store_from(cb, data.if_hash_equal); +} + +bool ConfigProposal::pack_cfg_proposal(vm::CellBuilder& cb, int param_id, Ref param_value, Ref if_hash_equal) const { + return cb.store_long_bool(0xf3, 8) + && cb.store_long_rchk_bool(param_id, 32) + && t_Maybe_Ref_Cell.store_from(cb, param_value) + && t_Maybe_uint256.store_from(cb, if_hash_equal); +} + +bool ConfigProposal::cell_pack(Ref& cell_ref, const ConfigProposal::Record& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigProposal::cell_pack_cfg_proposal(Ref& cell_ref, int param_id, Ref param_value, Ref if_hash_equal) const { + vm::CellBuilder cb; + return pack_cfg_proposal(cb, param_id, std::move(param_value), std::move(if_hash_equal)) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigProposal::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { + return cs.fetch_ulong(8) == 0xf3 + && pp.open("cfg_proposal") + && pp.fetch_int_field(cs, 32, "param_id") + && pp.field("param_value") + && t_Maybe_Ref_Cell.print_skip(pp, cs) + && pp.field("if_hash_equal") + && t_Maybe_uint256.print_skip(pp, cs) + && pp.close(); +} + +const ConfigProposal t_ConfigProposal; + +// +// code for type `ConfigProposalStatus` +// +constexpr unsigned char ConfigProposalStatus::cons_tag[1]; + +int ConfigProposalStatus::check_tag(const vm::CellSlice& cs) const { + return cs.prefetch_ulong(8) == 0xce ? cfg_proposal_status : -1; +} + +bool ConfigProposalStatus::skip(vm::CellSlice& cs) const { + return cs.advance_ext(0x10029) + && t_HashmapE_16_True.skip(cs) + && cs.advance(344); +} + +bool ConfigProposalStatus::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const { + return cs.fetch_ulong(8) == 0xce + && cs.advance(32) + && t_ConfigProposal.validate_skip_ref(ops, cs, weak) + && cs.advance(1) + && t_HashmapE_16_True.validate_skip(ops, cs, weak) + && cs.advance(344); +} + +bool ConfigProposalStatus::unpack(vm::CellSlice& cs, ConfigProposalStatus::Record& data) const { + return cs.fetch_ulong(8) == 0xce + && cs.fetch_uint_to(32, data.expires) + && cs.fetch_ref_to(data.proposal) + && cs.fetch_bool_to(data.is_critical) + && t_HashmapE_16_True.fetch_to(cs, data.voters) + && cs.fetch_int_to(64, data.remaining_weight) + && cs.fetch_uint256_to(256, data.validator_set_id) + && cs.fetch_uint_to(8, data.rounds_remaining) + && cs.fetch_uint_to(8, data.wins) + && cs.fetch_uint_to(8, data.losses); +} + +bool ConfigProposalStatus::cell_unpack(Ref cell_ref, ConfigProposalStatus::Record& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool ConfigProposalStatus::pack(vm::CellBuilder& cb, const ConfigProposalStatus::Record& data) const { + return cb.store_long_bool(0xce, 8) + && cb.store_ulong_rchk_bool(data.expires, 32) + && cb.store_ref_bool(data.proposal) + && cb.store_ulong_rchk_bool(data.is_critical, 1) + && t_HashmapE_16_True.store_from(cb, data.voters) + && cb.store_long_rchk_bool(data.remaining_weight, 64) + && cb.store_int256_bool(data.validator_set_id, 256, false) + && cb.store_ulong_rchk_bool(data.rounds_remaining, 8) + && cb.store_ulong_rchk_bool(data.wins, 8) + && cb.store_ulong_rchk_bool(data.losses, 8); +} + +bool ConfigProposalStatus::cell_pack(Ref& cell_ref, const ConfigProposalStatus::Record& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigProposalStatus::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { + return cs.fetch_ulong(8) == 0xce + && pp.open("cfg_proposal_status") + && pp.fetch_uint_field(cs, 32, "expires") + && pp.field("proposal") + && t_ConfigProposal.print_ref(pp, cs.fetch_ref()) + && pp.fetch_uint_field(cs, 1, "is_critical") + && pp.field("voters") + && t_HashmapE_16_True.print_skip(pp, cs) + && pp.fetch_int_field(cs, 64, "remaining_weight") + && pp.fetch_uint256_field(cs, 256, "validator_set_id") + && pp.fetch_uint_field(cs, 8, "rounds_remaining") + && pp.fetch_uint_field(cs, 8, "wins") + && pp.fetch_uint_field(cs, 8, "losses") + && pp.close(); +} + +const ConfigProposalStatus t_ConfigProposalStatus; + // // code for type `WorkchainFormat` // @@ -15219,6 +15534,10 @@ int ConfigParam::get_tag(const vm::CellSlice& cs) const { return cons8; case 9: return cons9; + case 10: + return cons10; + case 11: + return cons11; case 12: return cons12; case 14: @@ -15288,6 +15607,10 @@ int ConfigParam::check_tag(const vm::CellSlice& cs) const { return cons8; case cons9: return cons9; + case cons10: + return cons10; + case cons11: + return cons11; case cons12: return cons12; case cons14: @@ -15366,6 +15689,12 @@ bool ConfigParam::skip(vm::CellSlice& cs) const { case cons9: return t_Hashmap_32_True.skip(cs) && m_ == 9; + case cons10: + return t_Hashmap_32_True.skip(cs) + && m_ == 10; + case cons11: + return cs.advance_ext(0x20008) + && m_ == 11; case cons12: return t_HashmapE_32_WorkchainDescr.skip(cs) && m_ == 12; @@ -15476,6 +15805,12 @@ bool ConfigParam::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const { case cons9: return t_Hashmap_32_True.validate_skip(ops, cs, weak) && m_ == 9; + case cons10: + return t_Hashmap_32_True.validate_skip(ops, cs, weak) + && m_ == 10; + case cons11: + return t_ConfigVotingSetup.validate_skip(ops, cs, weak) + && m_ == 11; case cons12: return t_HashmapE_32_WorkchainDescr.validate_skip(ops, cs, weak) && m_ == 12; @@ -15756,6 +16091,50 @@ bool ConfigParam::cell_unpack_cons9(Ref cell_ref, Ref& mand return unpack_cons9(cs, mandatory_params) && cs.empty_ext(); } +bool ConfigParam::unpack(vm::CellSlice& cs, ConfigParam::Record_cons10& data) const { + return t_Hashmap_32_True.fetch_to(cs, data.critical_params) + && m_ == 10; +} + +bool ConfigParam::unpack_cons10(vm::CellSlice& cs, Ref& critical_params) const { + return t_Hashmap_32_True.fetch_to(cs, critical_params) + && m_ == 10; +} + +bool ConfigParam::cell_unpack(Ref cell_ref, ConfigParam::Record_cons10& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool ConfigParam::cell_unpack_cons10(Ref cell_ref, Ref& critical_params) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack_cons10(cs, critical_params) && cs.empty_ext(); +} + +bool ConfigParam::unpack(vm::CellSlice& cs, ConfigParam::Record_cons11& data) const { + return cs.fetch_subslice_ext_to(0x20008, data.x) + && m_ == 11; +} + +bool ConfigParam::unpack_cons11(vm::CellSlice& cs, Ref& x) const { + return cs.fetch_subslice_ext_to(0x20008, x) + && m_ == 11; +} + +bool ConfigParam::cell_unpack(Ref cell_ref, ConfigParam::Record_cons11& data) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack(cs, data) && cs.empty_ext(); +} + +bool ConfigParam::cell_unpack_cons11(Ref cell_ref, Ref& x) const { + if (cell_ref.is_null()) { return false; } + auto cs = load_cell_slice(std::move(cell_ref)); + return unpack_cons11(cs, x) && cs.empty_ext(); +} + bool ConfigParam::unpack(vm::CellSlice& cs, ConfigParam::Record_cons12& data) const { return t_HashmapE_32_WorkchainDescr.fetch_to(cs, data.workchains) && m_ == 12; @@ -16416,6 +16795,46 @@ bool ConfigParam::cell_pack_cons9(Ref& cell_ref, Ref mandat return pack_cons9(cb, std::move(mandatory_params)) && std::move(cb).finalize_to(cell_ref); } +bool ConfigParam::pack(vm::CellBuilder& cb, const ConfigParam::Record_cons10& data) const { + return t_Hashmap_32_True.store_from(cb, data.critical_params) + && m_ == 10; +} + +bool ConfigParam::pack_cons10(vm::CellBuilder& cb, Ref critical_params) const { + return t_Hashmap_32_True.store_from(cb, critical_params) + && m_ == 10; +} + +bool ConfigParam::cell_pack(Ref& cell_ref, const ConfigParam::Record_cons10& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigParam::cell_pack_cons10(Ref& cell_ref, Ref critical_params) const { + vm::CellBuilder cb; + return pack_cons10(cb, std::move(critical_params)) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigParam::pack(vm::CellBuilder& cb, const ConfigParam::Record_cons11& data) const { + return cb.append_cellslice_chk(data.x, 0x20008) + && m_ == 11; +} + +bool ConfigParam::pack_cons11(vm::CellBuilder& cb, Ref x) const { + return cb.append_cellslice_chk(x, 0x20008) + && m_ == 11; +} + +bool ConfigParam::cell_pack(Ref& cell_ref, const ConfigParam::Record_cons11& data) const { + vm::CellBuilder cb; + return pack(cb, data) && std::move(cb).finalize_to(cell_ref); +} + +bool ConfigParam::cell_pack_cons11(Ref& cell_ref, Ref x) const { + vm::CellBuilder cb; + return pack_cons11(cb, std::move(x)) && std::move(cb).finalize_to(cell_ref); +} + bool ConfigParam::pack(vm::CellBuilder& cb, const ConfigParam::Record_cons12& data) const { return t_HashmapE_32_WorkchainDescr.store_from(cb, data.workchains) && m_ == 12; @@ -16905,6 +17324,18 @@ bool ConfigParam::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const { && t_Hashmap_32_True.print_skip(pp, cs) && m_ == 9 && pp.close(); + case cons10: + return pp.open() + && pp.field("critical_params") + && t_Hashmap_32_True.print_skip(pp, cs) + && m_ == 10 + && pp.close(); + case cons11: + return pp.open() + && pp.field() + && t_ConfigVotingSetup.print_skip(pp, cs) + && m_ == 11 + && pp.close(); case cons12: return pp.open() && pp.field("workchains") @@ -21128,8 +21559,8 @@ const RefT t_Ref_OutMsgDescr{t_OutMsgDescr}; const RefT t_Ref_ShardAccountBlocks{t_ShardAccountBlocks}; const RefT t_Ref_McBlockExtra{t_McBlockExtra}; const Maybe t_Maybe_Ref_McBlockExtra{t_Ref_McBlockExtra}; -const RefT t_Ref_TYPE_1648{t_ValueFlow_aux}; -const RefT t_Ref_TYPE_1649{t_ValueFlow_aux1}; +const RefT t_Ref_TYPE_1649{t_ValueFlow_aux}; +const RefT t_Ref_TYPE_1650{t_ValueFlow_aux1}; const NatWidth t_natwidth_3{3}; const BinTree t_BinTree_ShardDescr{t_ShardDescr}; const RefT t_Ref_BinTree_ShardDescr{t_BinTree_ShardDescr}; @@ -21142,14 +21573,21 @@ const HashmapE t_HashmapE_256_CreatorStats{256, t_CreatorStats}; const HashmapAugE t_HashmapAugE_256_CreatorStats_uint32{256, t_CreatorStats, t_uint32}; const NatWidth t_natwidth_16{16}; const Maybe t_Maybe_ExtBlkRef{t_ExtBlkRef}; -const RefT t_Ref_TYPE_1666{t_McStateExtra_aux}; +const RefT t_Ref_TYPE_1667{t_McStateExtra_aux}; const RefT t_Ref_SignedCertificate{t_SignedCertificate}; const HashmapE t_HashmapE_16_CryptoSignaturePair{16, t_CryptoSignaturePair}; const Maybe t_Maybe_Ref_InMsg{t_Ref_InMsg}; -const RefT t_Ref_TYPE_1674{t_McBlockExtra_aux}; +const RefT t_Ref_TYPE_1675{t_McBlockExtra_aux}; const Hashmap t_Hashmap_16_ValidatorDescr{16, t_ValidatorDescr}; const HashmapE t_HashmapE_16_ValidatorDescr{16, t_ValidatorDescr}; const Hashmap t_Hashmap_32_True{32, t_True}; +const UInt t_uint8{8}; +const RefT t_Ref_ConfigProposalSetup{t_ConfigProposalSetup}; +const UInt t_uint256{256}; +const Maybe t_Maybe_uint256{t_uint256}; +const RefT t_Ref_ConfigProposal{t_ConfigProposal}; +const HashmapE t_HashmapE_16_True{16, t_True}; +const Int t_int64{64}; const NatWidth t_natwidth_12{12}; const NatWidth t_natwidth_32{32}; const NatWidth t_natwidth_13{13}; @@ -21162,14 +21600,13 @@ const RefT t_Ref_BlockSignatures{t_BlockSignatures}; const Maybe t_Maybe_Ref_BlockSignatures{t_Ref_BlockSignatures}; const RefT t_Ref_TopBlockDescr{t_TopBlockDescr}; const HashmapE t_HashmapE_96_Ref_TopBlockDescr{96, t_Ref_TopBlockDescr}; -const Int t_int64{64}; const Int t_int257{257}; const NatWidth t_natwidth_10{10}; const NatLeq t_natleq_4{4}; const RefT t_Ref_VmStackValue{t_VmStackValue}; const NatWidth t_natwidth_24{24}; const HashmapE t_HashmapE_4_VmStackValue{4, t_VmStackValue}; -const RefT t_Ref_TYPE_1705{t_VmGasLimits_aux}; +const RefT t_Ref_TYPE_1709{t_VmGasLimits_aux}; const HashmapE t_HashmapE_256_Ref_Cell{256, t_RefCell}; const UInt t_uint13{13}; const Maybe t_Maybe_uint13{t_uint13}; @@ -21250,6 +21687,7 @@ bool register_simple_types(std::function func) { && func("McStateExtra", &t_McStateExtra) && func("ShardStateUnsplit", &t_ShardStateUnsplit) && func("ShardState", &t_ShardState) + && func("GlobalVersion", &t_GlobalVersion) && func("BlockInfo", &t_BlockInfo) && func("ValueFlow", &t_ValueFlow) && func("BlockExtra", &t_BlockExtra) @@ -21278,7 +21716,10 @@ bool register_simple_types(std::function func) { && func("SignedCertificate", &t_SignedCertificate) && func("ValidatorDescr", &t_ValidatorDescr) && func("ValidatorSet", &t_ValidatorSet) - && func("GlobalVersion", &t_GlobalVersion) + && func("ConfigProposalSetup", &t_ConfigProposalSetup) + && func("ConfigVotingSetup", &t_ConfigVotingSetup) + && func("ConfigProposal", &t_ConfigProposal) + && func("ConfigProposalStatus", &t_ConfigProposalStatus) && func("WorkchainDescr", &t_WorkchainDescr) && func("BlockCreateFees", &t_BlockCreateFees) && func("StoragePrices", &t_StoragePrices) diff --git a/submodules/ton/tonlib-src/crypto/block/block-auto.h b/submodules/ton/tonlib-src/crypto/block/block-auto.h index ac0bf542b8..e9ed5d3947 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-auto.h +++ b/submodules/ton/tonlib-src/crypto/block/block-auto.h @@ -15,6 +15,7 @@ // uses built-in type `uint` // uses built-in type `bits` // uses built-in type `int8` +// uses built-in type `uint8` // uses built-in type `uint13` // uses built-in type `uint15` // uses built-in type `int16` @@ -24,6 +25,7 @@ // uses built-in type `uint63` // uses built-in type `int64` // uses built-in type `uint64` +// uses built-in type `uint256` // uses built-in type `int257` // uses built-in type `bits256` @@ -4533,11 +4535,12 @@ struct BlockInfo::Record { unsigned gen_catchain_seqno; // gen_catchain_seqno : uint32 unsigned min_ref_mc_seqno; // min_ref_mc_seqno : uint32 unsigned prev_key_block_seqno; // prev_key_block_seqno : uint32 + Ref gen_software; // gen_software : flags.0?GlobalVersion Ref master_ref; // master_ref : not_master?^BlkMasterInfo Ref prev_ref; // prev_ref : ^(BlkPrevInfo after_merge) Ref prev_vert_ref; // prev_vert_ref : vert_seqno_incr?^(BlkPrevInfo 0) Record() = default; - Record(unsigned _version, bool _not_master, bool _after_merge, bool _before_split, bool _after_split, bool _want_split, bool _want_merge, bool _key_block, bool _vert_seqno_incr, int _flags, int _seq_no, int _vert_seq_no, Ref _shard, unsigned _gen_utime, unsigned long long _start_lt, unsigned long long _end_lt, unsigned _gen_validator_list_hash_short, unsigned _gen_catchain_seqno, unsigned _min_ref_mc_seqno, unsigned _prev_key_block_seqno, Ref _master_ref, Ref _prev_ref, Ref _prev_vert_ref) : version(_version), not_master(_not_master), after_merge(_after_merge), before_split(_before_split), after_split(_after_split), want_split(_want_split), want_merge(_want_merge), key_block(_key_block), vert_seqno_incr(_vert_seqno_incr), flags(_flags), seq_no(_seq_no), vert_seq_no(_vert_seq_no), shard(std::move(_shard)), gen_utime(_gen_utime), start_lt(_start_lt), end_lt(_end_lt), gen_validator_list_hash_short(_gen_validator_list_hash_short), gen_catchain_seqno(_gen_catchain_seqno), min_ref_mc_seqno(_min_ref_mc_seqno), prev_key_block_seqno(_prev_key_block_seqno), master_ref(std::move(_master_ref)), prev_ref(std::move(_prev_ref)), prev_vert_ref(std::move(_prev_vert_ref)) {} + Record(unsigned _version, bool _not_master, bool _after_merge, bool _before_split, bool _after_split, bool _want_split, bool _want_merge, bool _key_block, bool _vert_seqno_incr, int _flags, int _seq_no, int _vert_seq_no, Ref _shard, unsigned _gen_utime, unsigned long long _start_lt, unsigned long long _end_lt, unsigned _gen_validator_list_hash_short, unsigned _gen_catchain_seqno, unsigned _min_ref_mc_seqno, unsigned _prev_key_block_seqno, Ref _gen_software, Ref _master_ref, Ref _prev_ref, Ref _prev_vert_ref) : version(_version), not_master(_not_master), after_merge(_after_merge), before_split(_before_split), after_split(_after_split), want_split(_want_split), want_merge(_want_merge), key_block(_key_block), vert_seqno_incr(_vert_seqno_incr), flags(_flags), seq_no(_seq_no), vert_seq_no(_vert_seq_no), shard(std::move(_shard)), gen_utime(_gen_utime), start_lt(_start_lt), end_lt(_end_lt), gen_validator_list_hash_short(_gen_validator_list_hash_short), gen_catchain_seqno(_gen_catchain_seqno), min_ref_mc_seqno(_min_ref_mc_seqno), prev_key_block_seqno(_prev_key_block_seqno), gen_software(std::move(_gen_software)), master_ref(std::move(_master_ref)), prev_ref(std::move(_prev_ref)), prev_vert_ref(std::move(_prev_vert_ref)) {} }; extern const BlockInfo t_BlockInfo; @@ -6085,6 +6088,176 @@ struct GlobalVersion final : TLB_Complex { extern const GlobalVersion t_GlobalVersion; +// +// headers for type `ConfigProposalSetup` +// + +struct ConfigProposalSetup final : TLB_Complex { + enum { cfg_vote_cfg }; + static constexpr int cons_len_exact = 8; + static constexpr unsigned char cons_tag[1] = { 0x36 }; + struct Record; + int get_size(const vm::CellSlice& cs) const override { + return 168; + } + bool skip(vm::CellSlice& cs) const override { + return cs.advance(168); + } + bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override; + bool unpack(vm::CellSlice& cs, Record& data) const; + bool cell_unpack(Ref cell_ref, Record& data) const; + bool pack(vm::CellBuilder& cb, const Record& data) const; + bool cell_pack(Ref& cell_ref, const Record& data) const; + bool print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "ConfigProposalSetup"; + } + int check_tag(const vm::CellSlice& cs) const override; + int get_tag(const vm::CellSlice& cs) const override { + return 0; + } +}; + +struct ConfigProposalSetup::Record { + typedef ConfigProposalSetup type_class; + int min_tot_rounds; // min_tot_rounds : uint8 + int max_tot_rounds; // max_tot_rounds : uint8 + int min_wins; // min_wins : uint8 + int max_losses; // max_losses : uint8 + unsigned min_store_sec; // min_store_sec : uint32 + unsigned max_store_sec; // max_store_sec : uint32 + unsigned bit_price; // bit_price : uint32 + unsigned cell_price; // cell_price : uint32 + Record() = default; + Record(int _min_tot_rounds, int _max_tot_rounds, int _min_wins, int _max_losses, unsigned _min_store_sec, unsigned _max_store_sec, unsigned _bit_price, unsigned _cell_price) : min_tot_rounds(_min_tot_rounds), max_tot_rounds(_max_tot_rounds), min_wins(_min_wins), max_losses(_max_losses), min_store_sec(_min_store_sec), max_store_sec(_max_store_sec), bit_price(_bit_price), cell_price(_cell_price) {} +}; + +extern const ConfigProposalSetup t_ConfigProposalSetup; + +// +// headers for type `ConfigVotingSetup` +// + +struct ConfigVotingSetup final : TLB_Complex { + enum { cfg_vote_setup }; + static constexpr int cons_len_exact = 8; + static constexpr unsigned char cons_tag[1] = { 0x91 }; + struct Record { + typedef ConfigVotingSetup type_class; + Ref normal_params; // normal_params : ^ConfigProposalSetup + Ref critical_params; // critical_params : ^ConfigProposalSetup + Record() = default; + Record(Ref _normal_params, Ref _critical_params) : normal_params(std::move(_normal_params)), critical_params(std::move(_critical_params)) {} + }; + int get_size(const vm::CellSlice& cs) const override { + return 0x20008; + } + bool skip(vm::CellSlice& cs) const override { + return cs.advance_ext(0x20008); + } + bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override; + bool unpack(vm::CellSlice& cs, Record& data) const; + bool unpack_cfg_vote_setup(vm::CellSlice& cs, Ref& normal_params, Ref& critical_params) const; + bool cell_unpack(Ref cell_ref, Record& data) const; + bool cell_unpack_cfg_vote_setup(Ref cell_ref, Ref& normal_params, Ref& critical_params) const; + bool pack(vm::CellBuilder& cb, const Record& data) const; + bool pack_cfg_vote_setup(vm::CellBuilder& cb, Ref normal_params, Ref critical_params) const; + bool cell_pack(Ref& cell_ref, const Record& data) const; + bool cell_pack_cfg_vote_setup(Ref& cell_ref, Ref normal_params, Ref critical_params) const; + bool print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "ConfigVotingSetup"; + } + int check_tag(const vm::CellSlice& cs) const override; + int get_tag(const vm::CellSlice& cs) const override { + return 0; + } +}; + +extern const ConfigVotingSetup t_ConfigVotingSetup; + +// +// headers for type `ConfigProposal` +// + +struct ConfigProposal final : TLB_Complex { + enum { cfg_proposal }; + static constexpr int cons_len_exact = 8; + static constexpr unsigned char cons_tag[1] = { 0xf3 }; + struct Record; + bool skip(vm::CellSlice& cs) const override; + bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override; + bool unpack(vm::CellSlice& cs, Record& data) const; + bool unpack_cfg_proposal(vm::CellSlice& cs, int& param_id, Ref& param_value, Ref& if_hash_equal) const; + bool cell_unpack(Ref cell_ref, Record& data) const; + bool cell_unpack_cfg_proposal(Ref cell_ref, int& param_id, Ref& param_value, Ref& if_hash_equal) const; + bool pack(vm::CellBuilder& cb, const Record& data) const; + bool pack_cfg_proposal(vm::CellBuilder& cb, int param_id, Ref param_value, Ref if_hash_equal) const; + bool cell_pack(Ref& cell_ref, const Record& data) const; + bool cell_pack_cfg_proposal(Ref& cell_ref, int param_id, Ref param_value, Ref if_hash_equal) const; + bool print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "ConfigProposal"; + } + int check_tag(const vm::CellSlice& cs) const override; + int get_tag(const vm::CellSlice& cs) const override { + return 0; + } +}; + +struct ConfigProposal::Record { + typedef ConfigProposal type_class; + int param_id; // param_id : int32 + Ref param_value; // param_value : Maybe ^Cell + Ref if_hash_equal; // if_hash_equal : Maybe uint256 + Record() = default; + Record(int _param_id, Ref _param_value, Ref _if_hash_equal) : param_id(_param_id), param_value(std::move(_param_value)), if_hash_equal(std::move(_if_hash_equal)) {} +}; + +extern const ConfigProposal t_ConfigProposal; + +// +// headers for type `ConfigProposalStatus` +// + +struct ConfigProposalStatus final : TLB_Complex { + enum { cfg_proposal_status }; + static constexpr int cons_len_exact = 8; + static constexpr unsigned char cons_tag[1] = { 0xce }; + struct Record; + bool skip(vm::CellSlice& cs) const override; + bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override; + bool unpack(vm::CellSlice& cs, Record& data) const; + bool cell_unpack(Ref cell_ref, Record& data) const; + bool pack(vm::CellBuilder& cb, const Record& data) const; + bool cell_pack(Ref& cell_ref, const Record& data) const; + bool print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "ConfigProposalStatus"; + } + int check_tag(const vm::CellSlice& cs) const override; + int get_tag(const vm::CellSlice& cs) const override { + return 0; + } +}; + +struct ConfigProposalStatus::Record { + typedef ConfigProposalStatus type_class; + unsigned expires; // expires : uint32 + Ref proposal; // proposal : ^ConfigProposal + bool is_critical; // is_critical : Bool + Ref voters; // voters : HashmapE 16 True + long long remaining_weight; // remaining_weight : int64 + RefInt256 validator_set_id; // validator_set_id : uint256 + int rounds_remaining; // rounds_remaining : uint8 + int wins; // wins : uint8 + int losses; // losses : uint8 + Record() = default; + Record(unsigned _expires, Ref _proposal, bool _is_critical, Ref _voters, long long _remaining_weight, RefInt256 _validator_set_id, int _rounds_remaining, int _wins, int _losses) : expires(_expires), proposal(std::move(_proposal)), is_critical(_is_critical), voters(std::move(_voters)), remaining_weight(_remaining_weight), validator_set_id(std::move(_validator_set_id)), rounds_remaining(_rounds_remaining), wins(_wins), losses(_losses) {} +}; + +extern const ConfigProposalStatus t_ConfigProposalStatus; + // // headers for type `WorkchainFormat` // @@ -6640,7 +6813,7 @@ extern const ValidatorSignedTempKey t_ValidatorSignedTempKey; // struct ConfigParam final : TLB_Complex { - enum { cons32, cons33, cons34, cons35, cons36, cons37, config_mc_block_limits, config_block_limits, cons14, cons0, cons1, cons2, cons3, cons4, cons6, cons7, cons9, cons12, cons15, cons16, cons17, cons18, cons31, cons39, cons28, cons8, config_mc_gas_prices, config_gas_prices, cons29, config_mc_fwd_prices, config_fwd_prices }; + enum { cons32, cons33, cons34, cons35, cons36, cons37, config_mc_block_limits, config_block_limits, cons14, cons0, cons1, cons2, cons3, cons4, cons6, cons7, cons9, cons10, cons12, cons15, cons16, cons17, cons18, cons31, cons39, cons11, cons28, cons8, config_mc_gas_prices, config_gas_prices, cons29, config_mc_fwd_prices, config_fwd_prices }; static constexpr int cons_len_exact = 0; int m_; ConfigParam(int m) : m_(m) {} @@ -6699,6 +6872,18 @@ struct ConfigParam final : TLB_Complex { Record_cons9() = default; Record_cons9(Ref _mandatory_params) : mandatory_params(std::move(_mandatory_params)) {} }; + struct Record_cons10 { + typedef ConfigParam type_class; + Ref critical_params; // critical_params : Hashmap 32 True + Record_cons10() = default; + Record_cons10(Ref _critical_params) : critical_params(std::move(_critical_params)) {} + }; + struct Record_cons11 { + typedef ConfigParam type_class; + Ref x; // ConfigVotingSetup + Record_cons11() = default; + Record_cons11(Ref _x) : x(std::move(_x)) {} + }; struct Record_cons12 { typedef ConfigParam type_class; Ref workchains; // workchains : HashmapE 32 WorkchainDescr @@ -6890,6 +7075,22 @@ struct ConfigParam final : TLB_Complex { bool pack_cons9(vm::CellBuilder& cb, Ref mandatory_params) const; bool cell_pack(Ref& cell_ref, const Record_cons9& data) const; bool cell_pack_cons9(Ref& cell_ref, Ref mandatory_params) const; + bool unpack(vm::CellSlice& cs, Record_cons10& data) const; + bool unpack_cons10(vm::CellSlice& cs, Ref& critical_params) const; + bool cell_unpack(Ref cell_ref, Record_cons10& data) const; + bool cell_unpack_cons10(Ref cell_ref, Ref& critical_params) const; + bool pack(vm::CellBuilder& cb, const Record_cons10& data) const; + bool pack_cons10(vm::CellBuilder& cb, Ref critical_params) const; + bool cell_pack(Ref& cell_ref, const Record_cons10& data) const; + bool cell_pack_cons10(Ref& cell_ref, Ref critical_params) const; + bool unpack(vm::CellSlice& cs, Record_cons11& data) const; + bool unpack_cons11(vm::CellSlice& cs, Ref& x) const; + bool cell_unpack(Ref cell_ref, Record_cons11& data) const; + bool cell_unpack_cons11(Ref cell_ref, Ref& x) const; + bool pack(vm::CellBuilder& cb, const Record_cons11& data) const; + bool pack_cons11(vm::CellBuilder& cb, Ref x) const; + bool cell_pack(Ref& cell_ref, const Record_cons11& data) const; + bool cell_pack_cons11(Ref& cell_ref, Ref x) const; bool unpack(vm::CellSlice& cs, Record_cons12& data) const; bool unpack_cons12(vm::CellSlice& cs, Ref& workchains) const; bool cell_unpack(Ref cell_ref, Record_cons12& data) const; @@ -8689,9 +8890,9 @@ extern const RefT t_Ref_McBlockExtra; // Maybe ^McBlockExtra extern const Maybe t_Maybe_Ref_McBlockExtra; // ^[$_ from_prev_blk:CurrencyCollection to_next_blk:CurrencyCollection imported:CurrencyCollection exported:CurrencyCollection ] -extern const RefT t_Ref_TYPE_1648; -// ^[$_ fees_imported:CurrencyCollection recovered:CurrencyCollection created:CurrencyCollection minted:CurrencyCollection ] extern const RefT t_Ref_TYPE_1649; +// ^[$_ fees_imported:CurrencyCollection recovered:CurrencyCollection created:CurrencyCollection minted:CurrencyCollection ] +extern const RefT t_Ref_TYPE_1650; // ## 3 extern const NatWidth t_natwidth_3; // BinTree ShardDescr @@ -8717,7 +8918,7 @@ extern const NatWidth t_natwidth_16; // Maybe ExtBlkRef extern const Maybe t_Maybe_ExtBlkRef; // ^[$_ flags:(## 16) {<= flags 1} validator_info:ValidatorInfo prev_blocks:OldMcBlocksInfo after_key_block:Bool last_key_block:(Maybe ExtBlkRef) block_create_stats:flags.0?BlockCreateStats ] -extern const RefT t_Ref_TYPE_1666; +extern const RefT t_Ref_TYPE_1667; // ^SignedCertificate extern const RefT t_Ref_SignedCertificate; // HashmapE 16 CryptoSignaturePair @@ -8725,13 +8926,27 @@ extern const HashmapE t_HashmapE_16_CryptoSignaturePair; // Maybe ^InMsg extern const Maybe t_Maybe_Ref_InMsg; // ^[$_ prev_blk_signatures:(HashmapE 16 CryptoSignaturePair) recover_create_msg:(Maybe ^InMsg) mint_msg:(Maybe ^InMsg) ] -extern const RefT t_Ref_TYPE_1674; +extern const RefT t_Ref_TYPE_1675; // Hashmap 16 ValidatorDescr extern const Hashmap t_Hashmap_16_ValidatorDescr; // HashmapE 16 ValidatorDescr extern const HashmapE t_HashmapE_16_ValidatorDescr; // Hashmap 32 True extern const Hashmap t_Hashmap_32_True; +// uint8 +extern const UInt t_uint8; +// ^ConfigProposalSetup +extern const RefT t_Ref_ConfigProposalSetup; +// uint256 +extern const UInt t_uint256; +// Maybe uint256 +extern const Maybe t_Maybe_uint256; +// ^ConfigProposal +extern const RefT t_Ref_ConfigProposal; +// HashmapE 16 True +extern const HashmapE t_HashmapE_16_True; +// int64 +extern const Int t_int64; // ## 12 extern const NatWidth t_natwidth_12; // ## 32 @@ -8756,8 +8971,6 @@ extern const Maybe t_Maybe_Ref_BlockSignatures; extern const RefT t_Ref_TopBlockDescr; // HashmapE 96 ^TopBlockDescr extern const HashmapE t_HashmapE_96_Ref_TopBlockDescr; -// int64 -extern const Int t_int64; // int257 extern const Int t_int257; // ## 10 @@ -8771,7 +8984,7 @@ extern const NatWidth t_natwidth_24; // HashmapE 4 VmStackValue extern const HashmapE t_HashmapE_4_VmStackValue; // ^[$_ max_limit:int64 cur_limit:int64 credit:int64 ] -extern const RefT t_Ref_TYPE_1705; +extern const RefT t_Ref_TYPE_1709; // HashmapE 256 ^Cell extern const HashmapE t_HashmapE_256_Ref_Cell; // uint13 diff --git a/submodules/ton/tonlib-src/crypto/block/block-parse.cpp b/submodules/ton/tonlib-src/crypto/block/block-parse.cpp index a032236608..22ac1b18cb 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-parse.cpp +++ b/submodules/ton/tonlib-src/crypto/block/block-parse.cpp @@ -344,11 +344,11 @@ unsigned long long VarUIntegerPos::as_uint(const vm::CellSlice& cs) const { bool VarUIntegerPos::store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const { int k = value.bit_size(false); - return k <= (n - 1) * 8 && value.sgn() > 0 && cb.store_long_bool((k + 7) >> 3, ln) && + return k <= (n - 1) * 8 && value.sgn() >= (int)store_pos_only && cb.store_long_bool((k + 7) >> 3, ln) && cb.store_int256_bool(value, (k + 7) & -8, false); } -const VarUIntegerPos t_VarUIntegerPos_16{16}, t_VarUIntegerPos_32{32}; +const VarUIntegerPos t_VarUIntegerPos_16{16}, t_VarUIntegerPos_32{32}, t_VarUIntegerPosRelaxed_32{32, true}; static inline bool redundant_int(const vm::CellSlice& cs) { int t = (int)cs.prefetch_long(9); @@ -500,8 +500,8 @@ bool HashmapE::add_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice int n = root_type.n; vm::Dictionary dict1{vm::DictAdvance(), cs1, n}, dict2{vm::DictAdvance(), cs2, n}; const TLB& vt = root_type.value_type; - vm::Dictionary::simple_combine_func_t combine = [vt](vm::CellBuilder& cb, Ref cs1_ref, - Ref cs2_ref) -> bool { + vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref cs1_ref, + Ref cs2_ref) -> bool { if (!vt.add_values(cb, cs1_ref.write(), cs2_ref.write())) { throw CombineError{}; } @@ -514,8 +514,8 @@ bool HashmapE::add_values_ref(Ref& res, Ref arg1, Ref cs1_ref, - Ref cs2_ref) -> bool { + vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref cs1_ref, + Ref cs2_ref) -> bool { if (!vt.add_values(cb, cs1_ref.write(), cs2_ref.write())) { throw CombineError{}; } @@ -535,8 +535,8 @@ int HashmapE::sub_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice& int n = root_type.n; vm::Dictionary dict1{vm::DictAdvance(), cs1, n}, dict2{vm::DictAdvance(), cs2, n}; const TLB& vt = root_type.value_type; - vm::Dictionary::simple_combine_func_t combine = [vt](vm::CellBuilder& cb, Ref cs1_ref, - Ref cs2_ref) -> bool { + vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref cs1_ref, + Ref cs2_ref) -> bool { int r = vt.sub_values(cb, cs1_ref.write(), cs2_ref.write()); if (r < 0) { throw CombineError{}; @@ -555,8 +555,8 @@ int HashmapE::sub_values_ref(Ref& res, Ref arg1, Ref cs1_ref, - Ref cs2_ref) -> bool { + vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref cs1_ref, + Ref cs2_ref) -> bool { int r = vt.sub_values(cb, cs1_ref.write(), cs2_ref.write()); if (r < 0) { throw CombineError{}; diff --git a/submodules/ton/tonlib-src/crypto/block/block-parse.h b/submodules/ton/tonlib-src/crypto/block/block-parse.h index 9590631132..e1578df0c0 100644 --- a/submodules/ton/tonlib-src/crypto/block/block-parse.h +++ b/submodules/ton/tonlib-src/crypto/block/block-parse.h @@ -68,13 +68,17 @@ struct VarUInteger final : TLB_Complex { bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override; unsigned precompute_integer_size(const td::BigInt256& value) const; unsigned precompute_integer_size(td::RefInt256 value) const; + std::ostream& print_type(std::ostream& os) const override { + return os << "(VarUInteger " << n << ")"; + } }; extern const VarUInteger t_VarUInteger_3, t_VarUInteger_7, t_VarUInteger_16, t_VarUInteger_32; struct VarUIntegerPos final : TLB_Complex { int n, ln; - VarUIntegerPos(int _n) : n(_n) { + bool store_pos_only; + VarUIntegerPos(int _n, bool relaxed = false) : n(_n), store_pos_only(!relaxed) { ln = 32 - td::count_leading_zeroes32(n - 1); } bool skip(vm::CellSlice& cs) const override; @@ -82,9 +86,12 @@ struct VarUIntegerPos final : TLB_Complex { td::RefInt256 as_integer_skip(vm::CellSlice& cs) const override; unsigned long long as_uint(const vm::CellSlice& cs) const override; bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "(VarUIntegerPos " << n << ")"; + } }; -extern const VarUIntegerPos t_VarUIntegerPos_16, t_VarUIntegerPos_32; +extern const VarUIntegerPos t_VarUIntegerPos_16, t_VarUIntegerPos_32, t_VarUIntegerPosRelaxed_32; struct VarInteger final : TLB_Complex { int n, ln; @@ -99,6 +106,9 @@ struct VarInteger final : TLB_Complex { return cb.store_zeroes_bool(ln); } bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "(VarInteger " << n << ")"; + } }; struct VarIntegerNz final : TLB_Complex { @@ -111,6 +121,9 @@ struct VarIntegerNz final : TLB_Complex { td::RefInt256 as_integer_skip(vm::CellSlice& cs) const override; long long as_int(const vm::CellSlice& cs) const override; bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override; + std::ostream& print_type(std::ostream& os) const override { + return os << "(VarIntegerNz " << n << ")"; + } }; struct Unary final : TLB { @@ -312,8 +325,8 @@ struct MsgAddress final : TLB_Complex { extern const MsgAddress t_MsgAddress; struct ExtraCurrencyCollection final : TLB { - HashmapE dict_type; - ExtraCurrencyCollection() : dict_type(32, t_VarUIntegerPos_32) { + HashmapE dict_type, dict_type2; + ExtraCurrencyCollection() : dict_type(32, t_VarUIntegerPos_32), dict_type2(32, t_VarUIntegerPosRelaxed_32) { } int get_size(const vm::CellSlice& cs) const override { return dict_type.get_size(cs); @@ -328,13 +341,13 @@ struct ExtraCurrencyCollection final : TLB { return dict_type.add_values(cb, cs1, cs2); } int sub_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice& cs2) const override { - return dict_type.sub_values(cb, cs1, cs2); + return dict_type2.sub_values(cb, cs1, cs2); } bool add_values_ref(Ref& res, Ref arg1, Ref arg2) const { return dict_type.add_values_ref(res, std::move(arg1), std::move(arg2)); } int sub_values_ref(Ref& res, Ref arg1, Ref arg2) const { - return dict_type.sub_values_ref(res, std::move(arg1), std::move(arg2)); + return dict_type2.sub_values_ref(res, std::move(arg1), std::move(arg2)); } bool store_ref(vm::CellBuilder& cb, Ref arg) const { return dict_type.store_ref(cb, std::move(arg)); diff --git a/submodules/ton/tonlib-src/crypto/block/block.cpp b/submodules/ton/tonlib-src/crypto/block/block.cpp index d9d3c26726..b160de6fbc 100644 --- a/submodules/ton/tonlib-src/crypto/block/block.cpp +++ b/submodules/ton/tonlib-src/crypto/block/block.cpp @@ -20,6 +20,7 @@ #include "block/block.h" #include "block/block-auto.h" #include "block/block-parse.h" +#include "block/mc-config.h" #include "ton/ton-shard.h" #include "common/bigexp.h" #include "common/util.h" @@ -1602,33 +1603,50 @@ bool check_one_config_param(Ref cs_ref, td::ConstBitPtr key, td:: const int mandatory_config_params[] = {18, 20, 21, 22, 23, 24, 25, 28, 34}; -bool valid_config_data(Ref cell, const td::BitArray<256>& addr, bool catch_errors, bool relax_par0) { +bool valid_config_data(Ref cell, const td::BitArray<256>& addr, bool catch_errors, bool relax_par0, + Ref old_mparams) { using namespace std::placeholders; if (cell.is_null()) { return false; } - if (!catch_errors) { - vm::Dictionary dict{std::move(cell), 32}; - for (int x : mandatory_config_params) { - if (!dict.int_key_exists(x)) { - LOG(ERROR) << "mandatory configuration parameter #" << x << " is missing"; - return false; - } + if (catch_errors) { + try { + return valid_config_data(std::move(cell), addr, false, relax_par0, std::move(old_mparams)); + } catch (vm::VmError&) { + return false; } - return dict.check_for_each(std::bind(check_one_config_param, _1, _2, addr.cbits(), relax_par0)); } - try { - vm::Dictionary dict{std::move(cell), 32}; - for (int x : mandatory_config_params) { - if (!dict.int_key_exists(x)) { - LOG(ERROR) << "mandatory configuration parameter #" << x << " is missing"; - return false; - } - } - return dict.check_for_each(std::bind(check_one_config_param, _1, _2, addr.cbits(), relax_par0)); - } catch (vm::VmError&) { + vm::Dictionary dict{std::move(cell), 32}; + if (!dict.check_for_each(std::bind(check_one_config_param, _1, _2, addr.cbits(), relax_par0))) { return false; } + for (int x : mandatory_config_params) { + if (!dict.int_key_exists(x)) { + LOG(ERROR) << "mandatory configuration parameter #" << x << " is missing"; + return false; + } + } + return config_params_present(dict, dict.lookup_ref(td::BitArray<32>{9})) && + config_params_present(dict, std::move(old_mparams)); +} + +bool config_params_present(vm::Dictionary& dict, Ref param_dict_root) { + auto res = block::Config::unpack_param_dict(std::move(param_dict_root)); + if (res.is_error()) { + LOG(ERROR) + << "invalid mandatory parameters dictionary while checking existence of all mandatory configuration parameters"; + return false; + } + for (int x : res.move_as_ok()) { + // LOG(DEBUG) << "checking whether mandatory configuration parameter #" << x << " exists"; + if (!dict.int_key_exists(x)) { + LOG(ERROR) << "configuration parameter #" << x + << " (declared as mandatory in configuration parameter #9) is missing"; + return false; + } + } + // LOG(DEBUG) << "all mandatory configuration parameters present"; + return true; } bool add_extra_currency(Ref extra1, Ref extra2, Ref& res) { @@ -1651,7 +1669,7 @@ bool sub_extra_currency(Ref extra1, Ref extra2, Ref= 0; } } diff --git a/submodules/ton/tonlib-src/crypto/block/block.h b/submodules/ton/tonlib-src/crypto/block/block.h index 0d961320bd..8b93caf761 100644 --- a/submodules/ton/tonlib-src/crypto/block/block.h +++ b/submodules/ton/tonlib-src/crypto/block/block.h @@ -606,7 +606,8 @@ bool unpack_CurrencyCollection(Ref csr, td::RefInt256& value, Ref bool valid_library_collection(Ref cell, bool catch_errors = true); bool valid_config_data(Ref cell, const td::BitArray<256>& addr, bool catch_errors = true, - bool relax_par0 = false); + bool relax_par0 = false, Ref old_mparams = {}); +bool config_params_present(vm::Dictionary& dict, Ref param_dict_root); bool add_extra_currency(Ref extra1, Ref extra2, Ref& res); bool sub_extra_currency(Ref extra1, Ref extra2, Ref& res); diff --git a/submodules/ton/tonlib-src/crypto/block/block.tlb b/submodules/ton/tonlib-src/crypto/block/block.tlb index a30cd89a87..e9af709bec 100644 --- a/submodules/ton/tonlib-src/crypto/block/block.tlb +++ b/submodules/ton/tonlib-src/crypto/block/block.tlb @@ -414,7 +414,7 @@ block_info#9bc7a987 version:uint32 after_split:(## 1) want_split:Bool want_merge:Bool key_block:Bool vert_seqno_incr:(## 1) - flags:(## 8) + flags:(## 8) { flags <= 1 } seq_no:# vert_seq_no:# { vert_seq_no >= vert_seqno_incr } { prev_seq_no:# } { ~prev_seq_no + 1 = seq_no } shard:ShardIdent gen_utime:uint32 @@ -423,6 +423,7 @@ block_info#9bc7a987 version:uint32 gen_catchain_seqno:uint32 min_ref_mc_seqno:uint32 prev_key_block_seqno:uint32 + gen_software:flags . 0?GlobalVersion master_ref:not_master?^BlkMasterInfo prev_ref:^(BlkPrevInfo after_merge) prev_vert_ref:vert_seqno_incr?^(BlkPrevInfo 0) @@ -572,6 +573,17 @@ _ to_mint:ExtraCurrencyCollection = ConfigParam 7; capabilities#c4 version:uint32 capabilities:uint64 = GlobalVersion; _ GlobalVersion = ConfigParam 8; // all zero if absent _ mandatory_params:(Hashmap 32 True) = ConfigParam 9; +_ critical_params:(Hashmap 32 True) = ConfigParam 10; + +cfg_vote_cfg#36 min_tot_rounds:uint8 max_tot_rounds:uint8 min_wins:uint8 max_losses:uint8 min_store_sec:uint32 max_store_sec:uint32 bit_price:uint32 cell_price:uint32 = ConfigProposalSetup; +cfg_vote_setup#91 normal_params:^ConfigProposalSetup critical_params:^ConfigProposalSetup = ConfigVotingSetup; +_ ConfigVotingSetup = ConfigParam 11; + +cfg_proposal#f3 param_id:int32 param_value:(Maybe ^Cell) if_hash_equal:(Maybe uint256) + = ConfigProposal; +cfg_proposal_status#ce expires:uint32 proposal:^ConfigProposal is_critical:Bool + voters:(HashmapE 16 True) remaining_weight:int64 validator_set_id:uint256 + rounds_remaining:uint8 wins:uint8 losses:uint8 = ConfigProposalStatus; wfmt_basic#1 vm_version:int32 vm_mode:uint64 = WorkchainFormat 1; wfmt_ext#0 min_addr_len:(## 12) max_addr_len:(## 12) addr_len_step:(## 12) diff --git a/submodules/ton/tonlib-src/crypto/block/create-state.cpp b/submodules/ton/tonlib-src/crypto/block/create-state.cpp index 5eb14528c9..e850603f34 100644 --- a/submodules/ton/tonlib-src/crypto/block/create-state.cpp +++ b/submodules/ton/tonlib-src/crypto/block/create-state.cpp @@ -55,6 +55,8 @@ #include "td/utils/port/path.h" #include "td/utils/port/signals.h" +#include "tonlib/keys/Mnemonic.h" + #include "block.h" #include "block-parse.h" #include "block-auto.h" @@ -616,7 +618,43 @@ void interpret_is_workchain_descr(vm::Stack& stack) { stack.push_bool(block::gen::t_WorkchainDescr.validate_ref(std::move(cell))); } +void interpret_add_extra_currencies(vm::Stack& stack) { + Ref y = stack.pop_maybe_cell(), x = stack.pop_maybe_cell(), res; + bool ok = block::add_extra_currency(std::move(x), std::move(y), res); + if (ok) { + stack.push_maybe_cell(std::move(res)); + } + stack.push_bool(ok); +} + +void interpret_sub_extra_currencies(vm::Stack& stack) { + Ref y = stack.pop_maybe_cell(), x = stack.pop_maybe_cell(), res; + bool ok = block::sub_extra_currency(std::move(x), std::move(y), res); + if (ok) { + stack.push_maybe_cell(std::move(res)); + } + stack.push_bool(ok); +} + +void interpret_mnemonic_to_privkey(vm::Stack& stack, int mode) { + td::SecureString str{td::Slice{stack.pop_string()}}; + auto res = tonlib::Mnemonic::create(std::move(str), td::SecureString()); + if (res.is_error()) { + throw fift::IntError{res.move_as_error().to_string()}; + } + auto privkey = res.move_as_ok().to_private_key(); + td::SecureString key; + if (mode & 1) { + auto pub = privkey.get_public_key(); + key = pub.move_as_ok().as_octet_string(); + } else { + key = privkey.as_octet_string(); + } + stack.push_bytes(key.as_slice()); +} + void init_words_custom(fift::Dictionary& d) { + using namespace std::placeholders; d.def_stack_word("verb@ ", interpret_get_verbosity); d.def_stack_word("verb! ", interpret_set_verbosity); d.def_stack_word("wcid@ ", interpret_get_workchain); @@ -631,6 +669,10 @@ void init_words_custom(fift::Dictionary& d) { d.def_stack_word("create_state ", interpret_create_state); d.def_stack_word("isShardState? ", interpret_is_shard_state); d.def_stack_word("isWorkchainDescr? ", interpret_is_workchain_descr); + d.def_stack_word("CC+? ", interpret_add_extra_currencies); + d.def_stack_word("CC-? ", interpret_sub_extra_currencies); + d.def_stack_word("mnemo>priv ", std::bind(interpret_mnemonic_to_privkey, _1, 0)); + d.def_stack_word("mnemo>pub ", std::bind(interpret_mnemonic_to_privkey, _1, 1)); } tlb::TypenameLookup tlb_dict; @@ -704,7 +746,12 @@ void interpret_tlb_validate_skip(vm::Stack& stack) { stack.push_bool(ok); } +void interpret_tlb_type_const(vm::Stack& stack, const tlb::TLB* ptr) { + stack.push_make_object(ptr); +} + void init_words_tlb(fift::Dictionary& d) { + using namespace std::placeholders; tlb_dict.register_types(block::gen::register_simple_types); d.def_stack_word("tlb-type-lookup ", interpret_tlb_type_lookup); d.def_stack_word("tlb-type-name ", interpret_tlb_type_name); @@ -713,6 +760,8 @@ void init_words_tlb(fift::Dictionary& d) { d.def_stack_word("(tlb-dump-str?) ", interpret_tlb_dump_to_str); d.def_stack_word("tlb-skip ", interpret_tlb_skip); d.def_stack_word("tlb-validate-skip ", interpret_tlb_validate_skip); + d.def_stack_word("ExtraCurrencyCollection", + std::bind(interpret_tlb_type_const, _1, &block::tlb::t_ExtraCurrencyCollection)); } void usage(const char* progname) { diff --git a/submodules/ton/tonlib-src/crypto/block/mc-config.cpp b/submodules/ton/tonlib-src/crypto/block/mc-config.cpp index 555b26033e..d2774797c0 100644 --- a/submodules/ton/tonlib-src/crypto/block/mc-config.cpp +++ b/submodules/ton/tonlib-src/crypto/block/mc-config.cpp @@ -40,6 +40,7 @@ #include namespace block { +using namespace std::literals::string_literals; using td::Ref; Config::Config(Ref config_root, const td::Bits256& config_addr, int _mode) @@ -335,6 +336,59 @@ std::unique_ptr ShardConfig::extract_shard_hashes_dict(Ref> Config::unpack_param_dict(vm::Dictionary& dict) { + try { + std::vector vect; + if (dict.check_for_each( + [&vect](Ref value, td::ConstBitPtr key, int key_len) { + bool ok = (key_len == 32 && value->empty_ext()); + if (ok) { + vect.push_back((int)key.get_int(32)); + } + return ok; + }, + true)) { + return std::move(vect); + } else { + return td::Status::Error("invalid parameter list dictionary"); + } + } catch (vm::VmError& vme) { + return td::Status::Error("error unpacking parameter list dictionary: "s + vme.get_msg()); + } +} + +td::Result> Config::unpack_param_dict(Ref dict_root) { + vm::Dictionary dict{std::move(dict_root), 32}; + return unpack_param_dict(dict); +} + +std::unique_ptr Config::get_param_dict(int idx) const { + return std::make_unique(get_config_param(idx), 32); +} + +td::Result> Config::unpack_param_list(int idx) const { + return unpack_param_dict(*get_param_dict(idx)); +} + +bool Config::all_mandatory_params_defined(int* bad_idx_ptr) const { + auto res = get_mandatory_param_list(); + if (res.is_error()) { + if (bad_idx_ptr) { + *bad_idx_ptr = -1; + } + return false; + } + for (int x : res.move_as_ok()) { + if (get_config_param(x).is_null()) { + if (bad_idx_ptr) { + *bad_idx_ptr = x; + } + return false; + } + } + return true; +} + std::unique_ptr ConfigInfo::create_accounts_dict() const { if (mode & needAccountsRoot) { return std::make_unique(accounts_root, 256, block::tlb::aug_ShardAccounts); diff --git a/submodules/ton/tonlib-src/crypto/block/mc-config.h b/submodules/ton/tonlib-src/crypto/block/mc-config.h index 8541110ffe..467b7c8a39 100644 --- a/submodules/ton/tonlib-src/crypto/block/mc-config.h +++ b/submodules/ton/tonlib-src/crypto/block/mc-config.h @@ -534,6 +534,21 @@ class Config { bool create_stats_enabled() const { return has_capability(ton::capCreateStatsEnabled); } + std::unique_ptr get_param_dict(int idx) const; + td::Result> unpack_param_list(int idx) const; + std::unique_ptr get_mandatory_param_dict() const { + return get_param_dict(9); + } + std::unique_ptr get_critical_param_dict() const { + return get_param_dict(10); + } + td::Result> get_mandatory_param_list() const { + return unpack_param_list(9); + } + td::Result> get_critical_param_list() const { + return unpack_param_list(10); + } + bool all_mandatory_params_defined(int* bad_idx_ptr = nullptr) const; td::Result get_dns_root_addr() const; bool set_block_id_ext(const ton::BlockIdExt& block_id_ext); td::Result> get_special_smartcontracts(bool without_config = false) const; @@ -580,6 +595,8 @@ class Config { static td::Result> extract_from_state(Ref mc_state_root, int mode = 0); static td::Result> extract_from_key_block(Ref key_block_root, int mode = 0); static td::Result> unpack_validator_set_start_stop(Ref root); + static td::Result> unpack_param_dict(vm::Dictionary& dict); + static td::Result> unpack_param_dict(Ref dict_root); protected: Config(int _mode) : mode(_mode) { diff --git a/submodules/ton/tonlib-src/crypto/block/transaction.cpp b/submodules/ton/tonlib-src/crypto/block/transaction.cpp index 34abfff13d..e04badb550 100644 --- a/submodules/ton/tonlib-src/crypto/block/transaction.cpp +++ b/submodules/ton/tonlib-src/crypto/block/transaction.cpp @@ -1555,9 +1555,17 @@ int Transaction::try_action_send_msg(const vm::CellSlice& cs0, ActionPhase& ap, Ref new_extra; if (!block::sub_extra_currency(ap.remaining_balance.extra, req.extra, new_extra)) { - LOG(DEBUG) << "not enough extra currency to send with the message"; + LOG(DEBUG) << "not enough extra currency to send with the message: " + << block::CurrencyCollection{0, req.extra}.to_str() << " required, only " + << block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str() << " available"; return skip_invalid ? 0 : 38; // not enough (extra) funds } + if (ap.remaining_balance.extra.not_null() || req.extra.not_null()) { + LOG(DEBUG) << "subtracting extra currencies: " + << block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str() << " minus " + << block::CurrencyCollection{0, req.extra}.to_str() << " equals " + << block::CurrencyCollection{0, new_extra}.to_str(); + } auto fwd_fee_mine = msg_prices.get_first_part(fwd_fee); auto fwd_fee_remain = fwd_fee - fwd_fee_mine; @@ -1691,7 +1699,9 @@ int Transaction::try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap, } } if (!block::sub_extra_currency(ap.remaining_balance.extra, reserve.extra, newc.extra)) { - LOG(DEBUG) << "not enough extra currency to reserve"; + LOG(DEBUG) << "not enough extra currency to reserve: " << block::CurrencyCollection{0, reserve.extra}.to_str() + << " required, only " << block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str() + << " available"; if (mode & 2) { // TODO: process (mode & 2) correctly by setting res_extra := inf (reserve.extra, ap.remaining_balance.extra) } @@ -1720,11 +1730,17 @@ bool Transaction::prepare_bounce_phase(const ActionPhaseConfig& cfg) { } bounce_phase = std::make_unique(); BouncePhase& bp = *bounce_phase; + block::gen::Message::Record msg; block::gen::CommonMsgInfo::Record_int_msg_info info; - if (!tlb::unpack_cell_inexact(in_msg, info)) { + auto cs = vm::load_cell_slice(in_msg); + if (!(tlb::unpack(cs, info) && gen::t_Maybe_Either_StateInit_Ref_StateInit.skip(cs) && cs.have(1) && + cs.have_refs((int)cs.prefetch_ulong(1)))) { bounce_phase.reset(); return false; } + if (cs.fetch_ulong(1)) { + cs = vm::load_cell_slice(cs.prefetch_ref()); + } info.ihr_disabled = true; info.bounce = false; info.bounced = true; @@ -1776,10 +1792,26 @@ bool Transaction::prepare_bounce_phase(const ActionPhaseConfig& cfg) { && block::tlb::t_Grams.store_long(cb, bp.fwd_fees) // fwd_fee:Grams && cb.store_long_bool(info.created_lt, 64) // created_lt:uint64 && cb.store_long_bool(info.created_at, 32) // created_at:uint32 - && cb.store_long_bool(0, 2) // init:(Maybe ...) state:(Either ..) - && cb.finalize_to(bp.out_msg)); + && cb.store_bool_bool(false)); // init:(Maybe ...) + if (cfg.bounce_msg_body) { + int body_bits = std::min((int)cs.size(), cfg.bounce_msg_body); + if (cb.remaining_bits() >= body_bits + 33u) { + CHECK(cb.store_bool_bool(false) // body:(Either X ^X) -> left X + && cb.store_long_bool(-1, 32) // int = -1 ("message type") + && cb.append_bitslice(cs.prefetch_bits(body_bits))); // truncated message body + } else { + vm::CellBuilder cb2; + CHECK(cb.store_bool_bool(true) // body:(Either X ^X) -> right ^X + && cb2.store_long_bool(-1, 32) // int = -1 ("message type") + && cb2.append_bitslice(cs.prefetch_bits(body_bits)) // truncated message body + && cb.store_builder_ref_bool(std::move(cb2))); // ^X + } + } else { + CHECK(cb.store_bool_bool(false)); // body:(Either ..) + } + CHECK(cb.finalize_to(bp.out_msg)); if (verbosity > 2) { - std::cerr << "generated bounced message: "; + LOG(INFO) << "generated bounced message: "; block::gen::t_Message_Any.print_ref(std::cerr, bp.out_msg); } out_msgs.push_back(bp.out_msg); diff --git a/submodules/ton/tonlib-src/crypto/block/transaction.h b/submodules/ton/tonlib-src/crypto/block/transaction.h index 5ab34710d0..5214a1b6a5 100644 --- a/submodules/ton/tonlib-src/crypto/block/transaction.h +++ b/submodules/ton/tonlib-src/crypto/block/transaction.h @@ -139,6 +139,7 @@ struct ComputePhaseConfig { struct ActionPhaseConfig { int max_actions{255}; + int bounce_msg_body{0}; // usually 0 or 256 bits MsgPrices fwd_std; MsgPrices fwd_mc; // from/to masterchain const WorkchainSet* workchains{nullptr}; diff --git a/submodules/ton/tonlib-src/crypto/common/linalloc.hpp b/submodules/ton/tonlib-src/crypto/common/linalloc.hpp new file mode 100644 index 0000000000..da2ed05b04 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/common/linalloc.hpp @@ -0,0 +1,50 @@ +/* + This file is part of TON Blockchain Library. + + TON Blockchain Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + TON Blockchain Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with TON Blockchain Library. If not, see . + + Copyright 2020 Telegram Systems LLP +*/ +namespace td { + +class LinearAllocator { + std::size_t size; + char *ptr, *cur, *end; + + public: + LinearAllocator(std::size_t _size) : size(_size) { + cur = ptr = (char*)malloc(size); + if (!ptr) { + throw std::bad_alloc(); + } + end = ptr + size; + } + ~LinearAllocator() { + free(ptr); + } + void* allocate(std::size_t count) { + char* t = cur; + cur += (count + 7) & -8; + if (cur > end) { + throw std::bad_alloc(); + } + return (void*)t; + } +}; + +} // namespace td + +inline void* operator new(std::size_t count, td::LinearAllocator& alloc) { + return alloc.allocate(count); +} diff --git a/submodules/ton/tonlib-src/crypto/common/refint.cpp b/submodules/ton/tonlib-src/crypto/common/refint.cpp index 3a031a5a38..a8fe1762ce 100644 --- a/submodules/ton/tonlib-src/crypto/common/refint.cpp +++ b/submodules/ton/tonlib-src/crypto/common/refint.cpp @@ -118,6 +118,24 @@ std::pair divmod(RefInt256 x, RefInt256 y, int round_mode) return std::make_pair(std::move(quot), std::move(x)); } +RefInt256 muldiv(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode) { + typename td::BigInt256::DoubleInt tmp{0}; + tmp.add_mul(*x, *y); + RefInt256 quot{true}; + tmp.mod_div(*z, quot.unique_write(), round_mode); + quot.write().normalize(); + return quot; +} + +std::pair muldivmod(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode) { + typename td::BigInt256::DoubleInt tmp{0}; + tmp.add_mul(*x, *y); + RefInt256 quot{true}; + tmp.mod_div(*z, quot.unique_write(), round_mode); + quot.write().normalize(); + return std::make_pair(std::move(quot), td::make_refint(tmp)); +} + RefInt256 operator&(RefInt256 x, RefInt256 y) { x.write() &= *y; return x; diff --git a/submodules/ton/tonlib-src/crypto/common/refint.h b/submodules/ton/tonlib-src/crypto/common/refint.h index ea1ae81b7f..a905eb7733 100644 --- a/submodules/ton/tonlib-src/crypto/common/refint.h +++ b/submodules/ton/tonlib-src/crypto/common/refint.h @@ -45,6 +45,8 @@ extern RefInt256 operator%(RefInt256 x, RefInt256 y); extern RefInt256 div(RefInt256 x, RefInt256 y, int round_mode = -1); extern RefInt256 mod(RefInt256 x, RefInt256 y, int round_mode = -1); extern std::pair divmod(RefInt256 x, RefInt256 y, int round_mode = -1); +extern RefInt256 muldiv(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode = -1); +extern std::pair muldivmod(RefInt256 x, RefInt256 y, RefInt256 z, int round_mode = -1); extern RefInt256 operator-(RefInt256 x); extern RefInt256 operator&(RefInt256 x, RefInt256 y); extern RefInt256 operator|(RefInt256 x, RefInt256 y); diff --git a/submodules/ton/tonlib-src/crypto/fift/lib/Asm.fif b/submodules/ton/tonlib-src/crypto/fift/lib/Asm.fif index ced35d6fd1..a2d22af244 100644 --- a/submodules/ton/tonlib-src/crypto/fift/lib/Asm.fif +++ b/submodules/ton/tonlib-src/crypto/fift/lib/Asm.fif @@ -1,7 +1,7 @@ library TVM_Asm // simple TVM Assembler variable @atend -'nop @atend ! +{ "not in asm context" abort } @atend ! { `normal eq? not abort"must be terminated by }>" } : @normal? { @atend @ 1 { @atend ! @normal? } does @atend ! } : @pushatend { @pushatend ref, swap @endblk } does @atend ! = -rot <= and } : 2x<= { 2 pick brembitrefs 1- 2x<= } : @havebitrefs -{ @havebits not ' @| if } : @ensurebits -{ @havebitrefs not ' @| if } : @ensurebitrefs +{ @havebits ' @| ifnot } : @ensurebits +{ @havebitrefs ' @| ifnot } : @ensurebitrefs { rot over @ensurebits -rot u, } : @simpleuop { tuck sbitrefs @ensurebitrefs swap s, } : @addop { tuck bbitrefs @ensurebitrefs swap b+ } : @addopb @@ -27,6 +28,7 @@ variable @atend { 1 { } : si() // x mi ma -- ? { rot tuck >= -rot <= and } : @range @@ -272,10 +274,27 @@ x{8A} @Defop(ref) PUSHREFCONT } cond } cond } dup : PUSHSLICE : SLICE -{ tuck bbitrefs swap 16 + dup 7 and 3 -roll swap @havebitrefs - not rot or - { swap b> PUSHREFCONT } - { over bbitrefs 2dup 120 0 2x<= +// ( b' -- ? ) +{ bbitrefs or 0= } : @cont-empty? +{ bbits 7 and 0= } : @cont-aligned? +// ( b b' -- ? ) +{ bbitrefs over 7 and { 2drop drop false } { + swap 16 + swap @havebitrefs nip + } cond +} : @cont-fits? +// ( b b' -- ? ) +{ bbitrefs over 7 and { 2drop drop false } { + 32 1 pair+ @havebitrefs nip + } cond +} : @cont-ref-fit? +// ( b b' b'' -- ? ) +{ over @cont-aligned? over @cont-aligned? and not { 2drop drop false } { + bbitrefs rot bbitrefs pair+ swap 32 + swap @havebitrefs nip + } cond +} : @two-cont-fit? +{ 2dup @cont-fits? not + { b> PUSHREFCONT } + { swap over bbitrefs 2dup 120 0 2x<= { drop swap x{9} s, swap 3 >> 4 u, swap b+ } { rot x{8F_} s, swap 2 u, swap 3 >> 7 u, swap b+ } cond } cond @@ -320,12 +339,16 @@ x{A985} @Defop MULDIVR x{A98C} @Defop MULDIVMOD x{A9A4} @Defop MULRSHIFT x{A9A5} @Defop MULRSHIFTR +x{A9A6} @Defop MULRSHIFTC x{A9B4} @Defop(8u+1) MULRSHIFT# x{A9B5} @Defop(8u+1) MULRSHIFTR# +x{A9B6} @Defop(8u+1) MULRSHIFTC# x{A9C4} @Defop LSHIFTDIV x{A9C5} @Defop LSHIFTDIVR +x{A9C6} @Defop LSHIFTDIVC x{A9D4} @Defop(8u+1) LSHIFT#DIV x{A9D5} @Defop(8u+1) LSHIFT#DIVR +x{A9D6} @Defop(8u+1) LSHIFT#DIVC x{AA} @Defop(8u+1) LSHIFT# x{AB} @Defop(8u+1) RSHIFT# x{AC} @Defop LSHIFT @@ -628,46 +651,80 @@ x{DB3F} @Defop RETDATA x{DC} @Defop IFRET x{DD} @Defop IFNOTRET x{DE} @Defop IF -{ }> PUSHCONT IF } : }>IF x{DF} @Defop IFNOT -{ }> PUSHCONT IFNOT } : }>IFNOT ' IFNOTRET : IF: ' IFRET : IFNOT: x{E0} @Defop IFJMP -{ }> PUSHCONT IFJMP } : }>IFJMP -{ { @normal? PUSHCONT IFJMP } @doafter<{ } : IFJMP:<{ x{E1} @Defop IFNOTJMP -{ }> PUSHCONT IFNOTJMP } : }>IFNOTJMP -{ { @normal? PUSHCONT IFNOTJMP } @doafter<{ } : IFNOTJMP:<{ x{E2} @Defop IFELSE -{ `else @endblk } : }>ELSE<{ -{ `else: @endblk } : }>ELSE: -{ PUSHCONT { @normal? PUSHCONT IFELSE } @doafter<{ } : @doifelse -{ 1 { swap @normal? -rot PUSHCONT swap PUSHCONT IFELSE } does @doafter<{ } : @doifnotelse -{ - { dup `else eq? - { drop @doifelse } - { dup `else: eq? - { drop PUSHCONT IFJMP } - { @normal? PUSHCONT IF - } cond - } cond - } @doafter<{ -} : IF:<{ -{ - { dup `else eq? - { drop @doifnotelse } - { dup `else: eq? - { drop PUSHCONT IFNOTJMP } - { @normal? PUSHCONT IFNOT - } cond - } cond - } @doafter<{ -} : IFNOT:<{ + x{E300} @Defop(ref) IFREF x{E301} @Defop(ref) IFNOTREF x{E302} @Defop(ref) IFJMPREF x{E303} @Defop(ref) IFNOTJMPREF +x{E30D} @Defop(ref) IFREFELSE +x{E30E} @Defop(ref) IFELSEREF +x{E30F} @Defop(ref*2) IFREFELSEREF + +{ 16 1 @havebitrefs nip } : @refop-fits? +// b b1 [e0 e1 e2] -- b' +{ -rot dup @cont-empty? { drop swap 0 } { + 2dup @cont-fits? { rot 1 } { + over @refop-fits? { b> rot 2 } { + swap @| swap 2dup @cont-fits? { rot 1 } { + b> rot 2 + } cond } cond } cond } cond + [] execute +} : @run-cont-op +{ triple 1 ' @run-cont-op does create } : @def-cont-op +{ } { PUSHCONT IF } { IFREF } @def-cont-op IF-cont +{ IFRET } { PUSHCONT IFJMP } { IFJMPREF } @def-cont-op IFJMP-cont +{ } { PUSHCONT IFNOT } { IFNOTREF } @def-cont-op IFNOT-cont +{ IFNOTRET } { PUSHCONT IFNOTJMP } { IFNOTJMPREF } @def-cont-op IFNOTJMP-cont +{ dup 2over rot } : 3dup + +recursive IFELSE-cont2 { + dup @cont-empty? { drop IF-cont } { + over @cont-empty? { nip IFNOT-cont } { + 3dup @two-cont-fit? { -rot PUSHCONT swap PUSHCONT IFELSE } { + 3dup nip @cont-ref-fit? { rot swap PUSHCONT swap b> IFREFELSE } { + 3dup drop @cont-ref-fit? { -rot PUSHCONT swap b> IFELSEREF } { + rot 32 2 @havebitrefs { rot b> rot b> IFREFELSEREF } { + @| -rot IFELSE-cont2 + } cond } cond } cond } cond } cond } cond +} swap ! + +{ }> IF-cont } : }>IF +{ }> IFNOT-cont } : }>IFNOT +{ }> IFJMP-cont } : }>IFJMP +{ }> IFNOTJMP-cont } : }>IFNOTJMP +{ { @normal? IFJMP-cont } @doafter<{ } : IFJMP:<{ +{ { @normal? IFNOTJMP-cont } @doafter<{ } : IFNOTJMP:<{ +{ `else @endblk } : }>ELSE<{ +{ `else: @endblk } : }>ELSE: +{ 1 { swap @normal? swap IFELSE-cont2 } does @doafter<{ } : @doifelse +{ 1 { swap @normal? IFELSE-cont2 } does @doafter<{ } : @doifnotelse +{ + { dup `else eq? + { drop @doifelse } + { dup `else: eq? + { drop IFJMP-cont } + { @normal? IF-cont + } cond + } cond + } @doafter<{ +} : IF:<{ +{ + { dup `else eq? + { drop @doifnotelse } + { dup `else: eq? + { drop IFNOTJMP-cont } + { @normal? IFNOT-cont + } cond + } cond + } @doafter<{ +} : IFNOT:<{ + x{E304} @Defop CONDSEL x{E305} @Defop CONDSELCHK x{E308} @Defop IFRETALT @@ -676,18 +733,22 @@ x{E309} @Defop IFNOTRETALT { PUSHCONT REPEAT } : }>REPEAT -{ { @normal? PUSHCONT REPEAT } @doafter<{ } : REPEAT:<{ x{E5} dup @Defop REPEATEND @Defop REPEAT: x{E6} @Defop UNTIL -{ }> PUSHCONT UNTIL } : }>UNTIL -{ { @normal? PUSHCONT UNTIL } @doafter<{ } : UNTIL:<{ x{E7} dup @Defop UNTILEND @Defop UNTIL: x{E8} @Defop WHILE x{E9} @Defop WHILEEND +x{EA} @Defop AGAIN +x{EB} dup @Defop AGAINEND @Defop AGAIN: + { `do @endblk } : }>DO<{ { `do: @endblk } : }>DO: +{ }> PUSHCONT REPEAT } : }>REPEAT +{ { @normal? PUSHCONT REPEAT } @doafter<{ } : REPEAT:<{ +{ }> PUSHCONT UNTIL } : }>UNTIL +{ { @normal? PUSHCONT UNTIL } @doafter<{ } : UNTIL:<{ { PUSHCONT { @normal? PUSHCONT WHILE } @doafter<{ } : @dowhile { { dup `do eq? @@ -696,10 +757,34 @@ x{E9} @Defop WHILEEND } cond } @doafter<{ } : WHILE:<{ -x{EA} @Defop AGAIN { }> PUSHCONT AGAIN } : }>AGAIN { { @normal? PUSHCONT AGAIN } @doafter<{ } : AGAIN:<{ -x{EB} dup @Defop AGAINEND @Defop AGAIN: + +x{E314} @Defop REPEATBRK +x{E315} @Defop REPEATENDBRK +x{E316} @Defop UNTILBRK +x{E317} dup @Defop UNTILENDBRK @Defop UNTILBRK: +x{E318} @Defop WHILEBRK +x{E319} @Defop WHILEENDBRK +x{E31A} @Defop AGAINBRK +x{E31B} dup @Defop AGAINENDBRK @Defop AGAINBRK: + +{ }> PUSHCONT REPEATBRK } : }>REPEATBRK +{ { @normal? PUSHCONT REPEATBRK } @doafter<{ } : REPEATBRK:<{ +{ }> PUSHCONT UNTILBRK } : }>UNTILBRK +{ { @normal? PUSHCONT UNTILBRK } @doafter<{ } : UNTILBRK:<{ +{ PUSHCONT { @normal? PUSHCONT WHILEBRK } @doafter<{ } : @dowhile +{ + { dup `do eq? + { drop @dowhile } + { `do: eq? not abort"`}>DO<{` expected" PUSHCONT WHILEENDBRK + } cond + } @doafter<{ +} : WHILEBRK:<{ +{ }> PUSHCONT AGAINBRK } : }>AGAINBRK +{ { @normal? PUSHCONT AGAINBRK } @doafter<{ } : AGAINBRK:<{ + + // // continuation stack manipulation and continuation creation // @@ -745,6 +830,8 @@ x{EDF6} @Defop THENRET x{EDF7} @Defop THENRETALT x{EDF8} @Defop INVERT x{EDF9} @Defop BOOLEVAL +x{EDFA} @Defop SAMEALT +x{EDFB} @Defop SAMEALTSAVE // x{EE} is BLESSARGS // // dictionary subroutine call/jump primitives diff --git a/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif b/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif index 1b7af49f82..6c83001a22 100644 --- a/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif +++ b/submodules/ton/tonlib-src/crypto/fift/lib/Fift.fif @@ -111,6 +111,8 @@ variable base { cdr cdr } : cddr { cdr cdr car } : caddr { null ' cons rot times } : list +{ -rot pair swap ! } : 2! +{ @ unpair } : 2@ { true (atom) drop } : atom { bl word atom 1 'nop } ::_ ` { hole dup 1 { @ execute } does create } : recursive @@ -121,13 +123,18 @@ variable base { 0 word -trailing scan-until-word 1 'nop } ::_ $<< { 0x40 runvmx } : runvmcode { 0x48 runvmx } : gasrunvmcode +{ 0xc8 runvmx } : gas2runvmcode { 0x43 runvmx } : runvmdict { 0x4b runvmx } : gasrunvmdict +{ 0xcb runvmx } : gas2runvmdict { 0x45 runvmx } : runvm { 0x4d runvmx } : gasrunvm +{ 0xcd runvmx } : gas2runvm { 0x55 runvmx } : runvmctx { 0x5d runvmx } : gasrunvmctx +{ 0xdd runvmx } : gas2runvmctx { 0x75 runvmx } : runvmctxact { 0x7d runvmx } : gasrunvmctxact +{ 0xfd runvmx } : gas2runvmctxact { 0x35 runvmx } : runvmctxactq { 0x3d runvmx } : gasrunvmctxactq diff --git a/submodules/ton/tonlib-src/crypto/fift/lib/Lists.fif b/submodules/ton/tonlib-src/crypto/fift/lib/Lists.fif index 3d50ae0f4c..b59e40a0d9 100644 --- a/submodules/ton/tonlib-src/crypto/fift/lib/Lists.fif +++ b/submodules/ton/tonlib-src/crypto/fift/lib/Lists.fif @@ -111,6 +111,42 @@ recursive list-map { swap uncons -rot over execute -rot list-map cons } cond } swap ! + +variable ctxdump variable curctx +// (a1 .. an) e -- executes e for a1, ..., an +{ ctxdump @ curctx @ ctxdump 2! curctx 2! + { curctx 2@ over null? not } { swap uncons rot tuck curctx 2! execute } + while 2drop ctxdump 2@ curctx ! ctxdump ! +} : list-foreach +forget ctxdump forget curctx + +// +// Experimental implementation of `for` loops with index +// +variable loopdump variable curloop +{ curloop @ loopdump @ loopdump 2! } : push-loop-ctx +{ loopdump 2@ loopdump ! curloop ! } : pop-loop-ctx +// ilast i0 e -- executes e for i=i0,i0+1,...,ilast-1 +{ -rot 2dup > { + push-loop-ctx { + triple dup curloop ! first execute curloop @ untriple 1+ 2dup <= + } until pop-loop-ctx + } if 2drop drop +} : for +// ilast i0 e -- same as 'for', but pushes current index i before executing e +{ -rot 2dup > { + push-loop-ctx { + triple dup curloop ! untriple nip swap execute curloop @ untriple 1+ 2dup <= + } until pop-loop-ctx + } if 2drop drop +} : for-i +// ( -- i ) Returns innermost loop index +{ curloop @ third } : i +// ( -- j ) Returns outer loop index +{ loopdump @ car third } : j +{ loopdump @ cadr third } : k +forget curloop forget loopdump + // // create Lisp-style lists using words "(" and ")" // diff --git a/submodules/ton/tonlib-src/crypto/fift/lib/TonUtil.fif b/submodules/ton/tonlib-src/crypto/fift/lib/TonUtil.fif index 0e2155e178..4ee5fc1518 100644 --- a/submodules/ton/tonlib-src/crypto/fift/lib/TonUtil.fif +++ b/submodules/ton/tonlib-src/crypto/fift/lib/TonUtil.fif @@ -77,15 +77,17 @@ library TonUtil // TON Blockchain Fift Library 1000000000 constant Gram { Gram swap */r } : Gram*/ { Gram * } : Gram* +{ (number) dup { 1- ' Gram*/ ' Gram* cond true } if +} : $>GR? // ( S -- nanograms ) -{ (number) ?dup 0= abort"not a valid Gram amount" -1- ' Gram*/ ' Gram* cond +{ $>GR? not abort"not a valid Gram amount" } : $>GR { bl word $>GR 1 'nop } ::_ GR$ // ( nanograms -- S ) { dup abs <# ' # 9 times char . hold #s rot sign #> nip -trailing0 } : (.GR) -{ (.GR) ."GR$" type space } : .GR +{ (.GR) ."GR$" type } : .GR_ +{ .GR_ space } : .GR // b x -- b' ( serializes a Gram amount ) { -1 { 1+ 2dup 8 * ufits } until @@ -105,19 +107,66 @@ nip -trailing0 } : (.GR) ' VarUInt32, : val, ' VarUInt32@ : val@ // d k v -- d' -{ cc -{ dup null? { ."(null) " drop } { val@ . } cond } dup : .maybeVarUInt32 : .val -{ cc-key-bits { swap 32 1<< rmod . ."-> " .val ."; " true } dictforeach drop cr } : .cc +{ dup null? { ."(null)" drop } { val@ ._ } cond } dup : .maybeVarUInt32 : .val +{ swap cc-key-bits { rot { ."+" } if .val ."*$" ._ true true } idictforeach drop } : (.cc) +{ false (.cc) { ."0" } ifnot } : .cc_ +{ .cc_ space } : .cc +{ true (.cc) drop } : .+cc_ +{ .+cc_ space } : .+cc { cc-key-bits { rot . ."-> " swap .val .val ."; " true } dictdiff drop cr } : show-cc-diff { cc-key-bits { val@ swap val@ + val, true } dictmerge } : cc+ -{ null swap cc-key-bits { val@ pair swap cons true } dictforeach drop } : cc>list-rev +{ null swap cc-key-bits { val@ pair swap cons true } idictforeach drop } : cc>list-rev { cc>list-rev list-reverse } : cc>list forget val, forget val@ forget .val +// ( S -- x -1 or 0 ) +{ (number) dup 2 = { -rot 2drop } if 1 = } : int? +{ int? dup { drop dup 0< { drop false } { true } cond } if } : pos-int? +// ( S -- k v -1 or 0 ) Parses expression * or *$ +{ dup "*" $pos dup 0< { 2drop false } { + $| dup $len 2 < { 2drop false } { + 1 $| nip dup 1 $| swap "$" $= { swap } if drop + int? dup { over 32 fits { 2drop false } ifnot } if + not { drop false } { + swap pos-int? not { drop false } { + true + } cond } cond } cond } cond +} : cc-key-value? +// ( S -- D -1 or 0 ) Parses an extra currency collection +// e.g. "10000*$3+7777*$-11" means "10000 units of currency #3 and 7777 units of currency #-11" +{ dictnew { // S D + swap dup "+" $pos dup 0< { drop null -rot } { $| 1 $| nip -rot } cond + cc-key-value? { +ccpair over null? dup { rot drop true } if } { 2drop false true } cond + } until +} : $>xcc? +{ $>xcc? not abort"invalid extra currency collection" } : $>xcc +{ char } word dup $len { $>xcc } { drop dictnew } cond 1 'nop } ::_ CX{ + +// complete currency collections +{ $>xcc? { true } { drop false } cond } : end-parse-cc +// ( S -- x D -1 or 0 ) Parses a currency collection +// e.g. "1.2+300*$2" means "1200000000ng plus 300 units of currency #2" +{ 0 swap dup "+" $pos dup 0< { drop dup + $>GR? { nip nip dictnew true } { end-parse-cc } cond + } { over swap $| swap $>GR? { 2swap 2drop swap 1 $| nip } { drop + } cond end-parse-cc } cond +} : $>cc? +{ $>cc? not abort"invalid currency collection" } : $>cc +{ char } word dup $len { $>cc } { drop 0 dictnew } cond 2 'nop } ::_ CC{ +// ( x D -- ) +{ swap ?dup { .GR_ .+cc_ } { .cc_ } cond } : .GR+cc_ +{ .GR+cc_ space } : .GR+cc +{ -rot Gram, swap dict, } : Gram+cc, + // Libraries // ( -- D ) New empty library collection ' dictnew : Libs{ diff --git a/submodules/ton/tonlib-src/crypto/fift/words.cpp b/submodules/ton/tonlib-src/crypto/fift/words.cpp index 3afd687ec4..f9be336f43 100644 --- a/submodules/ton/tonlib-src/crypto/fift/words.cpp +++ b/submodules/ton/tonlib-src/crypto/fift/words.cpp @@ -177,28 +177,15 @@ void interpret_divmod(vm::Stack& stack, int round_mode) { } void interpret_times_div(vm::Stack& stack, int round_mode) { - auto z = stack.pop_int(); - auto y = stack.pop_int(); - auto x = stack.pop_int(); - typename td::BigInt256::DoubleInt tmp{0}; - tmp.add_mul(*x, *y); - auto q = td::make_refint(); - tmp.mod_div(*z, q.unique_write(), round_mode); - q.unique_write().normalize(); - stack.push_int(std::move(q)); + auto z = stack.pop_int(), y = stack.pop_int(), x = stack.pop_int(); + stack.push_int(muldiv(std::move(x), std::move(y), std::move(z), round_mode)); } void interpret_times_divmod(vm::Stack& stack, int round_mode) { - auto z = stack.pop_int(); - auto y = stack.pop_int(); - auto x = stack.pop_int(); - typename td::BigInt256::DoubleInt tmp{0}; - tmp.add_mul(*x, *y); - auto q = td::make_refint(); - tmp.mod_div(*z, q.unique_write(), round_mode); - q.unique_write().normalize(); - stack.push_int(std::move(q)); - stack.push_int(td::make_refint(tmp)); + auto z = stack.pop_int(), y = stack.pop_int(), x = stack.pop_int(); + auto dm = muldivmod(std::move(x), std::move(y), std::move(z)); + stack.push_int(std::move(dm.first)); + stack.push_int(std::move(dm.second)); } void interpret_times_mod(vm::Stack& stack, int round_mode) { @@ -2242,6 +2229,7 @@ std::vector> get_vm_libraries() { // +16 = load c7 (smart-contract context) // +32 = return c5 (actions) // +64 = log vm ops to stderr +// +128 = pop hard gas limit (enabled by ACCEPT) from stack as well void interpret_run_vm(IntCtx& ctx, int mode) { if (mode < 0) { mode = ctx.stack.pop_smallint_range(0xff); @@ -2249,7 +2237,13 @@ void interpret_run_vm(IntCtx& ctx, int mode) { bool with_data = mode & 4; Ref c7; Ref data, actions; + long long gas_max = (mode & 128) ? ctx.stack.pop_long_range(vm::GasLimits::infty) : vm::GasLimits::infty; long long gas_limit = (mode & 8) ? ctx.stack.pop_long_range(vm::GasLimits::infty) : vm::GasLimits::infty; + if (!(mode & 128)) { + gas_max = gas_limit; + } else { + gas_max = std::max(gas_max, gas_limit); + } if (mode & 16) { c7 = ctx.stack.pop_tuple(); } @@ -2259,7 +2253,7 @@ void interpret_run_vm(IntCtx& ctx, int mode) { auto cs = ctx.stack.pop_cellslice(); OstreamLogger ostream_logger(ctx.error_stream); auto log = create_vm_log((mode & 64) && ctx.error_stream ? &ostream_logger : nullptr); - vm::GasLimits gas{gas_limit}; + vm::GasLimits gas{gas_limit, gas_max}; int res = vm::run_vm_code(cs, ctx.stack, mode & 3, &data, log, nullptr, &gas, get_vm_libraries(), std::move(c7), &actions); ctx.stack.push_smallint(res); diff --git a/submodules/ton/tonlib-src/crypto/func/builtins.cpp b/submodules/ton/tonlib-src/crypto/func/builtins.cpp index 066da4602f..91020be060 100644 --- a/submodules/ton/tonlib-src/crypto/func/builtins.cpp +++ b/submodules/ton/tonlib-src/crypto/func/builtins.cpp @@ -427,9 +427,7 @@ AsmOp compile_negate(std::vector& res, std::vector& args) { return exec_op("NEGATE", 1); } -AsmOp compile_mul(std::vector& res, std::vector& args) { - assert(res.size() == 1 && args.size() == 2); - VarDescr &r = res[0], &x = args[0], &y = args[1]; +AsmOp compile_mul_internal(VarDescr& r, VarDescr& x, VarDescr& y) { if (x.is_int_const() && y.is_int_const()) { r.set_const(x.int_const * y.int_const); x.unused(); @@ -492,6 +490,11 @@ AsmOp compile_mul(std::vector& res, std::vector& args) { return exec_op("MUL", 2); } +AsmOp compile_mul(std::vector& res, std::vector& args) { + assert(res.size() == 1 && args.size() == 2); + return compile_mul_internal(res[0], args[0], args[1]); +} + AsmOp compile_lshift(std::vector& res, std::vector& args) { assert(res.size() == 1 && args.size() == 2); VarDescr &r = res[0], &x = args[0], &y = args[1]; @@ -566,9 +569,7 @@ AsmOp compile_rshift(std::vector& res, std::vector& args, in return exec_op(rshift, 2); } -AsmOp compile_div(std::vector& res, std::vector& args, int round_mode) { - assert(res.size() == 1 && args.size() == 2); - VarDescr &r = res[0], &x = args[0], &y = args[1]; +AsmOp compile_div_internal(VarDescr& r, VarDescr& x, VarDescr& y, int round_mode) { if (x.is_int_const() && y.is_int_const()) { r.set_const(div(x.int_const, y.int_const, round_mode)); x.unused(); @@ -608,6 +609,11 @@ AsmOp compile_div(std::vector& res, std::vector& args, int r return exec_op(op, 2); } +AsmOp compile_div(std::vector& res, std::vector& args, int round_mode) { + assert(res.size() == 1 && args.size() == 2); + return compile_div_internal(res[0], args[0], args[1], round_mode); +} + AsmOp compile_mod(std::vector& res, std::vector& args, int round_mode) { assert(res.size() == 1 && args.size() == 2); VarDescr &r = res[0], &x = args[0], &y = args[1]; @@ -648,6 +654,87 @@ AsmOp compile_mod(std::vector& res, std::vector& args, int r return exec_op(op, 2); } +AsmOp compile_muldiv(std::vector& res, std::vector& args, int round_mode) { + assert(res.size() == 1 && args.size() == 3); + VarDescr &r = res[0], &x = args[0], &y = args[1], &z = args[2]; + if (x.is_int_const() && y.is_int_const() && z.is_int_const()) { + r.set_const(muldiv(x.int_const, y.int_const, z.int_const, round_mode)); + x.unused(); + y.unused(); + z.unused(); + return push_const(r.int_const); + } + if (x.always_zero() || y.always_zero()) { + // dubious optimization for z=0... + x.unused(); + y.unused(); + z.unused(); + r.set_const(td::make_refint(0)); + return push_const(r.int_const); + } + char c = (round_mode < 0) ? 0 : (round_mode > 0 ? 'C' : 'R'); + r.val = emulate_div(emulate_mul(x.val, y.val), z.val); + if (z.is_int_const()) { + if (*z.int_const == 0) { + x.unused(); + y.unused(); + z.unused(); + r.set_const(div(z.int_const, z.int_const)); + return push_const(r.int_const); + } + if (*z.int_const == 1) { + z.unused(); + return compile_mul_internal(r, x, y); + } + } + if (y.is_int_const() && *y.int_const == 1) { + y.unused(); + return compile_div_internal(r, x, z, round_mode); + } + if (x.is_int_const() && *x.int_const == 1) { + x.unused(); + return compile_div_internal(r, y, z, round_mode); + } + if (z.is_int_const()) { + int k = is_pos_pow2(z.int_const); + if (k > 0) { + z.unused(); + std::string op = "MULRSHIFT"; + if (c) { + op += c; + } + return exec_arg_op(op + '#', k, 2); + } + } + if (y.is_int_const()) { + int k = is_pos_pow2(y.int_const); + if (k > 0) { + y.unused(); + std::string op = "LSHIFT#DIV"; + if (c) { + op += c; + } + return exec_arg_op(op, k, 2); + } + } + if (x.is_int_const()) { + int k = is_pos_pow2(x.int_const); + if (k > 0) { + x.unused(); + std::string op = "LSHIFT#DIV"; + if (c) { + op += c; + } + return exec_arg_op(op, k, 2); + } + } + std::string op = "MULDIV"; + if (c) { + op += c; + } + return exec_op(op, 3); +} + int compute_compare(td::RefInt256 x, td::RefInt256 y, int mode) { int s = td::cmp(x, y); if (mode == 7) { @@ -933,8 +1020,9 @@ void define_builtins() { define_builtin_func("^_&=_", arith_bin_op, AsmOp::Custom("AND", 2)); define_builtin_func("^_|=_", arith_bin_op, AsmOp::Custom("OR", 2)); define_builtin_func("^_^=_", arith_bin_op, AsmOp::Custom("XOR", 2)); - define_builtin_func("muldivr", TypeExpr::new_map(Int3, Int), AsmOp::Custom("MULDIVR", 3)); - define_builtin_func("muldiv", TypeExpr::new_map(Int3, Int), AsmOp::Custom("MULDIV", 3)); + define_builtin_func("muldiv", TypeExpr::new_map(Int3, Int), std::bind(compile_muldiv, _1, _2, -1)); + define_builtin_func("muldivr", TypeExpr::new_map(Int3, Int), std::bind(compile_muldiv, _1, _2, 0)); + define_builtin_func("muldivc", TypeExpr::new_map(Int3, Int), std::bind(compile_muldiv, _1, _2, 1)); define_builtin_func("muldivmod", TypeExpr::new_map(Int3, Int2), AsmOp::Custom("MULDIVMOD", 3, 2)); define_builtin_func("_==_", arith_bin_op, std::bind(compile_cmp_int, _1, _2, 2)); define_builtin_func("_!=_", arith_bin_op, std::bind(compile_cmp_int, _1, _2, 5)); diff --git a/submodules/ton/tonlib-src/crypto/func/optimize.cpp b/submodules/ton/tonlib-src/crypto/func/optimize.cpp index 85c1fdd300..f8dc3d8273 100644 --- a/submodules/ton/tonlib-src/crypto/func/optimize.cpp +++ b/submodules/ton/tonlib-src/crypto/func/optimize.cpp @@ -575,9 +575,9 @@ bool Optimizer::find_at_least(int pb) { (is_push_rotrev(&i) && rewrite(AsmOp::Push(i), AsmOp::Custom("-ROT"))) || (is_push_xchg(&i, &j, &k) && rewrite(AsmOp::Push(i), AsmOp::Xchg(j, k))) || (is_reverse(&i, &j) && rewrite(AsmOp::BlkReverse(i, j))) || + (is_blkdrop2(&i, &j) && rewrite(AsmOp::BlkDrop2(i, j))) || (is_nip_seq(&i, &j) && rewrite(AsmOp::Xchg(i, j), AsmOp::BlkDrop(i))) || (is_pop_blkdrop(&i, &k) && rewrite(AsmOp::Pop(i), AsmOp::BlkDrop(k))) || - (is_blkdrop2(&i, &j) && rewrite(AsmOp::BlkDrop2(i, j))) || (is_2pop_blkdrop(&i, &j, &k) && (k >= 3 && k <= 13 && i != j + 1 && i <= 15 && j <= 14 ? rewrite(AsmOp::Xchg2(j + 1, i), AsmOp::BlkDrop(k + 2)) : rewrite(AsmOp::Pop(i), AsmOp::Pop(j), AsmOp::BlkDrop(k)))) || diff --git a/submodules/ton/tonlib-src/crypto/func/parse-func.cpp b/submodules/ton/tonlib-src/crypto/func/parse-func.cpp index 5c44444020..6e97cc3978 100644 --- a/submodules/ton/tonlib-src/crypto/func/parse-func.cpp +++ b/submodules/ton/tonlib-src/crypto/func/parse-func.cpp @@ -1288,7 +1288,9 @@ void parse_func_def(Lexer& lex) { sym::close_scope(lex); } -bool parse_source(std::istream* is, const src::FileDescr* fdescr) { +std::vector source_fdescr; + +bool parse_source(std::istream* is, src::FileDescr* fdescr) { src::SourceReader reader{is, fdescr}; Lexer lex{reader, true, ";,()[] ~."}; while (lex.tp() != _Eof) { @@ -1306,6 +1308,7 @@ bool parse_source_file(const char* filename) { throw src::Fatal{"source file name is an empty string"}; } src::FileDescr* cur_source = new src::FileDescr{filename}; + source_fdescr.push_back(cur_source); std::ifstream ifs{filename}; if (ifs.fail()) { throw src::Fatal{std::string{"cannot open source file `"} + filename + "`"}; @@ -1314,7 +1317,9 @@ bool parse_source_file(const char* filename) { } bool parse_source_stdin() { - return parse_source(&std::cin, new src::FileDescr{"stdin", true}); + src::FileDescr* cur_source = new src::FileDescr{"stdin", true}; + source_fdescr.push_back(cur_source); + return parse_source(&std::cin, cur_source); } } // namespace funC diff --git a/submodules/ton/tonlib-src/crypto/parser/srcread.cpp b/submodules/ton/tonlib-src/crypto/parser/srcread.cpp index 3b363242ba..332f15393a 100644 --- a/submodules/ton/tonlib-src/crypto/parser/srcread.cpp +++ b/submodules/ton/tonlib-src/crypto/parser/srcread.cpp @@ -14,9 +14,10 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include "srcread.h" +#include namespace src { @@ -34,9 +35,47 @@ std::ostream& operator<<(std::ostream& os, const Fatal& fatal) { return os << fatal.get_msg(); } +const char* FileDescr::convert_offset(long offset, long* line_no, long* line_pos, long* line_size) const { + long lno = 0, lpos = -1, lsize = 0; + const char* lstart = nullptr; + if (offset >= 0 && offset < (long)text.size()) { + auto it = std::upper_bound(line_offs.begin(), line_offs.end(), offset); + lno = it - line_offs.begin(); + if (lno && it != line_offs.end()) { + lsize = it[0] - it[-1]; + lpos = offset - it[-1]; + lstart = text.data() + it[-1]; + } + } else { + lno = (long)line_offs.size(); + } + if (line_no) { + *line_no = lno; + } + if (line_pos) { + *line_pos = lpos; + } + if (line_size) { + *line_size = lsize; + } + return lstart; +} + +const char* FileDescr::push_line(std::string new_line) { + if (line_offs.empty()) { + line_offs.push_back(0); + } + std::size_t cur_size = text.size(); + text += new_line; + text += '\0'; + line_offs.push_back((long)text.size()); + return text.data() + cur_size; +} + void SrcLocation::show(std::ostream& os) const { os << fdescr; - if (line_no > 0) { + long line_no, line_pos; + if (fdescr && convert_pos(&line_no, &line_pos)) { os << ':' << line_no; if (line_pos >= 0) { os << ':' << (line_pos + 1); @@ -45,13 +84,15 @@ void SrcLocation::show(std::ostream& os) const { } bool SrcLocation::show_context(std::ostream& os) const { - if (text.empty() || line_pos < 0 || (unsigned)line_pos > text.size()) { + long line_no, line_pos, line_size; + if (!fdescr || !convert_pos(&line_no, &line_pos, &line_size)) { return false; } - bool skip_left = (line_pos > 200), skip_right = (line_pos + 200u < text.size()); - const char* start = skip_left ? text.c_str() + line_pos - 100 : text.c_str(); - const char* end = skip_right ? text.c_str() + line_pos + 100 : text.c_str() + text.size(); - const char* here = text.c_str() + line_pos; + bool skip_left = (line_pos > 200), skip_right = (line_pos + 200u < line_size); + const char* here = fdescr->text.data() + char_offs; + const char* base = here - line_pos; + const char* start = skip_left ? here - 100 : base; + const char* end = skip_right ? here + 100 : base + line_size; os << " "; if (skip_left) { os << "... "; @@ -99,8 +140,8 @@ void ParseError::show(std::ostream& os) const { where.show_context(os); } -SourceReader::SourceReader(std::istream* _is, const FileDescr* _fdescr) - : ifs(_is), loc(_fdescr), eof(false), cur_line_len(0), start(0), cur(0), end(0) { +SourceReader::SourceReader(std::istream* _is, FileDescr* _fdescr) + : ifs(_is), fdescr(_fdescr), loc(_fdescr), eof(false), cur_line_len(0), start(0), cur(0), end(0) { load_line(); } @@ -139,7 +180,7 @@ const char* SourceReader::set_ptr(const char* ptr) { if (ptr < cur || ptr > end) { error("parsing position went outside of line"); } - loc.line_pos = (int)(ptr - start); + loc.char_offs += ptr - cur; cur = ptr; } return ptr; @@ -149,12 +190,11 @@ bool SourceReader::load_line() { if (eof) { return false; } + loc.set_eof(); if (ifs->eof()) { set_eof(); return false; } - ++loc.line_no; - loc.line_pos = -1; std::getline(*ifs, cur_line); if (ifs->fail()) { set_eof(); @@ -174,11 +214,16 @@ bool SourceReader::load_line() { cur_line.pop_back(); --len; } - loc.text = cur_line; cur_line_len = (int)len; - loc.line_pos = 0; - cur = start = cur_line.c_str(); - end = start + cur_line_len; + if (fdescr) { + cur = start = fdescr->push_line(std::move(cur_line)); + end = start + len; + loc.char_offs = (std::size_t)(cur - fdescr->text.data()); + cur_line.clear(); + } else { + cur = start = cur_line.c_str(); + end = start + cur_line_len; + } return true; } diff --git a/submodules/ton/tonlib-src/crypto/parser/srcread.h b/submodules/ton/tonlib-src/crypto/parser/srcread.h index 05b792122e..9352a24222 100644 --- a/submodules/ton/tonlib-src/crypto/parser/srcread.h +++ b/submodules/ton/tonlib-src/crypto/parser/srcread.h @@ -14,11 +14,12 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include +#include #include namespace src { @@ -31,9 +32,13 @@ namespace src { struct FileDescr { std::string filename; + std::string text; + std::vector line_offs; bool is_stdin; FileDescr(std::string _fname, bool _stdin = false) : filename(std::move(_fname)), is_stdin(_stdin) { } + const char* push_line(std::string new_line); + const char* convert_offset(long offset, long* line_no, long* line_pos, long* line_size = nullptr) const; }; struct Fatal { @@ -49,16 +54,23 @@ std::ostream& operator<<(std::ostream& os, const Fatal& fatal); struct SrcLocation { const FileDescr* fdescr; - int line_no; - int line_pos; - std::string text; - SrcLocation() : fdescr(nullptr), line_no(0), line_pos(-1) { + long char_offs; + SrcLocation() : fdescr(nullptr), char_offs(-1) { } - SrcLocation(const FileDescr* _fdescr, int line = 0, int pos = -1) : fdescr(_fdescr), line_no(line), line_pos(pos) { + SrcLocation(const FileDescr* _fdescr, long offs = -1) : fdescr(_fdescr), char_offs(-1) { } bool defined() const { return fdescr; } + bool eof() const { + return char_offs == -1; + } + void set_eof() { + char_offs = -1; + } + const char* convert_pos(long* line_no, long* line_pos, long* line_size = nullptr) const { + return defined() ? fdescr->convert_offset(char_offs, line_no, line_pos, line_size) : nullptr; + } void show(std::ostream& os) const; bool show_context(std::ostream& os) const; void show_gen_error(std::ostream& os, std::string message, std::string err_type = "") const; @@ -98,6 +110,7 @@ struct ParseError : Error { class SourceReader { std::istream* ifs; + FileDescr* fdescr; SrcLocation loc; bool eof; std::string cur_line; @@ -106,7 +119,7 @@ class SourceReader { const char *start, *cur, *end; public: - SourceReader(std::istream* _is, const FileDescr* _fdescr); + SourceReader(std::istream* _is, FileDescr* _fdescr); bool load_line(); bool is_eof() const { return eof; diff --git a/submodules/ton/tonlib-src/crypto/smartcont/CreateState.fif b/submodules/ton/tonlib-src/crypto/smartcont/CreateState.fif index 1330a446f1..c369df5657 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/CreateState.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/CreateState.fif @@ -52,43 +52,56 @@ // elected-for elections-begin-before elections-end-before stakes-frozen { 4 0 reverse 15 config! } : config.election_params! -dictnew 0 2constant validator-dict -{ @' validator-dict } : validator-dict@ -{ validator-dict@ nip } : validator# +variable validator-dict +dictnew 0 validator-dict 2! +{ validator-dict @ second } : validator# // val-pubkey weight -- { dup 0<= abort"validator weight must be non-negative" dup 64 ufits not abort"validator weight must fit into 64 bits" over Blen 32 <> abort"validator public key must be 32 bytes long" + validator-dict @ first 34 config! } : config.validators! -dictnew constant workchain-dict +variable workchain-dict // root-hash file-hash enable-utime actual-min-split min-split max-split workchain-id -- { dup isWorkchainDescr? not abort"invalid WorkchainDescr created" - s s>c 12 config! } : config.workchains! +{ workchain-dict @ dict>s s>c 12 config! } : config.workchains! -dictnew constant special-dict +variable special-dict // special-smc-addr -- -{ x{} swap @' special-dict 256 udict! not abort"cannot add a new special smart contract" - =: special-dict +{ x{} swap special-dict @ 256 udict! not abort"cannot add a new special smart contract" + special-dict ! } : make_special -{ @' special-dict dict>s s>c 31 config! } : config.special! +{ special-dict @ dict>s s>c 31 config! } : config.special! + +// ( l -- D ) Converts a list of parameter indices into a dictionary +{ dictnew { swap uncons -rot idict! not abort"cannot add parameter index" over null? + } until nip +} : param-list-to-dict +{ param-list-to-dict 9 config! } : config.mandatory_params! +{ param-list-to-dict 10 config! } : config.critical_params! + +// min_tot_rounds max_tot_rounds min_wins max_losses min_store_sec max_store_sec bit_price cell_price -- +{ 8 untuple 8 0 reverse } : cfg-prop-setup +// normal-prop-params critical-prop-params -- +{ swap cfg-prop-setup swap cfg-prop-setup } : make-proposals-setup +{ make-proposals-setup 11 config! } : config.param_proposals_setup! // bit-pps cell-pps mc-bit-pps mc-cell-pps -- { + parse_vote_config PROC:<{ + // c + CTOS // cs + 8 LDU // _4 cs + SWAP // cs _4 + 54 EQINT // cs _8 + 44 THROWIFNOT + 8 LDU // _12 cs + 8 LDU // _12 _15 cs + 8 LDU // _12 _15 _18 cs + 8 LDU // _12 _15 _18 _21 cs + 32 LDU // _12 _15 _18 _21 _24 cs + 32 LDU // _12 _15 _18 _21 _24 _27 cs + 32 LDU // _12 _15 _18 _21 _24 _27 _30 cs + 32 LDU // _12 _15 _18 _21 _24 _27 _30 _33 cs + 8 -ROLL // cs _12 _15 _18 _21 _24 _27 _30 _33 + 8 TUPLE // cs res + SWAP // res cs + ENDS + }> + get_vote_config PROCREF:<{ + // critical? + 11 PUSHINT // critical? _2=11 + CONFIGOPTPARAM // critical? _3 + CTOS // critical? cs + 8 LDU // critical? _6 cs + SWAP + 145 PUSHINT // critical? cs _6 _9=145 + EQUAL // critical? cs _10 + 44 THROWIFNOT + SWAP // cs critical? + IF:<{ // cs + LDREF // _19 _18 + NIP // cs + }> // cs + PLDREF // _14 + parse_vote_config INLINECALLDICT // _15 + }> check_validator_set PROC:<{ // vset CTOS // cs @@ -101,87 +146,6 @@ PROGRAM{ 64 PUSHINT // addr query_id ans_tag _3=64 send_answer CALLDICT }> - recv_internal PROC:<{ - // in_msg_cell in_msg - SWAP // in_msg in_msg_cell - CTOS // in_msg cs - 4 LDU // in_msg flags cs - LDMSGADDR // in_msg flags _74 _73 - DROP // in_msg flags s_addr - DUP // in_msg flags s_addr s_addr - REWRITESTDADDR // in_msg flags s_addr src_wc src_addr - SWAP // in_msg flags s_addr src_addr src_wc - INC // in_msg flags s_addr src_addr _15 - s0 s3 XCHG - 1 PUSHINT // in_msg _15 s_addr src_addr flags _16=1 - AND // in_msg _15 s_addr src_addr _17 - s1 s3 XCHG // in_msg src_addr s_addr _15 _17 - OR // in_msg src_addr s_addr _18 - s3 PUSH // in_msg src_addr s_addr _18 in_msg - SEMPTY // in_msg src_addr s_addr _18 _19 - OR // in_msg src_addr s_addr _20 - IFJMP:<{ // in_msg src_addr s_addr - 3 BLKDROP // - }> // in_msg src_addr s_addr - s0 s2 XCHG // s_addr src_addr in_msg - 32 LDU // s_addr src_addr tag in_msg - 64 LDU // s_addr src_addr tag query_id in_msg - s2 PUSH - 1314280276 PUSHINT // s_addr src_addr tag query_id in_msg tag _29=1314280276 - EQUAL // s_addr src_addr tag query_id in_msg _30 - IFJMP:<{ // s_addr src_addr tag query_id in_msg - 1 2 BLKDROP2 // s_addr src_addr query_id in_msg - LDREF // s_addr src_addr query_id vset in_msg - ENDS - 1 PUSHINT // s_addr src_addr query_id vset _36=1 - CONFIGOPTPARAM // s_addr src_addr query_id vset elector_param - DUP // s_addr src_addr query_id vset elector_param elector_param - ISNULL // s_addr src_addr query_id vset elector_param _39 - IF:<{ // s_addr src_addr query_id vset elector_param - DROP // s_addr src_addr query_id vset - -1 PUSHINT // s_addr src_addr query_id vset _40=-1 - }>ELSE<{ // s_addr src_addr query_id vset elector_param - CTOS // s_addr src_addr query_id vset _42 - 256 PLDU // s_addr src_addr query_id vset _40 - }> // s_addr src_addr query_id vset elector_addr - s0 s3 XCHG - FALSE - s0 s4 XCHG // s_addr ok query_id vset src_addr elector_addr - EQUAL // s_addr ok query_id vset _47 - IF:<{ // s_addr ok query_id vset - s2 POP // s_addr vset query_id - OVER // s_addr vset query_id vset - check_validator_set CALLDICT // s_addr vset query_id t_since t_until - NOW // s_addr vset query_id t_since t_until t - s2 s(-1) PUXC // s_addr vset query_id t_since t_until t_since t - GREATER // s_addr vset query_id t_since t_until _53 - s0 s2 XCHG // s_addr vset query_id _53 t_until t_since - GREATER // s_addr vset query_id _53 _54 - AND // s_addr vset query_id ok - s0 s2 XCHG // s_addr ok query_id vset - }> // s_addr ok query_id vset - s0 s2 XCHG // s_addr vset query_id ok - IFJMP:<{ // s_addr vset query_id - 36 PUSHINT - ROT // s_addr query_id _56=36 vset - set_conf_param CALLDICT - 4000730955 PUSHINT // s_addr query_id _58=4000730955 - send_confirmation CALLDICT - }> // s_addr vset query_id - NIP // s_addr query_id - 4000730991 PUSHINT // s_addr query_id _60=4000730991 - send_error CALLDICT - }> // s_addr src_addr tag query_id in_msg - s2 s4 XCHG - 4 BLKDROP // tag - DUP // tag tag - 0 EQINT // tag _64 - SWAP - 31 PUSHPOW2 // _64 tag _67 - AND // _64 _68 - OR // _69 - 37 THROWIFNOT - }> change_elector_code PROC:<{ // cs 1 PUSHINT // cs _2=1 @@ -220,7 +184,7 @@ PROGRAM{ EQUAL // cfg_dict public_key action cs _5 IFJMP:<{ // cfg_dict public_key action cs NIP // cfg_dict public_key cs - 32 LDU // cfg_dict public_key param_index cs + 32 LDI // cfg_dict public_key param_index cs LDREF // cfg_dict public_key param_index param_value cs ENDS s0 s1 s3 XCHG3 @@ -263,33 +227,32 @@ PROGRAM{ DROP // cfg_dict public_key action 32 THROWIF }> + get_current_vset PROCREF:<{ + // + 34 PUSHINT // _1=34 + CONFIGOPTPARAM // vset + DUP // vset vset + CTOS // vset cs + 8 LDU // vset _6 cs + SWAP // vset cs _6 + 18 EQINT // vset cs _10 + 40 THROWIFNOT + 96 PUSHINT // vset cs _19 + SDSKIPFIRST // vset cs + 64 LDU // vset total_weight cs + }> get_validator_descr PROCREF:<{ // idx - 34 PUSHINT // idx _2=34 - CONFIGOPTPARAM // idx vset - DUP // idx vset vset - ISNULL // idx vset _4 - IFJMP:<{ // idx vset - 2DROP // - PUSHNULL // _5 - 0 PUSHINT // _5 _6=0 - }> // idx vset - CTOS // idx cs - 8 LDU // idx _10 cs - SWAP // idx cs _10 - 18 EQINT // idx cs _14 - 40 THROWIFNOT - 96 PUSHINT // idx cs _23 - SDSKIPFIRST // idx cs - 64 LDU // idx total_weight cs - NEWC // idx total_weight cs _30 - SWAP // idx total_weight _30 cs - STSLICER // idx total_weight _31 + get_current_vset INLINECALLDICT // idx _13 _14 _15 + s2 POP // idx cs total_weight + NEWC + ROT // idx total_weight _6 cs + STSLICER // idx total_weight _7 ENDC // idx total_weight dict s1 s2 XCHG - 16 PUSHINT // total_weight idx dict _35=16 + 16 PUSHINT // total_weight idx dict _11=16 DICTUGET - NULLSWAPIFNOT // total_weight _41 _42 + NULLSWAPIFNOT // total_weight _16 _17 DROP // total_weight value SWAP // value total_weight }> @@ -311,6 +274,53 @@ PROGRAM{ 64 LDU // _18 _31 _30 DROP // _18 _21 }> + parse_config_proposal PROCREF:<{ + // c + CTOS // cs + 8 LDI // _4 cs + SWAP // cs _4 + -13 EQINT // cs _10 + 44 THROWIFNOT + 32 LDI // _15 cs + LDOPTREF // _15 _18 cs + 1 LDI // id val hash cs + SWAP // id val cs hash + IF:<{ // id val cs + 256 LDU // id val hash cs + }>ELSE<{ // id val cs + -1 PUSHINT // id val cs hash=-1 + SWAP // id val hash cs + }> + ENDS + }> + unpack_proposal_status PROCREF:<{ + // cs + 8 LDI // _2 cs + SWAP // cs _2 + -50 EQINT // cs _8 + 44 THROWIFNOT + 32 LDU // _10 cs + LDREF // _10 _13 cs + 1 LDI // _10 _13 _15 cs + LDDICT // _10 _13 _15 _18 cs + 64 LDI // _10 _13 _15 _18 _20 cs + 256 LDU // _10 _13 _15 _18 _20 _23 cs + }> + begin_pack_proposal_status PROC:<{ + // expires proposal critical? voters weight_remaining vset_id + -50 PUSHINT // expires proposal critical? voters weight_remaining vset_id _8 + NEWC // expires proposal critical? voters weight_remaining vset_id _8 _9 + 8 STI // expires proposal critical? voters weight_remaining vset_id _11 + s1 s6 XCHG // vset_id proposal critical? voters weight_remaining expires _11 + 32 STU // vset_id proposal critical? voters weight_remaining _13 + s1 s4 XCHG // vset_id weight_remaining critical? voters proposal _13 + STREF // vset_id weight_remaining critical? voters _14 + s1 s2 XCHG // vset_id weight_remaining voters critical? _14 + 1 STI // vset_id weight_remaining voters _16 + STDICT // vset_id weight_remaining _17 + 64 STI // vset_id _19 + 256 STU // _21 + }> new_proposal PROC:<{ // cs PUSHNULL // cs _1 @@ -417,6 +427,317 @@ PROGRAM{ DICTUSETB // vote_dict PUSHNULL // vote_dict _59 }> + register_voting_proposal PROCREF:<{ + // cs msg_value + SWAP // msg_value cs + 32 LDU // msg_value _5 cs + LDREF // msg_value _5 _8 cs + 1 LDI // msg_value _5 _8 _159 _158 + DROP // msg_value expire_at proposal critical? + s2 PUSH // msg_value expire_at proposal critical? expire_at + 30 RSHIFT# // msg_value expire_at proposal critical? _14 + IF:<{ // msg_value expire_at proposal critical? + NOW // msg_value expire_at proposal critical? _15 + s1 s3 XCHG // msg_value critical? proposal expire_at _15 + SUB // msg_value critical? proposal expire_at + s0 s2 XCHG // msg_value expire_at proposal critical? + }> // msg_value expire_at proposal critical? + OVER // msg_value expire_at proposal critical? proposal + parse_config_proposal INLINECALLDICT // msg_value expire_at proposal critical? param_id param_val hash + DUP // msg_value expire_at proposal critical? param_id param_val hash hash + -1 GTINT // msg_value expire_at proposal critical? param_id param_val hash _22 + IF:<{ // msg_value expire_at proposal critical? param_id param_val hash + s2 PUSH // msg_value expire_at proposal critical? param_id param_val hash param_id + CONFIGOPTPARAM // msg_value expire_at proposal critical? param_id param_val hash cur_val + DUP // msg_value expire_at proposal critical? param_id param_val hash cur_val cur_val + ISNULL // msg_value expire_at proposal critical? param_id param_val hash cur_val _26 + IF:<{ // msg_value expire_at proposal critical? param_id param_val hash cur_val + DROP // msg_value expire_at proposal critical? param_id param_val hash + 0 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash _27=0 + }>ELSE<{ // msg_value expire_at proposal critical? param_id param_val hash cur_val + HASHCU // msg_value expire_at proposal critical? param_id param_val hash _27 + }> // msg_value expire_at proposal critical? param_id param_val hash cur_hash + OVER // msg_value expire_at proposal critical? param_id param_val hash cur_hash hash + NEQ // msg_value expire_at proposal critical? param_id param_val hash _30 + IF:<{ // msg_value expire_at proposal critical? param_id param_val hash + DROP // msg_value expire_at proposal critical? param_id param_val + -3798229846 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash=-3798229846 + }> // msg_value expire_at proposal critical? param_id param_val hash + }>ELSE<{ // msg_value expire_at proposal critical? param_id param_val hash + 9 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash _33=9 + CONFIGOPTPARAM // msg_value expire_at proposal critical? param_id param_val hash m_params + s3 s(-1) PUXC + 32 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash param_id m_params _37=32 + DICTIGET + NULLSWAPIFNOT // msg_value expire_at proposal critical? param_id param_val hash _163 _164 + NIP // msg_value expire_at proposal critical? param_id param_val hash found? + IF:<{ // msg_value expire_at proposal critical? param_id param_val hash + DROP // msg_value expire_at proposal critical? param_id param_val + -3444600428 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash=-3444600428 + }> // msg_value expire_at proposal critical? param_id param_val hash + }> + OVER // msg_value expire_at proposal critical? param_id param_val hash param_val + CDEPTH // msg_value expire_at proposal critical? param_id param_val hash _40 + 8 PUSHPOW2 // msg_value expire_at proposal critical? param_id param_val hash _40 _41=256 + GEQ // msg_value expire_at proposal critical? param_id param_val hash _42 + IF:<{ // msg_value expire_at proposal critical? param_id param_val hash + DROP // msg_value expire_at proposal critical? param_id param_val + -3261162582 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash=-3261162582 + }> // msg_value expire_at proposal critical? param_id param_val hash + DUP // msg_value expire_at proposal critical? param_id param_val hash hash + -1 LESSINT // msg_value expire_at proposal critical? param_id param_val hash _45 + IFJMP:<{ // msg_value expire_at proposal critical? param_id param_val hash + 6 1 BLKDROP2 // hash + }> // msg_value expire_at proposal critical? param_id param_val hash + s3 PUSH // msg_value expire_at proposal critical? param_id param_val hash critical? + IFNOT:<{ // msg_value expire_at proposal critical? param_id param_val hash + 10 PUSHINT // msg_value expire_at proposal critical? param_id param_val hash _47=10 + CONFIGOPTPARAM // msg_value expire_at proposal critical? param_id param_val hash crit_params + s1 s3 XCHG + 32 PUSHINT // msg_value expire_at proposal critical? hash param_val param_id crit_params _51=32 + DICTIGET + NULLSWAPIFNOT // msg_value expire_at proposal critical? hash param_val _165 _166 + NIP // msg_value expire_at proposal critical? hash param_val found? + IF:<{ // msg_value expire_at proposal critical? hash param_val + -3279055188 PUSHINT + s2 POP // msg_value expire_at proposal critical? hash=-3279055188 param_val + }> // msg_value expire_at proposal critical? hash param_val + }>ELSE<{ + s2 POP // msg_value expire_at proposal critical? hash param_val + }> + OVER // msg_value expire_at proposal critical? hash param_val hash + -1 LESSINT // msg_value expire_at proposal critical? hash param_val _55 + IFJMP:<{ // msg_value expire_at proposal critical? hash param_val + s1 s5 XCHG + 5 BLKDROP // hash + }> // msg_value expire_at proposal critical? hash param_val + NIP // msg_value expire_at proposal critical? param_val + OVER // msg_value expire_at proposal critical? param_val critical? + get_vote_config INLINECALLDICT // msg_value expire_at proposal critical? param_val vote_cfg + 8 UNTUPLE // msg_value expire_at proposal critical? param_val _167 _168 _169 _170 _171 _172 _173 _174 + s4 POP + s4 POP + s5 POP // msg_value expire_at proposal critical? param_val max_store_sec max_tot_rounds bit_price cell_price min_store_sec + s8 s(-1) PUXC // msg_value expire_at proposal critical? param_val max_store_sec max_tot_rounds bit_price cell_price expire_at min_store_sec + LESS // msg_value expire_at proposal critical? param_val max_store_sec max_tot_rounds bit_price cell_price _67 + IFJMP:<{ // msg_value expire_at proposal critical? param_val max_store_sec max_tot_rounds bit_price cell_price + 9 BLKDROP // + -3313004649 PUSHINT // _68=-3313004649 + }> // msg_value expire_at proposal critical? param_val max_store_sec max_tot_rounds bit_price cell_price + s7 s3 XCHG2 // msg_value bit_price proposal critical? param_val cell_price max_tot_rounds expire_at max_store_sec + MIN // msg_value bit_price proposal critical? param_val cell_price max_tot_rounds expire_at + s0 s3 XCHG + 10 PUSHPOW2 // msg_value bit_price proposal critical? expire_at cell_price max_tot_rounds param_val _73=1024 + CDATASIZE // msg_value bit_price proposal critical? expire_at cell_price max_tot_rounds _175 _176 _177 + s2 POP // msg_value bit_price proposal critical? expire_at cell_price max_tot_rounds refs bits + 10 PUSHPOW2 // msg_value bit_price proposal critical? expire_at cell_price max_tot_rounds refs bits _76=1024 + ADD // msg_value bit_price proposal critical? expire_at cell_price max_tot_rounds refs _77 + s1 s7 XCHG // msg_value refs proposal critical? expire_at cell_price max_tot_rounds bit_price _77 + MUL // msg_value refs proposal critical? expire_at cell_price max_tot_rounds _78 + s0 s6 XCHG // msg_value _78 proposal critical? expire_at cell_price max_tot_rounds refs + 2 ADDCONST // msg_value _78 proposal critical? expire_at cell_price max_tot_rounds _80 + s1 s2 XCHG // msg_value _78 proposal critical? expire_at max_tot_rounds cell_price _80 + MUL // msg_value _78 proposal critical? expire_at max_tot_rounds _81 + s1 s5 XCHG // msg_value max_tot_rounds proposal critical? expire_at _78 _81 + ADD // msg_value max_tot_rounds proposal critical? expire_at pps + s0 s1 PUSH2 // msg_value max_tot_rounds proposal critical? expire_at pps pps expire_at + MUL // msg_value max_tot_rounds proposal critical? expire_at pps price + NOW // msg_value max_tot_rounds proposal critical? expire_at pps price _85 + s1 s3 XCHG // msg_value max_tot_rounds proposal critical? price pps expire_at _85 + ADD // msg_value max_tot_rounds proposal critical? price pps expire_at + load_data INLINECALLDICT // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict + s8 PUSH // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict proposal + HASHCU // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict phash + s0 s1 PUSH2 + 8 PUSHPOW2 // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict phash phash vote_dict _96=256 + DICTUGET + NULLSWAPIFNOT // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict phash pstatus found? + IFJMP:<{ // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict phash pstatus + s8 POP + s9 POP + s9 POP // msg_value vote_dict phash critical? pstatus pps expire_at cfg_dict stored_seqno public_key + s0 s5 XCHG // msg_value vote_dict phash critical? public_key pps expire_at cfg_dict stored_seqno pstatus + unpack_proposal_status INLINECALLDICT // msg_value vote_dict phash critical? public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id rest + s4 s12 PUXC // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id r_critical? critical? + NEQ // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id _106 + IFJMP:<{ // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id + 15 BLKDROP // + -3279055189 PUSHINT // _107=-3279055189 + }> // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id + s5 s8 PUSH2 // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id expires expire_at + GEQ // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id _108 + IFJMP:<{ // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id + 15 BLKDROP // + -3245109829 PUSHINT // _109=-3245109829 + }> // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno expires r_proposal r_critical? voters weight_remaining vset_id + s8 s5 PUXC // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters weight_remaining expire_at expires + SUB // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters weight_remaining _110 + 14 PUSHPOW2 // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters weight_remaining _110 _111=16384 + ADD // msg_value vote_dict phash rest public_key pps expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters weight_remaining _112 + s1 s9 XCHG // msg_value vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters pps _112 + MUL // msg_value vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters price + s13 s13 XCPU // price vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters msg_value price + SUB // price vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters _114 + 30 PUSHPOW2 // price vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters _114 _117 + LESS // price vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters _118 + IFJMP:<{ // price vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters + 13 BLKDROP // + -4032919844 PUSHINT // _119=-4032919844 + }> // price vote_dict phash rest public_key weight_remaining expire_at cfg_dict stored_seqno vset_id r_proposal r_critical? voters + s5 s6 XCHG + s0 s1 s4 XCHG3 + s7 s7 XCHG2 + s0 s3 XCHG // price vote_dict phash rest public_key stored_seqno cfg_dict expire_at r_proposal r_critical? voters weight_remaining vset_id + begin_pack_proposal_status INLINECALLDICT // price vote_dict phash rest public_key stored_seqno cfg_dict _121 + s0 s4 XCHG2 // price vote_dict phash cfg_dict public_key stored_seqno _121 rest + STSLICER // price vote_dict phash cfg_dict public_key stored_seqno _122 + s0 s4 s5 XCHG3 + 8 PUSHPOW2 // price public_key stored_seqno cfg_dict _122 phash vote_dict _123=256 + DICTUSETB // price public_key stored_seqno cfg_dict vote_dict + s1 s3 XCHG // price cfg_dict stored_seqno public_key vote_dict + store_data INLINECALLDICT + }> // msg_value max_tot_rounds proposal critical? price pps expire_at cfg_dict stored_seqno public_key vote_dict phash pstatus + DROP + s6 POP // msg_value max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vote_dict + s10 s6 XCPU // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key msg_value price + SUB // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key _126 + 30 PUSHPOW2 // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key _126 _129 + LESS // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key _130 + IFJMP:<{ // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key + 10 BLKDROP // + -4032919844 PUSHINT // _131=-4032919844 + }> // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key + get_current_vset INLINECALLDICT // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key _191 _192 _193 + DROP // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vset total_weight + 3 PUSHINT // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vset total_weight _138=3 + 1 LSHIFT#DIV // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vset _139 + INC // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vset weight_remaining + 0 PUSHINT // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vset weight_remaining _143=0 + PUSHNULL // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key vset weight_remaining _143=0 _144 + s0 s3 XCHG // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key _144 weight_remaining _143=0 vset + HASHCU // vote_dict max_tot_rounds proposal critical? price phash expire_at cfg_dict stored_seqno public_key _144 weight_remaining _143=0 _145 + s5 s7 XCHG + s4 s11 XCHG + s1 s10 XCHG + s3 s3 s0 XCHG3 // vote_dict max_tot_rounds public_key _143=0 price phash stored_seqno cfg_dict expire_at proposal critical? _144 weight_remaining _145 + begin_pack_proposal_status INLINECALLDICT // vote_dict max_tot_rounds public_key _143=0 price phash stored_seqno cfg_dict _146 + s1 s7 XCHG // vote_dict cfg_dict public_key _143=0 price phash stored_seqno max_tot_rounds _146 + 8 STU // vote_dict cfg_dict public_key _143=0 price phash stored_seqno _148 + s1 s4 XCHG // vote_dict cfg_dict public_key stored_seqno price phash _143=0 _148 + 16 STU // vote_dict cfg_dict public_key stored_seqno price phash _150 + s0 s1 s6 XCHG3 + 8 PUSHPOW2 // price cfg_dict public_key stored_seqno _150 phash vote_dict _151=256 + DICTUSETB // price cfg_dict public_key stored_seqno vote_dict + s1 s2 XCHG // price cfg_dict stored_seqno public_key vote_dict + store_data INLINECALLDICT + }> + recv_internal PROC:<{ + // msg_value in_msg_cell in_msg + SWAP // msg_value in_msg in_msg_cell + CTOS // msg_value in_msg cs + 4 LDU // msg_value in_msg flags cs + LDMSGADDR // msg_value in_msg flags s_addr cs + OVER // msg_value in_msg flags s_addr cs s_addr + REWRITESTDADDR // msg_value in_msg flags s_addr cs src_wc src_addr + SWAP // msg_value in_msg flags s_addr cs src_addr src_wc + INC // msg_value in_msg flags s_addr cs src_addr _16 + s0 s4 XCHG + 1 PUSHINT // msg_value in_msg _16 s_addr cs src_addr flags _17=1 + AND // msg_value in_msg _16 s_addr cs src_addr _18 + s1 s4 XCHG // msg_value in_msg src_addr s_addr cs _16 _18 + OR // msg_value in_msg src_addr s_addr cs _19 + s4 PUSH // msg_value in_msg src_addr s_addr cs _19 in_msg + SEMPTY // msg_value in_msg src_addr s_addr cs _19 _20 + OR // msg_value in_msg src_addr s_addr cs _21 + IFJMP:<{ // msg_value in_msg src_addr s_addr cs + 5 BLKDROP // + }> // msg_value in_msg src_addr s_addr cs + s0 s3 XCHG // msg_value cs src_addr s_addr in_msg + 32 LDU // msg_value cs src_addr s_addr tag in_msg + 64 LDU // msg_value cs src_addr s_addr tag query_id in_msg + s2 PUSH + 1314280276 PUSHINT // msg_value cs src_addr s_addr tag query_id in_msg tag _30=1314280276 + EQUAL // msg_value cs src_addr s_addr tag query_id in_msg _31 + IFJMP:<{ // msg_value cs src_addr s_addr tag query_id in_msg + s2 POP + s4 POP + s4 POP // in_msg query_id src_addr s_addr + s0 s3 XCHG // s_addr query_id src_addr in_msg + LDREF // s_addr query_id src_addr vset in_msg + ENDS + 1 PUSHINT // s_addr query_id src_addr vset _37=1 + CONFIGOPTPARAM // s_addr query_id src_addr vset elector_param + DUP // s_addr query_id src_addr vset elector_param elector_param + ISNULL // s_addr query_id src_addr vset elector_param _40 + IF:<{ // s_addr query_id src_addr vset elector_param + DROP // s_addr query_id src_addr vset + -1 PUSHINT // s_addr query_id src_addr vset _41=-1 + }>ELSE<{ // s_addr query_id src_addr vset elector_param + CTOS // s_addr query_id src_addr vset _43 + 256 PLDU // s_addr query_id src_addr vset _41 + }> // s_addr query_id src_addr vset elector_addr + s0 s2 XCHG + FALSE + s0 s3 XCHG // s_addr query_id ok vset src_addr elector_addr + EQUAL // s_addr query_id ok vset _48 + IF:<{ // s_addr query_id ok vset + NIP // s_addr query_id vset + DUP // s_addr query_id vset vset + check_validator_set CALLDICT // s_addr query_id vset t_since t_until + NOW // s_addr query_id vset t_since t_until t + s2 s(-1) PUXC // s_addr query_id vset t_since t_until t_since t + GREATER // s_addr query_id vset t_since t_until _54 + s0 s2 XCHG // s_addr query_id vset _54 t_until t_since + GREATER // s_addr query_id vset _54 _55 + AND // s_addr query_id vset ok + SWAP // s_addr query_id ok vset + }> // s_addr query_id ok vset + SWAP // s_addr query_id vset ok + IFJMP:<{ // s_addr query_id vset + 36 PUSHINT // s_addr query_id vset _57=36 + SWAP // s_addr query_id _57=36 vset + set_conf_param CALLDICT + 4000730955 PUSHINT // s_addr query_id _59=4000730955 + send_confirmation INLINECALLDICT + }> // s_addr query_id vset + DROP // s_addr query_id + 4000730991 PUSHINT // s_addr query_id _61=4000730991 + send_error INLINECALLDICT + }> // msg_value cs src_addr s_addr tag query_id in_msg + DROP + s3 POP // msg_value cs query_id s_addr tag + DUP + 1851150418 PUSHINT // msg_value cs query_id s_addr tag tag _63=1851150418 + EQUAL // msg_value cs query_id s_addr tag _64 + IFJMP:<{ // msg_value cs query_id s_addr tag + DROP // msg_value cs query_id s_addr + s2 s3 XCHG2 // s_addr query_id cs msg_value + register_voting_proposal INLINECALLDICT // s_addr query_id price + 64 PUSHINT // s_addr query_id price mode=64 + OVER // s_addr query_id price mode=64 price + NEGATE // s_addr query_id price mode=64 ans_tag + s2 PUSH // s_addr query_id price mode=64 ans_tag price + -1 GTINT // s_addr query_id price mode=64 ans_tag _72 + IF:<{ // s_addr query_id price mode=64 ans_tag + 2DROP // s_addr query_id price + 4 PUSHINT // s_addr query_id price _73=4 + RAWRESERVE + 3998634066 PUSHINT // s_addr query_id ans_tag=3998634066 + 7 PUSHPOW2 // s_addr query_id ans_tag=3998634066 mode=128 + }>ELSE<{ + s2 POP // s_addr query_id ans_tag mode + }> + send_answer CALLDICT + }> // msg_value cs query_id s_addr tag + 4 1 BLKDROP2 // tag + DUP // tag tag + 0 EQINT // tag _80 + SWAP + 31 PUSHPOW2 // _80 tag _83 + AND // _80 _84 + OR // _85 + 37 THROWIFNOT + }> recv_external PROC:<{ // in_msg 9 PUSHPOW2 // in_msg _3=512 @@ -429,15 +750,19 @@ PROGRAM{ s1 s2 XCHG // signature in_msg action msg_seqno cs valid_until _19 LESS // signature in_msg action msg_seqno cs _20 35 THROWIF + DUP // signature in_msg action msg_seqno cs cs + SDEPTH // signature in_msg action msg_seqno cs _23 + 64 GTINT // signature in_msg action msg_seqno cs _25 + 39 THROWIF load_data INLINECALLDICT // signature in_msg action msg_seqno cs cfg_dict stored_seqno public_key vote_dict s5 s2 XCPU // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key msg_seqno stored_seqno - EQUAL // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _28 + EQUAL // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _33 33 THROWIFNOT s5 PUSH - 1450144869 PUSHINT // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key action _30=1450144869 - SUB // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _31 - -2 PUSHINT // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _31 _32=-2 - AND // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _33 + 1450144869 PUSHINT // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key action _35=1450144869 + SUB // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _36 + -2 PUSHINT // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _36 _37=-2 + AND // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key _38 IFNOTJMP:<{ // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key s0 s3 XCHG // signature in_msg action vote_dict public_key cfg_dict stored_seqno cs 16 LDU // signature in_msg action vote_dict public_key cfg_dict stored_seqno idx cs @@ -446,9 +771,9 @@ PROGRAM{ SWAP // signature in_msg action vote_dict public_key cfg_dict stored_seqno idx cs total_weight vdescr unpack_validator_descr INLINECALLDICT // signature in_msg action vote_dict public_key cfg_dict stored_seqno idx cs total_weight val_pubkey weight s0 s10 XCHG // signature weight action vote_dict public_key cfg_dict stored_seqno idx cs total_weight val_pubkey in_msg - HASHSU // signature weight action vote_dict public_key cfg_dict stored_seqno idx cs total_weight val_pubkey _45 - s0 s11 s11 XCHG3 // total_weight weight action vote_dict public_key cfg_dict stored_seqno idx cs _45 signature val_pubkey - CHKSIGNU // total_weight weight action vote_dict public_key cfg_dict stored_seqno idx cs _46 + HASHSU // signature weight action vote_dict public_key cfg_dict stored_seqno idx cs total_weight val_pubkey _50 + s0 s11 s11 XCHG3 // total_weight weight action vote_dict public_key cfg_dict stored_seqno idx cs _50 signature val_pubkey + CHKSIGNU // total_weight weight action vote_dict public_key cfg_dict stored_seqno idx cs _51 34 THROWIFNOT ACCEPT s0 s2 XCHG // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno @@ -457,23 +782,27 @@ PROGRAM{ s8 PUSH // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno cfg_dict stored_seqno public_key vote_dict store_data INLINECALLDICT COMMIT - 34 PUSHINT // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _54=34 - CONFIGOPTPARAM // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _55 - HASHCU // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _56 + s2 PUSH + 10 PUSHPOW2 // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno cs _61=1024 + SDATASIZE // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _104 _105 _106 + 3 BLKDROP // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno + 34 PUSHINT // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _64=34 + CONFIGOPTPARAM // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _65 + HASHCU // total_weight weight action vote_dict public_key cfg_dict cs idx stored_seqno _66 s5 s7 XCHG s3 s4 XCHG s2 s3 XCHG - s8 s9 s0 XCHG3 // stored_seqno cfg_dict public_key vote_dict action cs idx weight total_weight _56 + s8 s9 s0 XCHG3 // stored_seqno cfg_dict public_key vote_dict action cs idx weight total_weight _66 register_vote CALLDICT // stored_seqno cfg_dict public_key vote_dict accepted s3 s4 s2 PUSH3 s4 PUSH // stored_seqno cfg_dict public_key vote_dict accepted cfg_dict stored_seqno public_key vote_dict store_data INLINECALLDICT DUP // stored_seqno cfg_dict public_key vote_dict accepted accepted - ISNULL // stored_seqno cfg_dict public_key vote_dict accepted _59 + ISNULL // stored_seqno cfg_dict public_key vote_dict accepted _69 IFNOT:<{ // stored_seqno cfg_dict public_key vote_dict accepted - 32 LDU // stored_seqno cfg_dict public_key vote_dict _60 accepted + 32 LDU // stored_seqno cfg_dict public_key vote_dict _70 accepted s3 s4 XCHG - s2 s4 XCHG // stored_seqno vote_dict cfg_dict public_key _60 accepted + s2 s4 XCHG // stored_seqno vote_dict cfg_dict public_key _70 accepted perform_action CALLDICT // stored_seqno vote_dict cfg_dict public_key s3 s0 s3 XCHG3 // cfg_dict stored_seqno public_key vote_dict store_data INLINECALLDICT @@ -482,9 +811,9 @@ PROGRAM{ }> }> // signature in_msg action vote_dict cs cfg_dict stored_seqno public_key s0 s6 XCHG // signature public_key action vote_dict cs cfg_dict stored_seqno in_msg - HASHSU // signature public_key action vote_dict cs cfg_dict stored_seqno _66 - s0 s7 s6 XC2PU // stored_seqno public_key action vote_dict cs cfg_dict _66 signature public_key - CHKSIGNU // stored_seqno public_key action vote_dict cs cfg_dict _67 + HASHSU // signature public_key action vote_dict cs cfg_dict stored_seqno _76 + s0 s7 s6 XC2PU // stored_seqno public_key action vote_dict cs cfg_dict _76 signature public_key + CHKSIGNU // stored_seqno public_key action vote_dict cs cfg_dict _77 34 THROWIFNOT ACCEPT s0 s5 XCHG // cfg_dict public_key action vote_dict cs stored_seqno diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.cpp b/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.cpp index 77cfbf739e..0fe6b23614 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.cpp +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.cpp @@ -1 +1 @@ -with_tvm_code("dns-auto", "te6ccgECLgEABhoAART/APSkE/S88sgLAQIBIAIDAgFIBAUBIvIw2zwxmPgAhB/4I/AD4V8ELQICzQYHAgEgGRoCASAICQIBIBMUAvdCDXScEgkl8D4AHQ0wMBcbCSXwPg+kAwIPpEA9MfIZJfBuFwIddJwj+UMNM/Ad5UFAJvA/hhIIMesJJfBeAgqxfAQ46ENFnbPOAgghByZWdkuiGCEHByb2y6qgCgIYIQdXBkZLqqAaABghBnb2djuqoCoCCWXwWEH/AF4YCgsARVAm8kCMjMF/QAFfQAyx1QA/oCUAP6AlAD+gISyx/LH8ntVIA/bbPCXQ0gcKvQnT/zBQCL0YsZpfCIIQ7m93bvAF4CeCEENoUHK6jhcwNgLTH/oA+gD6ANFvBEBEBQPwA3DwBuA0NAWCEENEZWy6jq8kbpJfBZYEA3F/8Afi2zwQRV8FbpiCEO50ZW3wBeH4QW8jghDva2F5WXCBAKDwBOAtLQwD/qPbPCbACI4ZMDU1NjYD0h8wEDUQNHEB8AeCEO9rYXnwBeAI9AQhbpsx0wUhwAACqgLXGJ0B0CDXSwGm+ICHsLEC4iKZMiB41yLXCwcC3wKaXwyCEO5vXDDwBeD4I20gcFRwBCDXSak2AorkMAHCBJtfD1uCEO92XDDwBeAswwEtDQ4ADF8FhB/wBQCEbTbTBwHAAFEzoQOONDMi10lScNcj+QKrH1MMgQDg9A5voY4ZbBLTH1MXvp3U0X4BgBD0DZE1kTDikTDiAZEw4gPeBP4kBE8TEREB2zwglQ5fDvAF4DApwwKOPQPUMCBujjV+IYAQ9A2OFdAg10mBARu+8p/XCxKCCAT+nLryn5Ew4iCAEPSEb6VsISGAEPSMb6VsIbDyn9+SMyLiJW8kI5xfD18DghDTT0ZG8AXhJBA3Wds8K8MEFbAUoA6DHaEuuYrgDyoQEQCsBG5SQLCYXwSCEO5vdGbgIm6ZXwOCEO5vLTKw4DOCEOJhZDIC0CDXSYEBG7mUECNfA+DTEgGCCAT+nL2UECNfA+BsEtIH1wv/Ar0CvbGWghDub3du4HAAFF8OghDncjxw8AUB4CnAAo5FMzhRd6BSgLyaXwuCEPNlcm/wBeBTdqDIyx/MVCCVgQDg9EMGqt9QCKAEqt9SQKBQRIMH9FswyEBEgwf0QwNFVHHwB/AG4CnAAYrgA18DBsAEjhUGyMsfFcxQcoEA4PRDUFQTcfAH8AbgXwoSAHA5OQFuml8LghDhbHJl8AXhF6AgyMsfFsxUIISBAOD0QySq31AIscgCgwf0Q1BDtggVQwRx8AfwBgIBIBUWAgEgFxgARRwgBjIywVQB88WWPoCFctqE8sfyz8hwv+Syx+RMeLJAfsAgABc+EFvIxAjcIBA8ASAAJx0+wL4QW8jghDva2F5WXCDBvAEgAPE+CMipjxSQLYJUhC5k1vwA+AyJIMH9IZvpTKTURKwjlQzIqvfUwK5jj8wIqk431MGgQDg9A5voY4S1wsfI7uZUAaBAOD0WzAFkTDikVviUCSDB/RbMCCDB/SGb6UyIZMgq9+ShB/iBqWVRRUDcALiEDYQNFnoW/ADgAgEgGxwCASAfIAENuHWts8XwOCkCAUgdHgIZs7E2zwzEDREBNs8oICkqAQ2xZrbPF8DgKwIBWCEiAT26MM+CMS2zwDlF8EcG3hkn8z3wHXSSKVWYAQ9GrgMoKwIBWCMkAgFqJygCASAlJgEQq+74I9s8XwMrAQ2nhbZ4Jr4HKQEPp6W2eCBGvgcpAQ2nx7Z4Br4HKQIPpTG2eNhFtnkpKgAo7UTQ1DH0BDH0BDHTHfoA+gD6ADAAMAKAZPlBMgTXSaoAgQDAoBSgA6YCqAKooAH2IddLIXewsfJeIJZfA3BtIW3hInjXItcLB55wyFAEzxYTywfJ0AKmCN4gwAiWXwNwbSFt4O1E0NQx9AQwbX8lBKsCjjID0wcBwACOKCDXSVJg1yP5AqsfI4EA4PQOb6GOECDXCx8mvpYyMyLXSQORMOKRMOLeA+RsIjIgLAAsbpZfA3BtIW3g0x/UMCLAAFBD1yNDMAA07UTQ1PQE9ATTHfoA+gD6AFUwbwQB0x/THzA="); +with_tvm_code("dns-auto", "te6ccgECLgEABhcAART/APSkE/S88sgLAQIBIAIDAgFIBAUBIvIw2zwxmPgAhB/4I/AD4V8ELQICzQYHAgEgGRoCASAICQIBIBMUAvdCDXScEgkl8D4AHQ0wMBcbCSXwPg+kAwIPpEA9MfIZJfBuFwIddJwj+UMNM/Ad5UFAJvA/hhIIMesJJfBeAgqxfAQ46ENFnbPOAgghByZWdkuiGCEHByb2y6qgCgIYIQdXBkZLqqAaABghBnb2djuqoCoCCWXwWEH/AF4YCgsARVAm8kCMjMF/QAFfQAyx1QA/oCUAP6AlAD+gISyx/LH8ntVIA/bbPCXQ0gcKvQnT/zBQCL0YsZpfCIIQ7m93bvAF4CeCEENoUHK6jhcwNgLTH/oA+gD6ANFvBEBEBQPwA3DwBuA0NAWCEENEZWy6jq8kbpJfBZYEA3F/8Afi2zwQRV8FbpiCEO50ZW3wBeH4QW8jghDva2F5WXCBAKDwBOAtLQwD/qPbPCbACI4ZMDU1NjYD0h8wEDUQNHEB8AeCEO9rYXnwBeAI9AQhbpsx0wUhwAACqgLXGJ0B0CDXSwGm+ICHsLEC4iKZMiB41yLXCwcC3wKaXwyCEO5vXDDwBeD4I20gcFRwBCDXSak2AorkMAHCBJtfD1uCEO92XDDwBeAswwEtDQ4ADF8FhB/wBQCEbTbTBwHAAFEzoQOONDMi10lScNcj+QKrH1MMgQDg9A5voY4ZbBLTH1MXvp3U0X4BgBD0DZE1kTDikTDiAZEw4gPeBP4kBE8TEREB2zwglGzh8AXgMCnDAo49A9QwIG6ONX4hgBD0DY4V0CDXSYEBG77yn9cLEoIIBP6cuvKfkTDiIIAQ9IRvpWwhIYAQ9IxvpWwhsPKf35IzIuIlbyQjnF8PXwOCENNPRkbwBeEkEDdZ2zwrwwQVsBSgDoMdoS654wIpDyoQEQCsBG5SQLCYXwSCEO5vdGbgIm6ZXwOCEO5vLTKw4DOCEOJhZDIC0CDXSYEBG7mUECNfA+DTEgGCCAT+nL2UECNfA+BsEtIH1wv/Ar0CvbGWghDub3du4HAAFF8OghDncjxw8AUB3MACjkUzOFF3oFKAvJpfC4IQ82Vyb/AF4FN2oMjLH8xUIJWBAOD0Qwaq31AIoASq31JAoFBEgwf0WzDIQESDB/RDA0VUcfAH8AbgKcAB4wJsMQbABI4VBsjLHxXMUHKBAOD0Q1BUE3HwB/AG4F8KEgBwOTkBbppfC4IQ4WxyZfAF4RegIMjLHxbMVCCEgQDg9EMkqt9QCLHIAoMH9ENQQ7YIFUMEcfAH8AYCASAVFgIBIBcYAEUcIAYyMsFUAfPFlj6AhXLahPLH8s/IcL/kssfkTHiyQH7AIAAXPhBbyMQI3CAQPAEgACcdPsC+EFvI4IQ72theVlwgwbwBIADxPgjIqY8UkC2CVIQuZNb8APgMiSDB/SGb6Uyk1ESsI5UMyKr31MCuY4/MCKpON9TBoEA4PQOb6GOEtcLHyO7mVAGgQDg9FswBZEw4pFb4lAkgwf0WzAggwf0hm+lMiGTIKvfkoQf4gallUUVA3AC4hA2EDRZ6FvwA4AIBIBscAgEgHyABDbh1rbPF8DgpAgFIHR4CGbOxNs8MxA0RATbPKCApKgENsWa2zxfA4CsCAVghIgE9ujDPgjEts8A5RfBHBt4ZJ/M98B10kilVmAEPRq4DKCsCAVgjJAIBaicoAgEgJSYBEKvu+CPbPF8DKwENp4W2eCa+BykBD6eltnggRr4HKQELp8e2eNhjKQIPpTG2eNhFtnkpKgAo7UTQ1DH0BDH0BDHTHfoA+gD6ADAAMAKAZPlBMgTXSaoAgQDAoBSgA6YCqAKooAH2IddLIXewsfJeIJZfA3BtIW3hInjXItcLB55wyFAEzxYTywfJ0AKmCN4gwAiWXwNwbSFt4O1E0NQx9AQwbX8lBKsCjjID0wcBwACOKCDXSVJg1yP5AqsfI4EA4PQOb6GOECDXCx8mvpYyMyLXSQORMOKRMOLeA+RsIjIgLAAsbpZfA3BtIW3g0x/UMCLAAFBD1yNDMAA07UTQ1PQE9ATTHfoA+gD6AFUwbwQB0x/THzA="); diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.fif b/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.fif index ad75a7db5f..fa8340335f 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-auto-code.fif @@ -570,8 +570,7 @@ PROGRAM{ check_owner INLINECALLDICT // msg_value key lhk exp qt ctl domdata gc prices nhk in_msg domain n cat_table err DUP // msg_value key lhk exp qt ctl domdata gc prices nhk in_msg domain n cat_table err err IFJMP:<{ // msg_value key lhk exp qt ctl domdata gc prices nhk in_msg domain n cat_table err - s0 s14 XCHG - 14 BLKDROP // err + 14 1 BLKDROP2 // err send_error CALLDICT }> // msg_value key lhk exp qt ctl domdata gc prices nhk in_msg domain n cat_table err DROP // msg_value key lhk exp qt ctl domdata gc prices nhk in_msg domain n cat_table @@ -730,8 +729,7 @@ PROGRAM{ housekeeping CALLDICT send_ok CALLDICT }> // price key lhk exp qt ctl domdata gc prices nhk cat_table stdper n data - s0 s3 XCHG - 3 BLKDROP // price key lhk exp qt ctl domdata gc prices nhk data + 3 1 BLKDROP2 // price key lhk exp qt ctl domdata gc prices nhk data s0 s6 XCHG // price key lhk exp data ctl domdata gc prices nhk qt 4 EQINT // price key lhk exp data ctl domdata gc prices nhk _311 IFJMP:<{ // price key lhk exp data ctl domdata gc prices nhk @@ -928,8 +926,7 @@ PROGRAM{ getppb PROC:<{ // load_prices INLINECALLDICT // _5 _6 _7 _8 - s0 s3 XCHG - 3 BLKDROP // ppb + 3 1 BLKDROP2 // ppb }> calcprice PROC:<{ // domain val diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-manual-code.cpp b/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-manual-code.cpp index 898666a25b..a7d525879a 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-manual-code.cpp +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/dns-manual-code.cpp @@ -1 +1 @@ -with_tvm_code("dns-manual", "te6ccgECGAEAAswAART/APSkE/S88sgLAQIBIAIDAgFIBAUC6vLbPAWDCNcYIPkBAdMf0z/4I6ofUyC58mNTKoBA9A5voTHyYFKUuvKiVBNG+RDyo/gAItcLBcAzmDQBdtch0/8wjoVa2zxAA+IDgyWhyEAHgED0Q44aIIBA9JZvpWwSIJQwUwe53iCTMzUBkmwh4rPmbBXwBBESAgLFBgcCASAMDQIBzwgJAAiqgl8DAgFICgsAIdAmRlj4nln+X/+gB6AGT2qkAAUXwOAAFzI9ADJ0EEz9HDyoYAAXvZznaiaGmvmOuF/8AgEgDg8AEbs3PtRNDXCx+AP5ujDCHXSSCUXwNwbeEgd7DyXiJ41yLXCweecMhQBM8WE8sHydACpgjeIMAIlF8DcG3g2zwUXwQjcAOrApjTBwHAABOhAuQgbY6bXwMhyMsGJM8WydCECSIC2zwFpRWyIMEBFUMw5jM1IpRfBXBt4WwSxwCSfzLfAtdJpvkhgRFRAAFsAAkjEB4AKAEPRqABztRNDTH9M/0//0BPQE0QE0cFmOk9s8IMcBmyDXSpPUMNCSfzPi3iLmMDETBPbTBSHBCo4sIZEx4SHAAZcx0wfUAvsA4AHACY4U1CH7BO1DAtDtHu1TVGID8QaC8gDg8i3gcCLBFJQw0g8B3m1tJMEeit4kwRSOkSWECSPbPDMClTLHAPKjkVvi3iTAC44TNAL0BFAkgBD0bjAQI4QJWfABAeAkwAyK4DAUFRYXAIQxAtMAAcABk9QB0JjTBQGqAtcYAeIg10nCD/KmIHjXItcLB/JocFMR10mpNgKY0wcBwAASoQHkMMjLBgHPFsnQUAMAIFn0qG+lIJQC9AQwkjJt4gIAKDQDgBD0WpkQI4QJQETwAQGSMDHiAGYxIsAVnDL0BBAjhAlQQvABAeAiwBaYMgKECfRzMAHgMDIgwB+TMPQE4MAgkm0B4PIsbQE="); +with_tvm_code("dns-manual", "te6ccgECGAEAAswAART/APSkE/S88sgLAQIBIAIDAgFIBAUC6vLbPAWDCNcYIPkBAdMf0z/4I6ofUyC58mNTKoBA9A5voTHyYFKUuvKiVBNG+RDyo/gAItcLBcAzmDQBdtch0/8wjoVa2zxAA+IDgyWhyEAHgED0Q44aIIBA9JZvpWwSIJQwUwe53iCTMzUBkmwh4rPmbBXwBBESAgLFBgcCASAMDQIBzwgJAAiqgl8DAgFICgsAIdAmRlj4nln+X/+gB6AGT2qkAAUXwOAAFzI9ADJ0EEz9HDyoYAAXvZznaiaGmvmOuF/8AgEgDg8AEbs3PtRNDXCx+AP5ujDCHXSSCUXwNwbeEgd7DyXiJ41yLXCweecMhQBM8WE8sHydACpgjeIMAIlF8DcG3g2zwUXwQjcAOrApjTBwHAABOhAuQgbY6bXwMhyMsGJM8WydCECSIC2zwFpRWyIMEBFUMw5jM1IpRfBXBt4WwSxwCSfzLfAtdJpvkhgRFRAAFsAAkjEB4AKAEPRqABztRNDTH9M/0//0BPQE0QE0cFmOk9s8IMcBmyDXSpPUMNCSfzPi3iLmMDETBPbTBSHBCo4sIZEx4SHAAZcx0wfUAvsA4AHACY4U1CH7BO1DAtDtHu1TVGID8QaC8gDg8i3gcCLBFJQw0g8B3m1tJMEe4wAkwRSOkSWECSPbPDMClTLHAPKjkVvi3iTAC44TNAL0BFAkgBD0bjAQI4QJWfABAeAkwAzjAjAUFRYXAIQxAtMAAcABk9QB0JjTBQGqAtcYAeIg10nCD/KmIHjXItcLB/JocFMR10mpNgKY0wcBwAASoQHkMMjLBgHPFsnQUAMAIFn0qG+lIJQC9AQwkjJt4gIAKDQDgBD0WpkQI4QJQETwAQGSMDHiAGYxIsAVnDL0BBAjhAlQQvABAeAiwBaYMgKECfRzMAHgMDIgwB+TMPQE4MAgkm0B4PIsbQE="); diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.cpp b/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.cpp index fafe3fa48c..792d023665 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.cpp +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.cpp @@ -1 +1 @@ -with_tvm_code("elector-code", "te6ccgECUwEACr8AART/APSkE/S88sgLAQIBIAIDAgFIBAUAUaX//xh2omh6AnoCETdKrPgN+SBOKjgQ+At5ICz4DPkgcXgL+SB4DRhAAgLFBgcCASAKCwIBywgJACqqgjGCEE5Db2SCEM5Db2RZcIBA8AYCASASEwIBIDM0AgN6oAwNAgFuEBECAWoODwBCqyztRND0BSBukltw4PADECZfBoMH9A5voZP6ADCSMHDiACO4ftRND0BSBukjBwlNDXCx/igAh7qu1E0PQFIG6YMHBUcABtUxHg8ANthP+OJySDB/R+b6UgjhgC+gDTHzHTH9P/0//RbwRSEG8CUANvAgKRMuIBs+YwM4AG2wpXtRND0BSBukjBt4PADECZfBm2E/44bIoMH9H5vpSCdAvoAMFIQbwJQA28CApEy4gGz5jAxgADOz4DtRND0BDH0BDCDB/QOb6GT+gAwkjBw4oAIBIBQVAgEgJCUCASAWFwIBIB4fAgEgGBkCASAcHQL3AHQ0wMBcbCSXwPg+kAwIccAlDEB8BDgAdMfIcAAlFsB8BDg0z8ighBOc3RLupUyECPwC+A0IYIQR2V0JLqTE/AR4CGCEE5Db2S6jhdUUkTwEpaCEM5Db2SShB/iQDNwgEDwBuAhghDudk9LuiKCEO52T2+6UhCxiuAwM4BobACE7UTQ9AT0BPQE+gDTH9P/0YAAKMkMA8A8AIiCDHrCZhB9AM3CAQPAG4V8DACkBcj0ABT0ABL0AAH6Assfy//J7VSAAITQ0x/TH/oA+gD0BNIA0gDRgAgEgICECASAiIwArAbIyx8Vyx9QA/oCAfoC9ADKAMoAyYAAdIAP+DPQ0h/SH9If1wofgAEUcIAYyMsFUAfPFlj6AhXLahPLH8s/IcL/kssfkTHiyQH7AIAAZIIQ7m9FTFlwgEDwBoAIBICYnAgEgLS4CASAoKQIBICorACEghDzdEhMWYIQO5rKAHLwBoABHIIQTlZTVHCCAMT/yMsQFcv/gx36AhTLahPLHxLLP8zJcfsAgADMUxKDB/QOb6GU+gAwoJEw4sgB+gICgwf0Q4AH3CP6RO1E0PQEIW4EpBSxlxA1XwVw8AfgBNP/0x/TH9P/1AHQgwjXGQHRghBlTFB0yMsfUkDLH1Iwyx9SYMv/UiDL/8nQURX5EZcQaF8IcfAH4SGDD7mXEGhfCHbwB+AH8AMxDYIQO5rKAKEgqgsjuZcQvV8NcvAH4FEioICwA+FF1vZcQrF8Mc/AH4AyXEJtfC3DwB+BTa4MH9A5voSCfMPoAWaAB0z8x0/8wUoC9kTHilxCbXwt08AfgUwG5lxCbXwt18AfgIPKs+AD4I8hY+gLLHxTLHxbL/xjL/0A4gwf0QxBFQTAWcHDwBMj0AFjPFsntVCCTcPAI4FsCASAvMAIBIDEyAHEcCB/jiwkgwf0fG+lII4dAtP/0z8x+gDSANGUMVEzoJdUGIjwCgcD4lBDoAORMuIBs+YwMwG68ruAAmRwUwB/jjcmgwf0fG+lII4oAtP/0z8x+gDSANGUMVEzoI4RVHcIqYRRZqBSF6BLsPAKCQPiUFOgBJEy4gGz5jA1A7pTIbuw8rsSoAGhgAFcAYAg9GZvoZIwcOHTPzHT/zH0BPoA+gD0BDHRIMIAlBA08A2VMBAj8AziEoACjDIC+kRw+DPQ1wv/7UTQ9AQEpFq9sSFusZJfBODwAwVfBVIVvQSzFLGSXwPg+AABkVuOHfQE9AT6AEM08A5wyMoAE/QA9ABZoPoCAc8Wye1U4oAIBIDU2AgFITU4CASA3OAIBID0+AgEgOToCASA7PAClPABB/pEAaSxIcAAsZgFoBA1VRLwAuBTAoAg9A5voY4m0z/T//QE+gD6AAugBMjLPxPL//QAAfoCAfoCUAbPFlQgU4Ag9EOUMAWgAeIQNUFD8AKAA0wxIfpEAaSeMIIQ/////kATcIBA8Abg7UTQ9AT0BFAzgwf0Zm+hn18EghD////+QBNwgEDwBuE2BfoA0QHI9AAV9AABzxbJ7VSCEPlvcyRwgBjIywVQBM8WUAT6AhLLahLLH8s/yYBA+wCAAbxw+DMgbpNfBHDg0NcL/yP6RAGkAr2xk18DcOD4AAHUIfsEIMcAkl8EnAHQ7R7tUwHxBoLyAOJ/gAAMcIAIBID9AAgEgSUoANRwAo4TAm8iIW8QAm8RJKirDxK2CBKgWOQwMYAP3IAQ+DPQ0w/TDzHTD9FxtglwbX+OQSmDB/R8b6UgjjIC+gDTH9Mf0//T/9EDowTIy38Uyh9SQMv/ydBRGrYIyMsfE8v/y/9AFIEBoPRBA6RDE5Ey4gGz5jA0WLYIUwG5l18HbXBtUxHgbYrmMzSlXJJvEeRwIIrmNjZbIoEFCQwBkA4EBoPSSb6UgjiEB039RGbYIAdMfMdcL/wPTH9P/MdcL/0EwFG8EUAVvAgSSbCHisxQASAJvIgFvEASkU0i+jhBUZQbwFFMCvJRsIiICkTDikTTiUza+EwFewABSQ7kSsZdfBG1wbVMR4FMBpZJvEeRvEG8QcFMAbW2K5jQ0NDZSVbrysVBEQxNEA/4GbyIBbyRTHYMH9A5vofK9+gAx0z8x1wv/U5y5jl1ROqirD1JAtghRRKEkqjsuqQRRlaBRiaCCEI6BJ4ojkoBzkoBT4sjLB8sfUkDL/1Kgyz8jlBPL/wKRM+JUIqiAEPRDcCTIy/8ayz9QBfoCGMoAQBqDB/RDCBBFExSK4iGKRUZHAAYDXwMACkwA8AoKARCK4gSkJG4VF0gAAlsB9QB8AM0+CMluZNfCHDgcPgzbpRfCPAT4IAR+DPQ+gD6APoA0x/RU2G5lF8M8BPgBJRfC/AT4AaTXwpw4CMQSVEyUHfwFSDAACCzKwYQWxBKEDlN3fAEI44QMWxSyPQA9AABzxbJ7VTwE+HwBTL4IwGgpsQptgmAEPgz0IEsBqTwAYAi+DP5AFMBupNfB3DgIo4vUySAIPQOb6GOINMfMSDTH9P/MFAEuvK5+CNQA6DIyx9YzxZABIAg9EMCkxNfA+KSbCHif4rmIG6SMHCQ4gHwAn+BMANCAENch1wsPUnC2CFMToIASyMsHUjDLH8sfGMsPF8sPGss/E/QAyXD4M9DXC/9TGPAJCfQEcAv5AFBkoCmgyMsfGcsfEsv/FfQAUAP6AnD6AhbKAEA0gCD0QwLI9AD0APQAAc8Wye1UfwCWI4Ag9HxvpSCOPALTP9P/UxW6ji40A/QE+gD6ACirAlGZoVApoATIyz8Wy/8S9AAB+gIB+gJYzxZUIAWAIPRDA3ABkl8D4pEy4gGzAgEgT1ACASBRUgAZCFukltwlQH5AAG64oACVAHwAwVfBZNfA3DhAvQEUTGAIPQOb6GTXwRw4YBA1yHXC/+AIvgzIfAYgCT4M1jwGLGOE3DIygAS9AD0AAHPFsntVPAXMH/gXwNwgAHs8AF/jjIkgCD0fG+lII4jAtMfMPgju1MUvbCOFTFUFUTwDhSgVHYTVHNY8AIDUFRwAd6RMuIBs+YGXwZus4ADdDGAJPgzbpJbcOFx+DPQ1wv/+Cj6RAGkAr2xkltw4IAi+DMgbpNfA3Dg8AUwMgLQgCjXIdcLH/gjUROhXLmTXwZw4FyhwTyRMZEw4oAR+DPQ+gAwA6BSAqFwbRA0ECNwcPAEyPQA9AABzxbJ7VR/g"); +with_tvm_code("elector-code", "te6ccgECUAEACrEAART/APSkE/S88sgLAQIBIAIDAgFIBAUAUaX//xh2omh6AnoCETdKrPgN+SBOKjgQ+At5ICz4DPkgcXgL+SB4DRhAAgLFBgcCASAnKAIBywgJACqqgjGCEE5Db2SCEM5Db2RZcIBA8AYCASAvMAIBIAoLAgEgDA0CAUghIgIBIA4PAgEgFBUCASAQEQIBIBITAKU8AEH+kQBpLEhwACxmAWgEDVVEvAC4FMCgCD0Dm+hjibTP9P/9AT6APoAC6AEyMs/E8v/9AAB+gIB+gJQBs8WVCBTgCD0Q5QwBaAB4hA1QUPwAoADTDEh+kQBpJ4wghD////+QBNwgEDwBuDtRND0BPQEUDODB/Rmb6GfXwSCEP////5AE3CAQPAG4TYF+gDRAcj0ABX0AAHPFsntVIIQ+W9zJHCAGMjLBVAEzxZQBPoCEstqEssfyz/JgED7AIABvHD4MyBuk18EcODQ1wv/I/pEAaQCvbGTXwNw4PgAAdQh+wQgxwCSXwScAdDtHu1TAfEGgvIA4n+AAAxwgAgEgFhcCASAdHgA1HACjhMCbyIhbxACbxEkqKsPErYIEqBY5DAxgA/cgBD4M9DTD9MPMdMP0XG2CXBtf45BKYMH9HxvpSCOMgL6ANMf0x/T/9P/0QOjBMjLfxTKH1JAy//J0FEatgjIyx8Ty//L/0AUgQGg9EEDpEMTkTLiAbPmMDRYtghTAbmXXwdtcG1TEeBtiuYzNKVckm8R5HAgiuY2NlsigGBkaAGQDgQGg9JJvpSCOIQHTf1EZtggB0x8x1wv/A9Mf0/8x1wv/QTAUbwRQBW8CBJJsIeKzFABIAm8iAW8QBKRTSL6OEFRlBvAUUwK8lGwiIgKRMOKRNOJTNr4TAV7AAFJDuRKxl18EbXBtUxHgUwGlkm8R5G8QbxBwUwBtbYrmNDQ0NlJVuvKxUERDExsB/gZvIgFvJFMdgwf0Dm+h8r36ADHTPzHXC/9TnLmOXVE6qKsPUkC2CFFEoSSqOy6pBFGVoFGJoIIQjoEniiOSgHOSgFPiyMsHyx9SQMv/UqDLPyOUE8v/ApEz4lQiqIAQ9ENwJMjL/xrLP1AF+gIYygBAGoMH9EMIEEUTFJJsMeIcACAhlUwA8AoKkVviBKQkbhUXAfUAfADNPgjJbmTXwhw4HD4M26UXwjwE+CAEfgz0PoA+gD6ANMf0VNhuZRfDPAT4ASUXwvwE+AGk18KcOAjEElRMlB38BUgwAAgsysGEFsQShA5Td3wBCOOEDFsUsj0APQAAc8Wye1U8BPh8AUy+CMBoKbEKbYJgBD4M9CAfAac8AGAIvgz+QBTAbqTXwdw4CKOL1MkgCD0Dm+hjiDTHzEg0x/T/zBQBLryufgjUAOgyMsfWM8WQASAIPRDApMTXwPikmwh4n+K5iBukjBw3gHwAn+AgANCAENch1wsPUnC2CFMToIASyMsHUjDLH8sfGMsPF8sPGss/E/QAyXD4M9DXC/9TGPAJCfQEcAv5AFBkoCmgyMsfGcsfEsv/FfQAUAP6AnD6AhbKAEA0gCD0QwLI9AD0APQAAc8Wye1UfwCWI4Ag9HxvpSCOPALTP9P/UxW6ji40A/QE+gD6ACirAlGZoVApoATIyz8Wy/8S9AAB+gIB+gJYzxZUIAWAIPRDA3ABkl8D4pEy4gGzAgEgIyQCASAlJgAZCFukltwlQH5AAG64oACTAHwA2xRk18DcOEC9ARRMYAg9A5voZNfBHDhgEDXIdcL/4Ai+DMh8BiAJPgzWPAYsY4TcMjKABL0APQAAc8Wye1U8Bcwf+BfA3CAAeTwAX+OMiSAIPR8b6UgjiMC0x8w+CO7UxS9sI4VMVQVRPAOFKBUdhNUc1jwAgNQVHAB3pEy4gGz5mxhbrOAA3QxgCT4M26SW3Dhcfgz0NcL//go+kQBpAK9sZJbcOCAIvgzIG6TXwNw4PAFMDIC0IAo1yHXCx/4I1EToVy5k18GcOBcocE8kTGRMOKAEfgz0PoAMAOgUgKhcG0QNBAjcHDwBMj0APQAAc8Wye1Uf4AIDeqApKgIBbi0uAgFqKywAQqss7UTQ9AUgbpJbcODwAxAmXwaDB/QOb6GT+gAwkjBw4gAjuH7UTQ9AUgbpIwcJTQ1wsf4oAIe6rtRND0BSBumDBwVHAAbVMR4PADbYT/jickgwf0fm+lII4YAvoA0x8x0x/T/9P/0W8EUhBvAlADbwICkTLiAbPmMDOABtsKV7UTQ9AUgbpIwbeDwAxAmXwZthP+OGyKDB/R+b6UgnQL6ADBSEG8CUANvAgKRMuIBs+YwMYAAzs+A7UTQ9AQx9AQwgwf0Dm+hk/oAMJIwcOKACASAxMgIBIEFCAgEgMzQCASA7PAIBIDU2AgEgOToC9wB0NMDAXGwkl8D4PpAMCHHAJQxAfAQ4AHTHyHAAJRbAfAQ4NM/IoIQTnN0S7qVMhAj8AvgNCGCEEdldCS6kxPwEeAhghBOQ29kuo4XVFJE8BKWghDOQ29kkoQf4kAzcIBA8AbgIYIQ7nZPS7oighDudk9vulIQseMCMDOA3OAAhO1E0PQE9AT0BPoA0x/T/9GAACjJDAPAPACIggx6wmYQfQDNwgEDwBuFfAwApAXI9AAU9AAS9AAB+gLLH8v/ye1UgACE0NMf0x/6APoA9ATSANIA0YAIBID0+AgEgP0AAKwGyMsfFcsfUAP6AgH6AvQAygDKAMmAAHSAD/gz0NIf0h/SH9cKH4ABFHCAGMjLBVAHzxZY+gIVy2oTyx/LPyHC/5LLH5Ex4skB+wCAAGSCEO5vRUxZcIBA8AaACASBDRAIBIEpLAgEgRUYCASBHSAAhIIQ83RITFmCEDuaygBy8AaAARyCEE5WU1RwggDE/8jLEBXL/4Md+gIUy2oTyx8Syz/MyXH7AIAAzFMSgwf0Dm+hlPoAMKCRMOLIAfoCAoMH9EOAB9wj+kTtRND0BCFuBKQUsZcQNV8FcPAH4ATT/9Mf0x/T/9QB0IMI1xkB0YIQZUxQdMjLH1JAyx9SMMsfUmDL/1Igy//J0FEV+RGXEGhfCHHwB+Ehgw+5lxBoXwh28AfgB/ADMQ2CEDuaygChIKoLI7mXEL1fDXLwB+BRIqCBJAPhRdb2XEKxfDHPwB+AMlxCbXwtw8AfgU2uDB/QOb6EgnzD6AFmgAdM/MdP/MFKAvZEx4pcQm18LdPAH4FMBuZcQm18LdfAH4CDyrPgA+CPIWPoCyx8Uyx8Wy/8Yy/9AOIMH9EMQRUEwFnBw8ATI9ABYzxbJ7VQgk3DwCOBbAgEgTE0CASBOTwBxHAgf44sJIMH9HxvpSCOHQLT/9M/MfoA0gDRlDFRM6CXVBiI8AoHA+JQQ6ADkTLiAbPmMDMBuvK7gAJkcFMAf443JoMH9HxvpSCOKALT/9M/MfoA0gDRlDFRM6COEVR3CKmEUWagUhegS7DwCgkD4lBToASRMuIBs+YwNQO6UyG7sPK7EqABoYABXAGAIPRmb6GSMHDh0z8x0/8x9AT6APoA9AQx0SDCAJQQNPANlTAQI/AM4hKAAoQyAvpEcPgz0NcL/+1E0PQEBKRavbEhbrGSXwTg8ANsUVIVvQSzFLGSXwPg+AABkVuOHfQE9AT6AEM08A5wyMoAE/QA9ABZoPoCAc8Wye1U4oA=="); diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.fif b/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.fif index 7aa8ac2970..ff1ebda31a 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/elector-code.fif @@ -506,8 +506,7 @@ PROGRAM{ 4 BLKDROP // }> // query_id ok ds elect unpack_elect CALLDICT // query_id ok ds _63 _64 _65 _66 _67 _68 _69 - s0 s5 XCHG - 5 BLKDROP // query_id ok ds elect_at finished + 5 1 BLKDROP2 // query_id ok ds elect_at finished s1 s4 PUXC // finished ok ds elect_at elect_at query_id NEQ // finished ok ds elect_at _33 s0 s4 XCHG // _33 ok ds elect_at finished @@ -1073,8 +1072,7 @@ PROGRAM{ s1 s3 XCHG s1 s4 XCHG // credits members best_stake m frozen m_stake i tot_stake tot_weight vset l stake src_addr }>ELSE<{ - s0 s3 XCHG - 3 BLKDROP // credits members best_stake m frozen m_stake i tot_stake tot_weight vset l stake src_addr + 3 1 BLKDROP2 // credits members best_stake m frozen m_stake i tot_stake tot_weight vset l stake src_addr }> OVER // credits members best_stake m frozen m_stake i tot_stake tot_weight vset l stake src_addr stake IF:<{ // credits members best_stake m frozen m_stake i tot_stake tot_weight vset l stake src_addr @@ -1377,8 +1375,7 @@ PROGRAM{ // ds elect credits SWAP // ds credits elect unpack_elect CALLDICT // ds credits _44 _45 _46 _47 _48 _49 _50 - s0 s5 XCHG - 5 BLKDROP // ds credits elect_at finished + 5 1 BLKDROP2 // ds credits elect_at finished IFNOTJMP:<{ // ds credits elect_at 3 BLKDROP // FALSE // _11 @@ -1462,8 +1459,7 @@ PROGRAM{ SWAP // elect credits past_elect grams active_id active_hash id f NOT // elect credits past_elect grams active_id active_hash id _26 }> // elect credits past_elect grams active_id active_hash id - s0 s6 XCHG - 6 BLKDROP // id + 6 1 BLKDROP2 // id ISNULL // _27 NOT // _28 }> diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.cpp b/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.cpp index 4c55e58f32..7831989635 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.cpp +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.cpp @@ -1 +1 @@ -with_tvm_code("multisig", "te6ccgECKAEAA+YAART/APSkE/S88sgLAQIBIAIDAgFIBAUE3vIgxwCOgzDbPOCDCNcYIPkBAdMH2zwiwAAToVNxePQOb6EB2zwC8p9UGrv5EPKgBvQEIPkBAdMfURi68qrTP3BTAfAJAcIIAYMKvLHyaFMVgED0Dm+hIJgNpCDCCvJnDd/4I6ofU0C58mFUI6NTThweJB0CAswGBwIBIAoLAAPZhAIBSAgJAC1QKkItdJEqCTItdKlwLUAdAT8AnobBKABPQhbpEx4CBukTDgAdAg10rDAJrUAvAKyFjPFszJ4HHXI8gBzxb0AMmAIBIAwNAgEgEhMBFbvtltUDRwVSDbPIJwIBSA4PAgEgEBEBc7EddCDCNcYIPkBAdMHggHUxO1D2FMgePQOb6Hyn9cL/14x+RDyoK4B9AQhbpNbcTLg+QFY2zwBpAGAhAD2u2oDoAOgA+gIBegIR/ICA/IDdeU/4BWR6AADni2TAABWuGVdBANVmdqHsQAIBIBQVAgFIFhcBUbclW2eGJkZqRhAIHoHN9DHCTYRaQAAzGmHmLgBa4CYcC2/uHAt3dG4QHgGHtVmbZ4ar4G/tscaKInAIHo+N9KQRxGBaQAAxw0QQAhrkJLrgZPYTmQA54sqEAJAIHohgUiYcUiYcUiZcQDZiXMCL4JAeAgEgGBkCA5k4GhsBEawabZ4vgbYJQB4AFa35QQDMlXah7BhAAQ2pNs8FV8FgHgAVrdws4IBqsztQ9iACINs8AvJl+ABQQ3FDE9s87VQeJwSo2zwvrlMgsPJiErECpIIBhqD4AQWXAhEQAj4+MI6jAREQAQ/bPEDXePRDUxe5JoIgDhAAAAAAoCS8sPJpEL0QvAXiVBZbVHPnVhBT3Ns8VHEKVHq8HyUiIAAg7UTQ0x/TB9MH0z/0BPQE0QBIAY4aMNIAAfKj0wfTB1AD1wEg+QEF+QEVuvKkUAPgbCFwVCATBLjbPO1U+A9wJW5Tib6xmBBuEC1Qx18HjxswVCQDUE3bPFBVoEZQEEkQOksJU7nbPFBUFn/i+AAHgyWhjh0mgED0lm+lbBIglDBTArneIJY3OH85BwWSbCHis+YwBichIiMAYHCOKQPQgwjXGNMH9AQwUxZ49A5vofKl1wv/VEVE+RDypq5SILFSA70UoSNu5mwiMgKaUjC+jy5fA/gAkyLXSpgC0wfUAvsAAugycMjKAEAUgED0Q1MhePQOb6Ew2zyl2zxaePRDjhdxyMsAFMsHEssHWM8BWM8WQBOAQPRDAeIkJQEKipJfBuImAArT/9MHMAAMAcjL/8sHARQQRRA0QwDbPO1UJwAcyMsfywfLB8s/9AD0AMk="); +with_tvm_code("multisig", "te6ccgECKQEAA/oAART/APSkE/S88sgLAQIBIAIDAgFIBAUE2vIgxwCOgzDbPOCDCNcYIPkBAdMH2zwiwAAToVNxePQOb6Hyn9s8VBq6+RDyoAb0BCD5AQHTH1EYuvKq0z9wUwHwCgHCCAGDCryx8mhTFYBA9A5voSCYDqQgwgryZw7f+COqH1NAufJhVCOjU04eIR8gAgLMBgcCASAMDQIBIAgJAgFmCgsAA9GEAiPymAvHoHN9CYbZ5S7Z4BPHohwfIwAtAKkItdJEqCTItdKlwLUAdAT8ArobBKAATwhbpEx4CBukTDgAdAg10rDAJrUAvALyFjPFszJ4HHXI8gBzxb0AMmACASAODwIBIBQVARW77ZbVA0cFUg2zyCgCAUgQEQIBIBITAXOxHXQgwjXGCD5AQHTB4IB1MTtQ9hTIHj0Dm+h8p/XC/9eMfkQ8qCuAfQEIW6TW3Ey4PkBWNs8AaQBgJQA9rtqA6ADoAPoCAXoCEfyAgPyA3XlP+AXkegAA54tkwAAVrhlXQQDVZnah7EACASAWFwIBSBgZAVG3JVtnhiZGakYQCB6BzfQxwk2EWkAAMxph5i4AWuAmHAtv7hwLd3RuECEBhbVZm2eGq+Bv7bHGiiJwCB6PjfSkEcRgWkAAMcNEEAIa5CS64GT2E5kAOeLKhACQCB6IYFImHFImHFImXEA2YlzNiDAhAgEgGhsCA5k4HB0BEawabZ4vgbYJQCEAFa35QQDMlXah7BhAAQ2pNs8FV8FgIQAVrdws4IBqsztQ9iACINs8AvJl+ABQQ3FDE9s87VQhKAAK0//TBzAEpts8L65TILDyYhKxAqQls1McubAlgiAOEAAAAACgKLyw8mmCAYag+AEFlwIREAI+PjCOjREQH9s8QNd49EMQvQXiVBZbVHPnVhBT3Ns8VHEKVHq8IiMmJAAg7UTQ0x/TB9MH0z/0BPQE0QBIAY4aMNIAAfKj0wfTB1AD1wEg+QEF+QEVuvKkUAPgbCFwVCATAAwByMv/ywcE1ts87VT4D3AlblOJvrGYEG4QLVDHXwePGzBUJANQTds8UFWgRlAQSRA6SwlTuds8UFQWf+L4AAeDJaGOLCaAQPSWb6UglDBTA7neII4WODk5CNIAAZfTBzAW8AcFkTDifwgHBZJsMeKz5jAGKCUmJwBgcI4pA9CDCNcY0wf0BDBTFnj0Dm+h8qXXC/9URUT5EPKmrlIgsVIDvRShI27mbCIyAH5SML6OIF8D+ACTItdKmALTB9QC+wAC6DJwyMoAQBSAQPRDAvAHjhdxyMsAFMsHEssHWM8BWM8WQBOAQPRDAeIBII6KEEUQNEMA2zztVJJfBuIoABzIyx/LB8sHyz/0APQAyQ=="); diff --git a/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.fif b/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.fif index 14c6db1115..aaf4462474 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/auto/multisig-code.fif @@ -7,6 +7,7 @@ PROGRAM{ DECLPROC check_signatures DECLPROC recv_internal DECLPROC unpack_query_data + DECLPROC dec_flood DECLPROC try_init DECLPROC update_pending_queries DECLPROC calc_boc_size @@ -120,6 +121,20 @@ PROGRAM{ 0 PUSHINT // in_msg root_i _27=0 s0 s1 s2 XCPUXC // root_i _27=0 _28=0 in_msg }> + dec_flood PROC:<{ + // owner_infos creator_i + s0 s1 PUSH2 + 8 PUSHINT // owner_infos creator_i creator_i owner_infos _4=8 + DICTUGET + NULLSWAPIFNOT // owner_infos creator_i _15 _16 + DROP // owner_infos creator_i owner_info + unpack_owner_info INLINECALLDICT // owner_infos creator_i public_key flood + DEC // owner_infos creator_i public_key _11 + pack_owner_info INLINECALLDICT // owner_infos creator_i _12 + s0 s2 XCHG + 8 PUSHINT // _12 creator_i owner_infos _13=8 + DICTUSETB // owner_infos + }> try_init PROCREF:<{ // unpack_state INLINECALLDICT // wallet_id n k last_cleaned owner_infos pending_queries @@ -157,31 +172,22 @@ PROGRAM{ s0 s1 s4 XCHG3 64 PUSHINT // creator_i owner_infos _23 query_id pending_queries _24=64 DICTUSETB // creator_i owner_infos pending_queries - s2 s1 PUSH2 - 8 PUSHINT // creator_i owner_infos pending_queries creator_i owner_infos _28=8 - DICTUGET - NULLSWAPIFNOT // creator_i owner_infos pending_queries _56 _57 - DROP // creator_i owner_infos pending_queries owner_info - unpack_owner_info INLINECALLDICT // creator_i owner_infos pending_queries public_key flood - DEC // creator_i owner_infos pending_queries public_key _35 - pack_owner_info INLINECALLDICT // creator_i owner_infos pending_queries _36 - 2SWAP - 8 PUSHINT // pending_queries _36 creator_i owner_infos _37=8 - DICTUSETB // pending_queries owner_infos + s0 s2 XCHG // pending_queries owner_infos creator_i + dec_flood CALLDICT // pending_queries owner_infos }>ELSE<{ // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n - 1 PUSHINT // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n _40=1 - NEWC // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n _40=1 _41 - 1 STU // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n _43 - s1 s4 XCHG // pending_queries owner_infos msg query_id n cnt cnt_bits creator_i _43 - 8 STU // pending_queries owner_infos msg query_id n cnt cnt_bits _45 - s1 s2 XCHG // pending_queries owner_infos msg query_id n cnt_bits cnt _45 - 8 STU // pending_queries owner_infos msg query_id n cnt_bits _47 - ROT // pending_queries owner_infos msg query_id cnt_bits _47 n - STUX // pending_queries owner_infos msg query_id _48 - ROT // pending_queries owner_infos query_id _48 msg - STSLICER // pending_queries owner_infos query_id _49 + 1 PUSHINT // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n _29=1 + NEWC // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n _29=1 _30 + 1 STU // pending_queries owner_infos msg query_id creator_i cnt cnt_bits n _32 + s1 s4 XCHG // pending_queries owner_infos msg query_id n cnt cnt_bits creator_i _32 + 8 STU // pending_queries owner_infos msg query_id n cnt cnt_bits _34 + s1 s2 XCHG // pending_queries owner_infos msg query_id n cnt_bits cnt _34 + 8 STU // pending_queries owner_infos msg query_id n cnt_bits _36 + ROT // pending_queries owner_infos msg query_id cnt_bits _36 n + STUX // pending_queries owner_infos msg query_id _37 + ROT // pending_queries owner_infos query_id _37 msg + STSLICER // pending_queries owner_infos query_id _38 s0 s1 s3 XCHG3 - 64 PUSHINT // owner_infos _49 query_id pending_queries _50=64 + 64 PUSHINT // owner_infos _38 query_id pending_queries _39=64 DICTUSETB // owner_infos pending_queries SWAP // pending_queries owner_infos }> @@ -230,84 +236,84 @@ PROGRAM{ 8 PUSHINT // root_signature root_hash root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned root_i owner_infos _25=8 DICTUGET NULLSWAPIFNOT // root_signature root_hash root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned owner_info found? - SWAP // root_signature root_hash root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned found? owner_info - unpack_owner_info INLINECALLDICT // root_signature root_hash root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned found? public_key flood - s0 s2 XCHG // root_signature root_hash root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned flood public_key found? 31 THROWIFNOT - s10 s11 s11 XC2PU // public_key flood root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned root_hash root_signature public_key - CHKSIGNU // public_key flood root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned _33 + unpack_owner_info INLINECALLDICT // root_signature root_hash root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned public_key flood + s10 s11 s10 XC2PU // flood public_key root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned root_hash root_signature public_key + CHKSIGNU // flood public_key root_i in_msg wallet_id n k pending_queries owner_infos last_cleaned _33 32 THROWIFNOT - s0 s6 XCHG // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos in_msg - LDDICT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures in_msg - DUP // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures in_msg in_msg - HASHSU // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures in_msg hash - SWAP // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash in_msg - 32 LDU // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_wallet_id in_msg - s1 s8 XCPU // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash in_msg query_wallet_id wallet_id - EQUAL // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash in_msg _45 + s0 s6 XCHG // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos in_msg + LDDICT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures in_msg + DUP // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures in_msg in_msg + HASHSU // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures in_msg hash + SWAP // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash in_msg + 32 LDU // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_wallet_id in_msg + s1 s8 XCPU // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash in_msg query_wallet_id wallet_id + EQUAL // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash in_msg _45 42 THROWIFNOT - 64 LDU // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg - 0 PUSHINT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _53=0 - s0 s1 PUSH2 // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _53=0 _54=0 in_msg - calc_boc_size CALLDICT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg cnt bits - SWAP // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg bits cnt - 8 GTINT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg bits _58 + 64 LDU // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg + 0 PUSHINT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _53=0 + s0 s1 PUSH2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _53=0 _54=0 in_msg + calc_boc_size CALLDICT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg cnt bits + SWAP // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg bits cnt + 8 GTINT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg bits _58 SWAP - 11 PUSHPOW2 // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _58 bits _59=2048 - GREATER // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _58 _60 - OR // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _61 + 11 PUSHPOW2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _58 bits _59=2048 + GREATER // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _58 _60 + OR // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg _61 40 THROWIF s1 s5 PUSH2 - 64 PUSHINT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query_id pending_queries _65=64 + 64 PUSHINT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query_id pending_queries _65=64 DICTUGET - NULLSWAPIFNOT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? - DUP // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? found? - IFNOT:<{ // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? - s0 s13 XCHG // public_key found? root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood - INC // public_key found? root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood - DUP // public_key found? root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood flood - 10 GTINT // public_key found? root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood _71 + NULLSWAPIFNOT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? + DUP // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? found? + IFNOT:<{ // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? + s0 s14 XCHG // found? public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood + INC // found? public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood + DUP // found? public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood flood + 10 GTINT // found? public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query flood _71 39 THROWIF - s0 s13 XCHG // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? - }> // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? - NOW // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? _74 - 32 LSHIFT# // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? bound - s4 s0 PUSH2 // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? bound query_id bound - LESS // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? bound _78 + s0 s14 XCHG // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? + }> // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? + NOW // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? _74 + 32 LSHIFT# // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? bound + s4 s0 PUSH2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? bound query_id bound + LESS // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id in_msg query found? bound _78 33 THROWIF s3 s10 s2 XCPUXC - s4 s14 PUSH2 // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound in_msg n query found? root_i - unpack_query_data INLINECALLDICT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg - s15 PUSH // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg root_i - POW2 // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg mask - s2 s0 PUSH2 // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg mask cnt_bits mask - AND // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg mask _89 + s4 s14 PUSH2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound in_msg n query found? root_i + unpack_query_data INLINECALLDICT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg + s15 PUSH // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg root_i + POW2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg mask + s2 s0 PUSH2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg mask cnt_bits mask + AND // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt cnt_bits msg mask _89 34 THROWIF - s1 s2 XCHG // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt msg cnt_bits mask - OR // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt msg cnt_bits - s0 s2 XCHG // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt - INC // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt - 100000 PUSHINT // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _94=100000 + s1 s2 XCHG // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt msg cnt_bits mask + OR // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt msg cnt_bits + s0 s2 XCHG // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt + INC // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt + s5 PUSH // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt found? + NOT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _95 + s1 s12 PUSH2 // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _95 cnt k + LESS // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _95 _96 + AND // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _97 + s5 PUSH + 15461882265600 PUSHINT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _97 bound _102 + ADD // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _97 _103 + s8 PUSH // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _97 _103 query_id + GREATER // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _97 _104 + AND // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _105 + 41 THROWIF + 100000 PUSHINT // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id found? bound creator_i cnt_bits msg cnt _107=100000 SETGASLIMIT - s0 s5 XCHG // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i cnt_bits msg found? - IFNOT:<{ // public_key flood root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i cnt_bits msg - s1 16 s() XCHG - s0 s15 XCHG // cnt_bits msg root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i public_key flood - pack_owner_info INLINECALLDICT // cnt_bits msg root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i _97 + s0 s5 XCHG // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i cnt_bits msg found? + IFNOT:<{ // flood public_key root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i cnt_bits msg + s0 16 s() XCHG + s1 s15 XCHG // msg cnt_bits root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i public_key flood + pack_owner_info INLINECALLDICT // msg cnt_bits root_i last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound creator_i _110 s0 s13 s7 XCHG3 - 8 PUSHINT // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt _97 root_i owner_infos _98=8 - DICTUSETB // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos - s1 s7 PUSH2 // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos cnt k - LESS // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos _101 - s6 PUSH - 15461882265600 PUSHINT // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos _101 bound _106 - ADD // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos _101 _107 - s4 PUSH // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos _101 _107 query_id - GREATER // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos _101 _108 - AND // cnt_bits msg creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos _109 - 41 THROWIF + 8 PUSHINT // msg cnt_bits creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt _110 root_i owner_infos _111=8 + DICTUSETB // msg cnt_bits creator_i last_cleaned wallet_id n k pending_queries bound signatures hash query_id cnt owner_infos s11 s13 XCHG - s11 s12 XCHG s0 s5 XCHG // creator_i cnt_bits msg last_cleaned wallet_id n k pending_queries owner_infos signatures hash query_id cnt bound }>ELSE<{ s2 16 s() XCHG @@ -322,15 +328,15 @@ PROGRAM{ update_pending_queries INLINECALLDICT // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos s1 s0 s10 PUSH3 s10 s11 s12 PUSH3 // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos pending_queries owner_infos last_cleaned k n wallet_id - pack_state INLINECALLDICT // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos _112 + pack_state INLINECALLDICT // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos _114 c4 POP COMMIT 0 PUSHINT // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 s5 PUSH // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 signatures - ISNULL // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _117 - s8 s9 PUSH2 // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _117 cnt k - GEQ // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _117 _118 - OR // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _119 + ISNULL // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _119 + s8 s9 PUSH2 // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _119 cnt k + GEQ // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _119 _120 + OR // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 _121 IFNOT:<{ // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos need_save=0 DROP // creator_i cnt_bits msg last_cleaned wallet_id n k cnt bound signatures hash query_id pending_queries owner_infos s4 s0 s2 XCPUXC @@ -355,32 +361,44 @@ PROGRAM{ }> ACCEPT s0 s7 XCHG - 38 PUSHPOW2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound _128 + 38 PUSHPOW2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound _130 SUB // need_save pending_queries owner_infos last_cleaned wallet_id n k bound UNTIL:<{ s6 PUSH - 64 PUSHINT // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries _135=64 + 64 PUSHINT // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries _137=64 DICTUREMMIN - NULLSWAPIFNOT2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound _178 _180 _179 _181 - 1 2 BLKDROP2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f - DUP // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f f - IF:<{ // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f - DROP // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i - s0 s2 PUSH2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i i bound - LESS // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f - }> // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f - DUP // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f f - IF:<{ // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' i f - s7 POP + NULLSWAPIFNOT2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f + DUP // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f f + IF:<{ // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f + DROP // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i + s0 s3 PUSH2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i i bound + LESS // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f + }> // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f + DUP // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f f + IF:<{ // need_save pending_queries owner_infos last_cleaned wallet_id n k bound pending_queries' query i f s8 POP - -1 PUSHINT s9 POP + s9 POP // query i owner_infos f wallet_id n k bound pending_queries' + s0 s8 XCHG // pending_queries' i owner_infos f wallet_id n k bound query + 1 LDI // pending_queries' i owner_infos f wallet_id n k bound _142 query + SWAP // pending_queries' i owner_infos f wallet_id n k bound query _142 + IF:<{ // pending_queries' i owner_infos f wallet_id n k bound query + 8 LDU // pending_queries' i owner_infos f wallet_id n k bound _195 _194 + DROP // pending_queries' i owner_infos f wallet_id n k bound _146 + s1 s6 XCHG // pending_queries' i bound f wallet_id n k owner_infos _146 + dec_flood CALLDICT // pending_queries' i bound f wallet_id n k owner_infos + s0 s5 XCHG // pending_queries' i owner_infos f wallet_id n k bound + }>ELSE<{ + DROP // pending_queries' i owner_infos f wallet_id n k bound + }> // pending_queries last_cleaned owner_infos f wallet_id n k bound + -1 PUSHINT // pending_queries last_cleaned owner_infos f wallet_id n k bound need_save=-1 + s0 s8 XCHG s0 s7 XCHG s0 s5 XCHG // need_save=-1 pending_queries owner_infos last_cleaned wallet_id n k bound f }>ELSE<{ - 2 1 BLKDROP2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound f + 3 1 BLKDROP2 // need_save pending_queries owner_infos last_cleaned wallet_id n k bound f }> - NOT // need_save pending_queries owner_infos last_cleaned wallet_id n k bound _141 + NOT // need_save pending_queries owner_infos last_cleaned wallet_id n k bound _151 }> // need_save pending_queries owner_infos last_cleaned wallet_id n k bound DROP // need_save pending_queries owner_infos last_cleaned wallet_id n k s0 s6 XCHG // k pending_queries owner_infos last_cleaned wallet_id n need_save @@ -388,7 +406,7 @@ PROGRAM{ s4 s5 XCHG s3 s4 XCHG s3 s0 s0 XCHG3 // pending_queries owner_infos last_cleaned k n wallet_id - pack_state INLINECALLDICT // _142 + pack_state INLINECALLDICT // _152 c4 POP }>ELSE<{ 6 BLKDROP // @@ -561,8 +579,7 @@ PROGRAM{ NOT // mask pending_queries n a i _31 s1 s2 XCHG // mask pending_queries n i a _31 }> // mask pending_queries n i a - s0 s4 XCHG - 4 BLKDROP // a + 4 1 BLKDROP2 // a }> get_messages_unsigned_by_id PROC:<{ // id diff --git a/submodules/ton/tonlib-src/crypto/smartcont/config-code.fc b/submodules/ton/tonlib-src/crypto/smartcont/config-code.fc index 15c87b3833..5559ba2764 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/config-code.fc +++ b/submodules/ton/tonlib-src/crypto/smartcont/config-code.fc @@ -23,6 +23,25 @@ .end_cell()); } +;; [min_tot_rounds, max_tot_rounds, min_wins, max_losses, min_store_sec, max_store_sec, bit_price, cell_price] +_ parse_vote_config(cell c) inline { + var cs = c.begin_parse(); + throw_unless(44, cs~load_uint(8) == 0x36); + var res = [cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(8), cs~load_uint(32), cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)]; + cs.end_parse(); + return res; +} + +;; cfg_vote_setup#91 normal_params:^ConfigProposalSetup critical_params:^ConfigProposalSetup = ConfigVotingSetup; +_ get_vote_config(int critical?) inline_ref { + var cs = config_param(11).begin_parse(); + throw_unless(44, cs~load_uint(8) == 0x91); + if (critical?) { + cs~load_ref(); + } + return parse_vote_config(cs.preload_ref()); +} + (int, int) check_validator_set(cell vset) { var cs = vset.begin_parse(); throw_unless(9, cs~load_uint(8) == 0x12); ;; validators_ext#12 only @@ -37,56 +56,23 @@ () send_answer(addr, query_id, ans_tag, mode) impure { ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000 - send_raw_message(begin_cell().store_uint(0x18, 6).store_slice(addr).store_uint(0, 5 + 4 + 4 + 64 + 32 + 1 + 1).store_uint(ans_tag, 32).store_uint(query_id, 64).end_cell(), mode); + send_raw_message(begin_cell() + .store_uint(0x18, 6) + .store_slice(addr) + .store_uint(0, 5 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(ans_tag, 32) + .store_uint(query_id, 64) + .end_cell(), mode); } -() send_confirmation(addr, query_id, ans_tag) impure { +() send_confirmation(addr, query_id, ans_tag) impure inline { return send_answer(addr, query_id, ans_tag, 64); } -() send_error(addr, query_id, ans_tag) impure { +() send_error(addr, query_id, ans_tag) impure inline { return send_answer(addr, query_id, ans_tag, 64); } -() recv_internal(cell in_msg_cell, slice in_msg) impure { - var cs = in_msg_cell.begin_parse(); - var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool - var s_addr = cs~load_msg_addr(); - (int src_wc, int src_addr) = s_addr.parse_std_addr(); - if ((src_wc + 1) | (flags & 1) | in_msg.slice_empty?()) { - ;; source not in masterchain, or a bounced message, or a simple transfer - return (); - } - int tag = in_msg~load_uint(32); - int query_id = in_msg~load_uint(64); - if (tag == 0x4e565354) { - ;; set next validator set - var vset = in_msg~load_ref(); - in_msg.end_parse(); - var elector_param = config_param(1); - var elector_addr = cell_null?(elector_param) ? -1 : elector_param.begin_parse().preload_uint(256); - var ok = false; - if (src_addr == elector_addr) { - ;; message from elector smart contract - ;; set next validator set - (var t_since, var t_until) = check_validator_set(vset); - var t = now(); - ok = (t_since > t) & (t_until > t_since); - } - if (ok) { - set_conf_param(36, vset); - ;; send confirmation - return send_confirmation(s_addr, query_id, 0xee764f4b); - } else { - return send_error(s_addr, query_id, 0xee764f6f); - } - } - ;; if tag is non-zero and its higher bit is zero, throw an exception (the message is an unsupported query) - ;; to bounce message back to sender - throw_unless(37, (tag == 0) | (tag & (1 << 31))); - ;; do nothing for other internal messages -} - ;; forward a message to elector smart contract to make it upgrade its code () change_elector_code(slice cs) impure { var dest_addr = config_param(1).begin_parse().preload_uint(256); @@ -108,7 +94,7 @@ _ perform_action(cfg_dict, public_key, action, cs) { if (action == 0x43665021) { ;; change one configuration parameter - var param_index = cs~load_uint(32); + var param_index = cs~load_int(32); var param_value = cs~load_ref(); cs.end_parse(); cfg_dict~idict_set_ref(32, param_index, param_value); @@ -137,11 +123,8 @@ _ perform_action(cfg_dict, public_key, action, cs) { } } -(slice, int) get_validator_descr(int idx) inline_ref { +(cell, int, slice) get_current_vset() inline_ref { var vset = config_param(34); - if (vset.null?()) { - return (null(), 0); - } var cs = begin_parse(vset); ;; validators_ext#12 utime_since:uint32 utime_until:uint32 ;; total:(## 16) main:(## 16) { main <= total } { main >= 1 } @@ -149,6 +132,11 @@ _ perform_action(cfg_dict, public_key, action, cs) { throw_unless(40, cs~load_uint(8) == 0x12); cs~skip_bits(32 + 32 + 16 + 16); int total_weight = cs~load_uint(64); + return (vset, total_weight, cs); +} + +(slice, int) get_validator_descr(int idx) inline_ref { + var (vset, total_weight, cs) = get_current_vset(); var dict = begin_cell().store_slice(cs).end_cell(); var (value, _) = dict.udict_get?(16, idx); return (value, total_weight); @@ -163,6 +151,40 @@ _ perform_action(cfg_dict, public_key, action, cs) { return (cs~load_uint(256), cs~load_uint(64)); } +;; cfg_proposal#f3 param_id:int32 param_value:(Maybe ^Cell) if_hash_equal:(Maybe uint256) +;; c -> (param-id param-cell maybe-hash) +(int, cell, int) parse_config_proposal(cell c) inline_ref { + var cs = c.begin_parse(); + throw_unless(44, cs~load_int(8) == 0xf3 - 0x100); + var (id, val, hash) = (cs~load_int(32), cs~load_maybe_ref(), cs~load_int(1)); + if (hash) { + hash = cs~load_uint(256); + } else { + hash = -1; + } + cs.end_parse(); + return (id, val, hash); +} + +;; cfg_proposal_status#ce expires:uint32 proposal:^ConfigProposal is_critical:Bool +;; voters:(HashmapE 16 True) remaining_weight:int64 validator_set_id:uint256 +;; rounds_remaining:uint8 wins:uint8 losses:uint8 = ConfigProposalStatus; +(int, cell, int, cell, int, int, slice) unpack_proposal_status(slice cs) inline_ref { + throw_unless(44, cs~load_int(8) == 0xce - 0x100); + return (cs~load_uint(32), cs~load_ref(), cs~load_int(1), cs~load_dict(), cs~load_int(64), cs~load_uint(256), cs); +} + +builder begin_pack_proposal_status(int expires, cell proposal, int critical?, cell voters, int weight_remaining, int vset_id) inline { + return begin_cell() + .store_int(0xce - 0x100, 8) + .store_uint(expires, 32) + .store_ref(proposal) + .store_int(critical?, 1) + .store_dict(voters) + .store_int(weight_remaining, 64) + .store_uint(vset_id, 256); +} + (cell, int, int, slice) new_proposal(cs) inline { return (null(), 0, 0, cs); } @@ -210,6 +232,141 @@ builder pack_proposal(cell voters, int sum_weight, int vset_id, slice body) inli } } +int register_voting_proposal(slice cs, int msg_value) inline_ref { + var (expire_at, proposal, critical?) = (cs~load_uint(32), cs~load_ref(), cs~load_int(1)); + if (expire_at >> 30) { + expire_at -= now(); + } + var (param_id, param_val, hash) = parse_config_proposal(proposal); + if (hash >= 0) { + cell cur_val = config_param(param_id); + int cur_hash = null?(cur_val) ? 0 : cell_hash(cur_val); + if (cur_hash != hash) { + hash = -0xe2646356; ;; bad current value + } + } else { + var m_params = config_param(9); + var (_, found?) = m_params.idict_get?(32, param_id); + if (found?) { + hash = -0xcd506e6c; ;; cannot set mandatory parameter to null + } + } + if (param_val.cell_depth() >= 256) { + hash = -0xc2616456; ;; bad value + } + if (hash < -1) { + return hash; ;; return error if any + } + ifnot (critical?) { + var crit_params = config_param(10); + var (_, found?) = crit_params.idict_get?(32, param_id); + if (found?) { + hash = -0xc3726954; ;; trying to set a critical parameter without critical flag + } + } + if (hash < -1) { + return hash; + } + ;; obtain vote proposal configuration + var vote_cfg = get_vote_config(critical?); + var [min_tot_rounds, max_tot_rounds, min_wins, max_losses, min_store_sec, max_store_sec, bit_price, cell_price] = vote_cfg; + if (expire_at < min_store_sec) { + return -0xc5787069; ;; expired + } + expire_at = min(expire_at, max_store_sec); + ;; compute price + var (_, bits, refs) = compute_data_size(param_val, 1024); + var pps = bit_price * (bits + 1024) + cell_price * (refs + 2); + var price = pps * expire_at; + expire_at += now(); + var (cfg_dict, stored_seqno, public_key, vote_dict) = load_data(); + int phash = proposal.cell_hash(); + var (pstatus, found?) = vote_dict.udict_get?(256, phash); + if (found?) { + ;; proposal already exists; we can only extend it + var (expires, r_proposal, r_critical?, voters, weight_remaining, vset_id, rest) = unpack_proposal_status(pstatus); + if (r_critical? != critical?) { + return -0xc3726955; ;; cannot upgrade critical parameter to non-critical... + } + if (expires >= expire_at) { + return -0xc16c7245; ;; proposal already exists + } + ;; recompute price + price = pps * (expire_at - expires + 16384); + if (msg_value - price < (1 << 30)) { + return -0xf0617924; ;; need more money + } + ;; update expiration time + vote_dict~udict_set_builder(256, phash, begin_pack_proposal_status(expire_at, r_proposal, r_critical?, voters, weight_remaining, vset_id).store_slice(rest)); + store_data(cfg_dict, stored_seqno, public_key, vote_dict); + return price; + } + if (msg_value - price < (1 << 30)) { + return -0xf0617924; ;; need more money + } + ;; obtain current validator set data + var (vset, total_weight, _) = get_current_vset(); + int weight_remaining = muldiv(total_weight, 2, 3) + 1; + ;; create new proposal + vote_dict~udict_set_builder(256, phash, + begin_pack_proposal_status(expire_at, proposal, critical?, null(), weight_remaining, vset.cell_hash()) + .store_uint(max_tot_rounds, 8).store_uint(0, 16)); + store_data(cfg_dict, stored_seqno, public_key, vote_dict); + return price; +} + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + var s_addr = cs~load_msg_addr(); + (int src_wc, int src_addr) = s_addr.parse_std_addr(); + if ((src_wc + 1) | (flags & 1) | in_msg.slice_empty?()) { + ;; source not in masterchain, or a bounced message, or a simple transfer + return (); + } + int tag = in_msg~load_uint(32); + int query_id = in_msg~load_uint(64); + if (tag == 0x4e565354) { + ;; set next validator set + var vset = in_msg~load_ref(); + in_msg.end_parse(); + var elector_param = config_param(1); + var elector_addr = cell_null?(elector_param) ? -1 : elector_param.begin_parse().preload_uint(256); + var ok = false; + if (src_addr == elector_addr) { + ;; message from elector smart contract + ;; set next validator set + (var t_since, var t_until) = check_validator_set(vset); + var t = now(); + ok = (t_since > t) & (t_until > t_since); + } + if (ok) { + set_conf_param(36, vset); + ;; send confirmation + return send_confirmation(s_addr, query_id, 0xee764f4b); + } else { + return send_error(s_addr, query_id, 0xee764f6f); + } + } + if (tag == 0x6e565052) { + ;; new voting proposal + var price = register_voting_proposal(cs, msg_value); + int mode = 64; + int ans_tag = - price; + if (price >= 0) { + ;; ok, debit price + raw_reserve(price, 4); + ans_tag = 0xee565052; + mode = 128; + } + return send_answer(s_addr, query_id, ans_tag, mode); + } + ;; if tag is non-zero and its higher bit is zero, throw an exception (the message is an unsupported query) + ;; to bounce message back to sender + throw_unless(37, (tag == 0) | (tag & (1 << 31))); + ;; do nothing for other internal messages +} + () recv_external(slice in_msg) impure { var signature = in_msg~load_bits(512); var cs = in_msg; @@ -217,6 +374,7 @@ builder pack_proposal(cell voters, int sum_weight, int vset_id, slice body) inli int msg_seqno = cs~load_uint(32); var valid_until = cs~load_uint(32); throw_if(35, valid_until < now()); + throw_if(39, slice_depth(cs) > 64); var (cfg_dict, stored_seqno, public_key, vote_dict) = load_data(); throw_unless(33, msg_seqno == stored_seqno); ifnot ((action - 0x566f7465) & -2) { @@ -228,6 +386,7 @@ builder pack_proposal(cell voters, int sum_weight, int vset_id, slice body) inli stored_seqno += 1; store_data(cfg_dict, stored_seqno, public_key, vote_dict); commit(); + var (_, bits, refs) = cs.slice_compute_data_size(1024); (vote_dict, var accepted) = register_vote(vote_dict, action, cs, idx, weight, total_weight, config_param(34).cell_hash()); store_data(cfg_dict, stored_seqno, public_key, vote_dict); ifnot (accepted.null?()) { diff --git a/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif b/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif index fefc7e4625..8fc00c32ce 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/gen-zerostate.fif @@ -1,5 +1,7 @@ +#!/usr/bin/create-state -s "TonUtil.fif" include "Asm.fif" include +"Lists.fif" include def? $1 { @' $1 } { "" } cond constant suffix { suffix $+ } : +suffix @@ -199,6 +201,15 @@ smc1_addr config.minter_smc! 1000000000000 -17 of-cc 666666666666 239 of-cc cc+ config.to_mint! +( 0 1 9 10 12 14 15 16 17 18 20 21 22 23 24 25 28 34 ) config.mandatory_params! +( -1000 -1001 0 1 9 10 12 14 15 16 17 32 34 36 ) config.critical_params! + +// [ min_tot_rounds max_tot_rounds min_wins max_losses min_store_sec max_store_sec bit_price cell_price ] +// first for ordinary proposals, then for critical proposals +_( 2 3 2 2 1000000 10000000 GR$.001 GR$.2 ) +_( 4 7 4 2 5000000 20000000 GR$.002 GR$.8 ) +config.param_proposals_setup! + "validator-keys" +suffix +".pub" file>B { dup Blen } { 32 B| swap dup ."Validator public key = " Bx. cr 17 add-validator } while drop diff --git a/submodules/ton/tonlib-src/crypto/smartcont/multisig-code.fc b/submodules/ton/tonlib-src/crypto/smartcont/multisig-code.fc index 36e21a7b7f..243262b67e 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/multisig-code.fc +++ b/submodules/ton/tonlib-src/crypto/smartcont/multisig-code.fc @@ -66,6 +66,13 @@ _ unpack_owner_info(slice cs) inline_ref { return (root_i, 0, 0, in_msg); } +(cell, ()) dec_flood(cell owner_infos, int creator_i) { + (slice owner_info, var found?) = owner_infos.udict_get?(8, creator_i); + (int public_key, int flood) = unpack_owner_info(owner_info); + owner_infos~udict_set_builder(8, creator_i, pack_owner_info(public_key, flood - 1)); + return (owner_infos, ()); +} + () try_init() impure inline_ref { ;; first query without signatures is always accepted (int wallet_id, int n, int k, int last_cleaned, cell owner_infos, cell pending_queries) = unpack_state(); @@ -82,10 +89,7 @@ _ unpack_owner_info(slice cs) inline_ref { send_raw_message(msg~load_ref(), mode); } pending_queries~udict_set_builder(64, query_id, begin_cell().store_int(0, 1)); - - (slice owner_info, var found?) = owner_infos.udict_get?(8, creator_i); - (int public_key, int flood) = unpack_owner_info(owner_info); - owner_infos~udict_set_builder(8, creator_i, pack_owner_info(public_key, flood - 1)); + owner_infos~dec_flood(creator_i); } else { pending_queries~udict_set_builder(64, query_id, begin_cell() .store_uint(1, 1) @@ -123,8 +127,8 @@ _ unpack_owner_info(slice cs) inline_ref { last_cleaned -= last_cleaned == 0; (slice owner_info, var found?) = owner_infos.udict_get?(8, root_i); - (int public_key, int flood) = unpack_owner_info(owner_info); throw_unless(31, found?); + (int public_key, int flood) = unpack_owner_info(owner_info); throw_unless(32, check_signature(root_hash, root_signature, public_key)); cell signatures = in_msg~load_dict(); @@ -154,11 +158,12 @@ _ unpack_owner_info(slice cs) inline_ref { cnt_bits |= mask; cnt += 1; + throw_if(41, ~ found? & (cnt < k) & (bound + ((60 * 60) << 32) > query_id)); + set_gas_limit(100000); ifnot (found?) { owner_infos~udict_set_builder(8, root_i, pack_owner_info(public_key, flood)); - throw_if(41, (cnt < k) & (bound + ((60 * 60) << 32) > query_id)); } (pending_queries, owner_infos) = update_pending_queries(pending_queries, owner_infos, msg, query_id, creator_i, cnt, cnt_bits, n, k); @@ -178,12 +183,15 @@ _ unpack_owner_info(slice cs) inline_ref { bound -= (64 << 32); ;; clean up records expired more than 64 seconds ago int old_last_cleaned = last_cleaned; do { - var (pending_queries', i, _, f) = pending_queries.udict_delete_get_min(64); + var (pending_queries', i, query, f) = pending_queries.udict_delete_get_min(64); f~touch(); if (f) { f = (i < bound); } if (f) { + if (query~load_int(1)) { + owner_infos~dec_flood(query~load_uint(8)); + } pending_queries = pending_queries'; last_cleaned = i; need_save = -1; diff --git a/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc b/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc index ca8337e133..0b98eeb448 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc +++ b/submodules/ton/tonlib-src/crypto/smartcont/stdlib.fc @@ -42,8 +42,10 @@ int string_hash(slice s) asm "SHA256U"; int check_signature(int hash, slice signature, int public_key) asm "CHKSIGNU"; int check_data_signature(slice data, slice signature, int public_key) asm "CHKSIGNS"; -(int, int, int) compute_data_size(cell c, int max_cells) asm "CDATASIZE"; -(int, int, int) slice_compute_data_size(slice s, int max_cells) asm "SDATASIZE"; +(int, int, int) compute_data_size(cell c, int max_cells) impure asm "CDATASIZE"; +(int, int, int) slice_compute_data_size(slice s, int max_cells) impure asm "SDATASIZE"; +(int, int, int, int) compute_data_size?(cell c, int max_cells) asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; +(int, int, int, int) slice_compute_data_size?(cell c, int max_cells) asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; ;; () throw_if(int excno, int cond) impure asm "THROWARGIF"; @@ -62,6 +64,8 @@ cont bless(slice s) impure asm "BLESS"; int min(int x, int y) asm "MIN"; int max(int x, int y) asm "MAX"; +(int, int) minmax(int x, int y) asm "MINMAX"; +int abs(int x) asm "ABS"; slice begin_parse(cell c) asm "CTOS"; () end_parse(slice s) impure asm "ENDS"; diff --git a/submodules/ton/tonlib-src/crypto/smartcont/wallet-v2.fif b/submodules/ton/tonlib-src/crypto/smartcont/wallet-v2.fif index f01ca47e67..fd5f6ae749 100755 --- a/submodules/ton/tonlib-src/crypto/smartcont/wallet-v2.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/wallet-v2.fif @@ -9,9 +9,11 @@ true =: allow-bounce false =: force-bounce 3 =: send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors 60 =: timeout // external message expires in 60 seconds +variable extra-currencies +{ extra-currencies @ cc+ extra-currencies ! } : extra-cc+! begin-options - " [-n|-b] [-t] [-B ] [-C ] []" +cr +tab + " [-x *] [-n|-b] [-t] [-B ] [-C ] []" +cr +tab +"Creates a request to advanced wallet created by new-wallet-v2.fif, with private key loaded from file .pk " +"and address from .addr, and saves it into .boc ('wallet-query.boc' by default)" disable-digit-options generic-help-setopt @@ -19,6 +21,8 @@ begin-options "Clears bounce flag" option-help "b" "--force-bounce" { true =: force-bounce } short-long-option "Forces bounce flag" option-help + "x" "--extra" { $>xcc extra-cc+! } short-long-option-arg + "Indicates the amount of extra currencies to be transfered" option-help "t" "--timeout" { parse-int =: timeout } short-long-option-arg "Sets expiration timeout in seconds (" timeout (.) $+ +" by default)" option-help "B" "--body" { =: body-boc-file } short-long-option-arg @@ -38,7 +42,7 @@ true constant bounce $1 =: file-base $2 bounce parse-load-address force-bounce or allow-bounce and =: bounce 2=: dest_addr $3 parse-int =: seqno -$4 $>GR =: amount +$4 $>cc extra-cc+! extra-currencies @ 2=: amount $5 "wallet-query" replace-if-null =: savefile file-base +".addr" load-address @@ -49,13 +53,13 @@ file-base +".pk" load-keypair nip constant wallet_pk def? body-boc-file { @' body-boc-file file>B B>boc } { comment simple-transfer-body } cond constant body-cell -."Transferring " amount .GR ."to account " +."Transferring " amount .GR+cc ."to account " dest_addr 2dup bounce 7 + .Addr ." = " .addr ."seqno=0x" seqno x. ."bounce=" bounce . cr ."Body of transfer message is " body-cell diff --git a/submodules/ton/tonlib-src/crypto/smartcont/wallet-v3.fif b/submodules/ton/tonlib-src/crypto/smartcont/wallet-v3.fif index 71618bb854..a81ffb0547 100644 --- a/submodules/ton/tonlib-src/crypto/smartcont/wallet-v3.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/wallet-v3.fif @@ -9,9 +9,11 @@ true =: allow-bounce false =: force-bounce 3 =: send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors 60 =: timeout // external message expires in 60 seconds +variable extra-currencies +{ extra-currencies @ cc+ extra-currencies ! } : extra-cc+! begin-options - " [-n|-b] [-t] [-B ] [-C ] []" +cr +tab + " [-x *] [-n|-b] [-t] [-B ] [-C ] []" +cr +tab +"Creates a request to advanced wallet created by new-wallet-v3.fif, with private key loaded from file .pk " +"and address from .addr, and saves it into .boc ('wallet-query.boc' by default)" disable-digit-options generic-help-setopt @@ -19,6 +21,8 @@ begin-options "Clears bounce flag" option-help "b" "--force-bounce" { true =: force-bounce } short-long-option "Forces bounce flag" option-help + "x" "--extra" { $>xcc extra-cc+! } short-long-option-arg + "Indicates the amount of extra currencies to be transfered" option-help "t" "--timeout" { parse-int =: timeout } short-long-option-arg "Sets expiration timeout in seconds (" timeout (.) $+ +" by default)" option-help "B" "--body" { =: body-boc-file } short-long-option-arg @@ -40,7 +44,7 @@ $1 =: file-base $2 bounce parse-load-address force-bounce or allow-bounce and =: bounce 2=: dest_addr $3 parse-int =: subwallet_id $4 parse-int =: seqno -$5 $>GR =: amount +$5 $>cc extra-cc+! extra-currencies @ 2=: amount $6 "wallet-query" replace-if-null =: savefile file-base +".addr" load-address @@ -51,14 +55,14 @@ file-base +".pk" load-keypair nip constant wallet_pk def? body-boc-file { @' body-boc-file file>B B>boc } { comment simple-transfer-body } cond constant body-cell -."Transferring " amount .GR ."to account " +."Transferring " amount .GR+cc ."to account " dest_addr 2dup bounce 7 + .Addr ." = " .addr ."subwallet_id=0x" subwallet_id x. ."seqno=0x" seqno x. ."bounce=" bounce . cr ."Body of transfer message is " body-cell diff --git a/submodules/ton/tonlib-src/crypto/smartcont/wallet.fif b/submodules/ton/tonlib-src/crypto/smartcont/wallet.fif index d752476d29..4c0cd37467 100755 --- a/submodules/ton/tonlib-src/crypto/smartcont/wallet.fif +++ b/submodules/ton/tonlib-src/crypto/smartcont/wallet.fif @@ -8,9 +8,11 @@ true =: allow-bounce false =: force-bounce 3 =: send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors +variable extra-currencies +{ extra-currencies @ cc+ extra-currencies ! } : extra-cc+! begin-options - " [-n|-b] [-B ] [-C ] []" +cr +tab + " [-x *] [-n|-b] [-B ] [-C ] []" +cr +tab +"Creates a request to simple wallet created by new-wallet.fif, with private key loaded from file .pk " +"and address from .addr, and saves it into .boc ('wallet-query.boc' by default)" disable-digit-options generic-help-setopt @@ -18,6 +20,8 @@ begin-options "Clears bounce flag" option-help "b" "--force-bounce" { true =: force-bounce } short-long-option "Forces bounce flag" option-help + "x" "--extra" { $>xcc extra-cc+! } short-long-option-arg + "Indicates the amount of extra currencies to be transfered" option-help "B" "--body" { =: body-boc-file } short-long-option-arg "Sets the payload of the transfer message" option-help "C" "--comment" { =: comment } short-long-option-arg @@ -35,7 +39,7 @@ true =: bounce $1 =: file-base $2 bounce parse-load-address allow-bounce and force-bounce or =: bounce 2=: dest_addr $3 parse-int =: seqno -$4 $>GR =: amount +$4 $>cc extra-cc+! extra-currencies @ 2=: amount $5 "wallet-query" replace-if-null =: savefile allow-bounce not force-bounce and abort"cannot have bounce flag both set and cleared" // "" 1 { 69091 * 1+ 65535 and tuck 2521 / 65 + hold swap } 1000 times drop =: comment @@ -48,13 +52,13 @@ file-base +".pk" load-keypair nip constant wallet_pk def? body-boc-file { @' body-boc-file file>B B>boc } { comment simple-transfer-body } cond constant body-cell -."Transferring " amount .GR ."to account " +."Transferring " amount .GR+cc ."to account " dest_addr 2dup bounce 7 + .Addr ." = " .addr ."seqno=0x" seqno x. ."bounce=" bounce . cr ."Body of transfer message is " body-cell diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.cpp b/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.cpp index 20750fcbad..202ff2dce2 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.cpp +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include "GenericAccount.h" @@ -96,4 +96,19 @@ td::Ref GenericAccount::create_ext_message(const block::StdAddress& ad return res; } +td::Result GenericAccount::get_public_key(const SmartContract& sc) { + auto answer = sc.run_get_method("get_public_key"); + if (!answer.success) { + return td::Status::Error("get_public_key failed"); + } + auto do_get_public_key = [&]() -> td::Result { + auto key = answer.stack.write().pop_int_finite(); + td::SecureString bytes(32); + if (!key->export_bytes(bytes.as_mutable_slice().ubegin(), bytes.size(), false)) { + return td::Status::Error("get_public_key failed"); + } + return td::Ed25519::PublicKey(std::move(bytes)); + }; + return TRY_VM(do_get_public_key()); +} } // namespace ton diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.h b/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.h index 003b8e1b76..27e43e25be 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/GenericAccount.h @@ -14,11 +14,14 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include "vm/cells.h" #include "block/block.h" +#include "Ed25519.h" +#include "SmartContract.h" + namespace ton { class GenericAccount { public: @@ -27,5 +30,7 @@ class GenericAccount { static td::Ref create_ext_message(const block::StdAddress& address, td::Ref new_state, td::Ref body) noexcept; static void store_int_message(vm::CellBuilder& cb, const block::StdAddress& dest_address, td::int64 gramms); + + static td::Result get_public_key(const SmartContract& sc); }; } // namespace ton diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWallet.h b/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWallet.h index e1db23efb0..68d3fe43c0 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWallet.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWallet.h @@ -26,7 +26,7 @@ #include "vm/cells/CellString.h" namespace ton { -class HighloadWallet : ton::SmartContract, public WalletInterface { +class HighloadWallet : public ton::SmartContract, public WalletInterface { public: explicit HighloadWallet(State state) : ton::SmartContract(std::move(state)) { } diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWalletV2.h b/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWalletV2.h index 2b6f99e7b0..975cf644ce 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWalletV2.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/HighloadWalletV2.h @@ -26,7 +26,7 @@ #include "vm/cells/CellString.h" namespace ton { -class HighloadWalletV2 : ton::SmartContract, public WalletInterface { +class HighloadWalletV2 : public ton::SmartContract, public WalletInterface { public: explicit HighloadWalletV2(State state) : ton::SmartContract(std::move(state)) { } diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.cpp b/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.cpp index 36ba273043..42a6ea8ad4 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.cpp +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.cpp @@ -44,7 +44,7 @@ td::Ref prepare_vm_stack(td::Ref body) { return stack_ref; } -td::Ref prepare_vm_c7() { +td::Ref prepare_vm_c7(td::uint32 now) { // TODO: fix initialization of c7 td::BitArray<256> rand_seed; rand_seed.as_slice().fill(0); @@ -54,7 +54,7 @@ td::Ref prepare_vm_c7() { td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea td::make_refint(0), // actions:Integer td::make_refint(0), // msgs_sent:Integer - td::make_refint(0), // unixtime:Integer + td::make_refint(now), // unixtime:Integer td::make_refint(0), // block_lt:Integer td::make_refint(0), // trans_lt:Integer std::move(rand_seed_int), // rand_seed:Integer @@ -166,8 +166,12 @@ td::Ref SmartContract::get_init_state() const { } SmartContract::Answer SmartContract::run_method(Args args) { + td::uint32 now = 0; + if (args.now) { + now = args.now.unwrap(); + } if (!args.c7) { - args.c7 = prepare_vm_c7(); + args.c7 = prepare_vm_c7(now); } if (!args.limits) { args.limits = vm::GasLimits{(long long)0, (long long)1000000, (long long)10000}; @@ -182,8 +186,12 @@ SmartContract::Answer SmartContract::run_method(Args args) { } SmartContract::Answer SmartContract::run_get_method(Args args) const { + td::uint32 now = 0; + if (args.now) { + now = args.now.unwrap(); + } if (!args.c7) { - args.c7 = prepare_vm_c7(); + args.c7 = prepare_vm_c7(now); } if (!args.limits) { args.limits = vm::GasLimits{1000000}; diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.h b/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.h index 24c2d13232..5bc70a4fe9 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/SmartContract.h @@ -55,6 +55,7 @@ class SmartContract : public td::CntObject { td::optional limits; td::optional> c7; td::optional> stack; + td::optional now; bool ignore_chksig{false}; Args() { @@ -62,6 +63,10 @@ class SmartContract : public td::CntObject { Args(std::initializer_list stack) : stack(td::Ref(true, std::vector(std::move(stack)))) { } + Args&& set_now(int now) { + this->now = now; + return std::move(*this); + } Args&& set_method_id(td::Slice method_name) { unsigned crc = td::crc16(method_name); return set_method_id((crc & 0xffff) | 0x10000); diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/Wallet.h b/submodules/ton/tonlib-src/crypto/smc-envelope/Wallet.h index 2299be7cca..459db7eaac 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/Wallet.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/Wallet.h @@ -26,7 +26,7 @@ #include "vm/cells/CellString.h" namespace ton { -class Wallet : ton::SmartContract, public WalletInterface { +class Wallet : public ton::SmartContract, public WalletInterface { public: explicit Wallet(State state) : ton::SmartContract(std::move(state)) { } diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.cpp b/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.cpp new file mode 100644 index 0000000000..aea899d339 --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.cpp @@ -0,0 +1,38 @@ +/* + This file is part of TON Blockchain Library. + + TON Blockchain Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + TON Blockchain Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with TON Blockchain Library. If not, see . + + Copyright 2017-2020 Telegram Systems LLP +*/ +#include "WalletInterface.h" + +namespace ton { +td::Result WalletInterfaceRaw::get_public_key() const { + auto sc = as_smart_constract(); + auto answer = sc.run_get_method("get_public_key"); + if (!answer.success) { + return td::Status::Error("get_public_key failed"); + } + auto do_get_public_key = [&]() -> td::Result { + auto key = answer.stack.write().pop_int_finite(); + td::SecureString bytes(32); + if (!key->export_bytes(bytes.as_mutable_slice().ubegin(), bytes.size())) { + return td::Status::Error("get_public_key failed"); + } + return td::Ed25519::PublicKey(std::move(bytes)); + }; + return TRY_VM(do_get_public_key()); +} +} // namespace ton diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.h b/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.h index 2c7760a1af..c8666f53a3 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/WalletInterface.h @@ -45,7 +45,7 @@ class WalletInterface { virtual td::Result> make_a_gift_message(const td::Ed25519::PrivateKey &private_key, td::uint32 valid_until, td::Span gifts) const = 0; virtual td::Result get_public_key() const { - return td::Status::Error("TODO"); + return td::Status::Error("Unsupported"); } td::Result> get_init_message(const td::Ed25519::PrivateKey &private_key, diff --git a/submodules/ton/tonlib-src/crypto/smc-envelope/WalletV3.h b/submodules/ton/tonlib-src/crypto/smc-envelope/WalletV3.h index b7c211ca54..c5cfead340 100644 --- a/submodules/ton/tonlib-src/crypto/smc-envelope/WalletV3.h +++ b/submodules/ton/tonlib-src/crypto/smc-envelope/WalletV3.h @@ -26,7 +26,7 @@ #include "vm/cells/CellString.h" namespace ton { -class WalletV3 : ton::SmartContract, public WalletInterface { +class WalletV3 : public ton::SmartContract, public WalletInterface { public: explicit WalletV3(State state) : ton::SmartContract(std::move(state)) { } diff --git a/submodules/ton/tonlib-src/crypto/test/fift/test-stack-copy.fif b/submodules/ton/tonlib-src/crypto/test/fift/test-stack-copy.fif new file mode 100644 index 0000000000..4fb10a34ee --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/test/fift/test-stack-copy.fif @@ -0,0 +1,20 @@ +#!/usr/bin/fift -s +"Asm.fif" include +2500 =: N +{ 5 * } : *K +N 100 / =: N/100 +N 10 / =: N/10 +{ { EXECUTE } 100 times } : 100EXECUTE +{ DUP { 2DUP } 7 times } : 15DUP +{ { 2DUP } 50 times } : 100DUP +{ { 15 -1 SETCONTARGS 15DUP } 10 times } : 10SET&DUP +<{ + CONT:<{ }> + 15DUP + N/10 INT REPEAT:<{ 10SET&DUP }> + N/100 *K INT REPEAT:<{ 100DUP }> + N/100 *K INT REPEAT:<{ 100EXECUTE }> +}>s =: Code + +Code csr. +Code 1000000 gasrunvmcode diff --git a/submodules/ton/tonlib-src/crypto/test/fift/testcc.fif b/submodules/ton/tonlib-src/crypto/test/fift/testcc.fif new file mode 100644 index 0000000000..4cbd781c3e --- /dev/null +++ b/submodules/ton/tonlib-src/crypto/test/fift/testcc.fif @@ -0,0 +1,32 @@ +#!/usr/bin/create-state -s +{ dup tlb-type-lookup { nip } { "unknown TLB type " swap $+ abort } cond } : $>tlb +{ bl word $>tlb 1 'nop } ::_ tlb: +{ dup null? { drop true } { + " } cond cr } : cshow +{ ."X = " over dup .cc space .cc-valid cr + ."Y = " dup dup .cc space .cc-valid cr + ."X + Y = " 2dup CC+? cshow + ."X - Y = " 2dup CC-? cshow + ."Y - X = " 2dup swap CC-? cshow + ."X + X = " over dup CC+? cshow + ."Y + Y = " dup dup CC+? cshow + ."X - X = " over dup CC-? cshow + ."Y - Y = " dup dup CC-? cshow + 2drop ."********************" cr +} : one-test +CX{666666666666*$239+1000000000000*$-17} =: X +X CX{666666666666*$239+4444*$-17} one-test +X CX{666666666665*$239+4444*$-17} one-test +X CX{666666666667*$239+4444*$-17} one-test +X CX{666666666666*$239} one-test +X CX{666666666665*$239} one-test +X CX{666666666667*$239} one-test +X CX{1111*$1} one-test +X CX{0*$-17} one-test +X cc0 1 0 +newccpair one-test +X cc0 239 0 +newccpair one-test diff --git a/submodules/ton/tonlib-src/crypto/test/test-db.cpp b/submodules/ton/tonlib-src/crypto/test/test-db.cpp index 1b7e19009d..411e0c7707 100644 --- a/submodules/ton/tonlib-src/crypto/test/test-db.cpp +++ b/submodules/ton/tonlib-src/crypto/test/test-db.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include "vm/boc.h" #include "vm/cellslice.h" @@ -694,6 +694,32 @@ TEST(TonDb, BenchCellBuilder3) { td::bench(BenchCellBuilder3()); } +TEST(TonDb, BocFuzz) { + vm::std_boc_deserialize(td::base64_decode("te6ccgEBAQEAAgAoAAA=").move_as_ok()).ensure_error(); + vm::std_boc_deserialize(td::base64_decode("te6ccgQBQQdQAAAAAAEAte6ccgQBB1BBAAAAAAEAAAAAAP/" + "wAACJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJicmJiYmJiYmJiYmJiQ0NDQ0NDQ0NDQ0NDQ0ND" + "Q0NiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiQAA//AAAO4=") + .move_as_ok()); + vm::std_boc_deserialize(td::base64_decode("SEkh/w==").move_as_ok()).ensure_error(); + vm::std_boc_deserialize( + td::base64_decode( + "te6ccqwBMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMAKCEAAAAgAQ==") + .move_as_ok()) + .ensure_error(); +} +void test_parse_prefix(td::Slice boc) { + for (size_t i = 0; i <= boc.size(); i++) { + auto prefix = boc.substr(0, i); + vm::BagOfCells::Info info; + auto res = info.parse_serialized_header(prefix); + if (res > 0) { + break; + } + CHECK(res != 0); + CHECK(-res > (int)i); + } +} + TEST(TonDb, Boc) { td::Random::Xorshift128plus rnd{123}; for (int t = 0; t < 1000; t++) { @@ -704,6 +730,8 @@ TEST(TonDb, Boc) { auto serialized = serialize_boc(std::move(cell), mode); CHECK(serialized.size() != 0); + test_parse_prefix(serialized); + auto loaded_cell = deserialize_boc(serialized); ASSERT_EQ(cell_hash, loaded_cell->get_hash()); diff --git a/submodules/ton/tonlib-src/crypto/test/test-smartcont.cpp b/submodules/ton/tonlib-src/crypto/test/test-smartcont.cpp index eb6e88802f..08b19a0509 100644 --- a/submodules/ton/tonlib-src/crypto/test/test-smartcont.cpp +++ b/submodules/ton/tonlib-src/crypto/test/test-smartcont.cpp @@ -306,6 +306,8 @@ TEST(Tonlib, WalletV3) { ASSERT_EQ(239u, wallet.get_wallet_id().ok()); ASSERT_EQ(123u, wallet.get_seqno().ok()); CHECK(priv_key.get_public_key().ok().as_octet_string() == wallet.get_public_key().ok().as_octet_string()); + CHECK(priv_key.get_public_key().ok().as_octet_string() == + ton::GenericAccount::get_public_key(wallet).ok().as_octet_string()); auto gift_message = ton::GenericAccount::create_ext_message( address, {}, wallet.make_a_gift_message(priv_key, 60, {gift}).move_as_ok()); @@ -337,6 +339,7 @@ TEST(Tonlib, HighloadWallet) { ASSERT_EQ(239u, wallet.get_wallet_id().ok()); ASSERT_EQ(0u, wallet.get_seqno().ok()); CHECK(pub_key.as_octet_string() == wallet.get_public_key().ok().as_octet_string()); + CHECK(pub_key.as_octet_string() == ton::GenericAccount::get_public_key(wallet).ok().as_octet_string()); CHECK(address.addr.as_slice() == td::Slice(new_wallet_addr).substr(0, 32)); @@ -417,6 +420,7 @@ TEST(Tonlib, HighloadWalletV2) { {ton::HighloadWalletV2::get_init_code(-1), ton::HighloadWalletV2::get_init_data(pub_key, 239)}); ASSERT_EQ(239u, wallet.get_wallet_id().ok()); CHECK(pub_key.as_octet_string() == wallet.get_public_key().ok().as_octet_string()); + CHECK(pub_key.as_octet_string() == ton::GenericAccount::get_public_key(wallet).ok().as_octet_string()); CHECK(address.addr.as_slice() == td::Slice(new_wallet_addr).substr(0, 32)); @@ -579,16 +583,58 @@ TEST(Smartcon, Multisig) { wallet_id, td::transform(keys, [](auto& key) { return key.get_public_key().ok().as_octet_string(); }), k); auto ms = ton::MultisigWallet::create(init_state); - td::uint64 query_id = 123 | ((100 * 60ull) << 32); - ton::MultisigWallet::QueryBuilder qb(wallet_id, query_id, vm::CellBuilder().finalize()); - // first empty query (init) - CHECK(ms.write().send_external_message(vm::CellBuilder().finalize()).code == 0); - // first empty query - CHECK(ms.write().send_external_message(vm::CellBuilder().finalize()).code > 0); + td::uint32 now = 0; + auto args = [&now]() -> ton::SmartContract::Args { return ton::SmartContract::Args().set_now(now); }; + // first empty query (init) + CHECK(ms.write().send_external_message(vm::CellBuilder().finalize(), args()).code == 0); + // first empty query + CHECK(ms.write().send_external_message(vm::CellBuilder().finalize(), args()).code > 0); + + { + td::uint64 query_id = 123 | ((now + 10 * 60ull) << 32); + ton::MultisigWallet::QueryBuilder qb(wallet_id, query_id, vm::CellBuilder().finalize()); + auto query = qb.create(0, keys[0]); + auto res = ms.write().send_external_message(query, args()); + CHECK(!res.accepted); + CHECK(res.code == 41); + } + { + for (int i = 1; i <= 11; i++) { + td::uint64 query_id = i | ((now + 100 * 60ull) << 32); + ton::MultisigWallet::QueryBuilder qb(wallet_id, query_id, vm::CellBuilder().finalize()); + auto query = qb.create(5, keys[5]); + auto res = ms.write().send_external_message(query, args()); + if (i <= 10) { + CHECK(res.accepted); + } else { + CHECK(!res.accepted); + } + } + + now += 100 * 60 + 100; + { + td::uint64 query_id = 200 | ((now + 100 * 60ull) << 32); + ton::MultisigWallet::QueryBuilder qb(wallet_id, query_id, vm::CellBuilder().finalize()); + auto query = qb.create(6, keys[6]); + auto res = ms.write().send_external_message(query, args()); + CHECK(res.accepted); + } + + { + td::uint64 query_id = 300 | ((now + 100 * 60ull) << 32); + ton::MultisigWallet::QueryBuilder qb(wallet_id, query_id, vm::CellBuilder().finalize()); + auto query = qb.create(5, keys[5]); + auto res = ms.write().send_external_message(query, args()); + CHECK(res.accepted); + } + } + + td::uint64 query_id = 123 | ((now + 100 * 60ull) << 32); + ton::MultisigWallet::QueryBuilder qb(wallet_id, query_id, vm::CellBuilder().finalize()); for (int i = 0; i < 10; i++) { auto query = qb.create(i, keys[i]); - auto ans = ms.write().send_external_message(query); + auto ans = ms.write().send_external_message(query, args()); LOG(INFO) << "CODE: " << ans.code; LOG(INFO) << "GAS: " << ans.gas_used; } @@ -598,12 +644,12 @@ TEST(Smartcon, Multisig) { auto query = qb.create(49, keys[49]); CHECK(ms->get_n_k() == std::make_pair(n, k)); - auto ans = ms.write().send_external_message(query); + auto ans = ms.write().send_external_message(query, args()); LOG(INFO) << "CODE: " << ans.code; LOG(INFO) << "GAS: " << ans.gas_used; CHECK(ans.success); ASSERT_EQ(0, ms->processed(query_id)); - CHECK(ms.write().send_external_message(query).code > 0); + CHECK(ms.write().send_external_message(query, args()).code > 0); ASSERT_EQ(0, ms->processed(query_id)); { @@ -614,7 +660,7 @@ TEST(Smartcon, Multisig) { query = qb.create(99, keys[99]); } - ans = ms.write().send_external_message(query); + ans = ms.write().send_external_message(query, args()); LOG(INFO) << "CODE: " << ans.code; LOG(INFO) << "GAS: " << ans.gas_used; ASSERT_EQ(-1, ms->processed(query_id)); diff --git a/submodules/ton/tonlib-src/crypto/test/vm.cpp b/submodules/ton/tonlib-src/crypto/test/vm.cpp index 77157f6d84..3227f8fa66 100644 --- a/submodules/ton/tonlib-src/crypto/test/vm.cpp +++ b/submodules/ton/tonlib-src/crypto/test/vm.cpp @@ -22,6 +22,7 @@ #include "fift/utils.h" #include "common/bigint.hpp" +#include "td/utils/base64.h" #include "td/utils/tests.h" #include "td/utils/ScopeGuard.h" #include "td/utils/StringBuilder.h" @@ -53,7 +54,10 @@ std::string run_vm(td::Ref cell) { vm::Stack stack; try { - vm::run_vm_code(vm::load_cell_slice_ref(cell), stack, 0 /*flags*/, nullptr /*data*/, std::move(log) /*VmLog*/); + vm::GasLimits gas_limit(1000, 1000); + + vm::run_vm_code(vm::load_cell_slice_ref(cell), stack, 0 /*flags*/, nullptr /*data*/, std::move(log) /*VmLog*/, + nullptr, &gas_limit); } catch (...) { LOG(FATAL) << "catch unhandled exception"; } @@ -77,6 +81,14 @@ void test_run_vm(td::Slice code_hex) { test_run_vm(to_cell(buff, bits)); } +void test_run_vm_raw(td::Slice code64) { + auto code = td::base64_decode(code64).move_as_ok(); + if (code.size() > 127) { + code.resize(127); + } + test_run_vm(vm::CellBuilder().store_bytes(code).finalize()); +} + TEST(VM, simple) { test_run_vm("ABCBABABABA"); } @@ -126,12 +138,12 @@ TEST(VM, unhandled_exception_1) { TEST(VM, unhandled_exception_2) { // infinite loop now - // test_run_vm("EBEDB4"); + test_run_vm("EBEDB4"); } TEST(VM, unhandled_exception_3) { // infinite loop now - // test_run_vm("EBEDC0"); + test_run_vm("EBEDC0"); } TEST(VM, unhandled_exception_4) { @@ -142,6 +154,17 @@ TEST(VM, unhandled_exception_5) { test_run_vm("738B04016D21F41476A721F49F"); } +TEST(VM, infinity_loop_1) { + test_run_vm_raw("f3r4AJGQ6rDraIQ="); +} +TEST(VM, infinity_loop_2) { + test_run_vm_raw("kpTt7ZLrig=="); +} + +TEST(VM, oom_1) { + test_run_vm_raw("bXflX/BvDw=="); +} + TEST(VM, bigint) { td::StringBuilder sb({}, true); diff --git a/submodules/ton/tonlib-src/crypto/tl/tlbc-data.h b/submodules/ton/tonlib-src/crypto/tl/tlbc-data.h index 2aae4e8a12..8b6f2392f4 100644 --- a/submodules/ton/tonlib-src/crypto/tl/tlbc-data.h +++ b/submodules/ton/tonlib-src/crypto/tl/tlbc-data.h @@ -14,11 +14,12 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include #include +#include "common/linalloc.hpp" namespace tlbc { @@ -26,6 +27,8 @@ using src::Lexem; using src::Lexer; using sym::sym_idx_t; +extern td::LinearAllocator AR; + struct Type; struct Constructor; diff --git a/submodules/ton/tonlib-src/crypto/tl/tlbc.cpp b/submodules/ton/tonlib-src/crypto/tl/tlbc.cpp index 0364e5dbf2..127eacb0a7 100644 --- a/submodules/ton/tonlib-src/crypto/tl/tlbc.cpp +++ b/submodules/ton/tonlib-src/crypto/tl/tlbc.cpp @@ -23,7 +23,7 @@ exception statement from your version. If you delete this exception statement from all source files in the program, then also delete it here. - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include #include @@ -219,6 +219,8 @@ inline bool is_uc_ident(sym_idx_t idx) { namespace tlbc { +td::LinearAllocator AR(1 << 22); + /* * * AUXILIARY DATA TYPES @@ -906,7 +908,7 @@ bool TypeExpr::no_tchk() const { } TypeExpr* TypeExpr::mk_intconst(const src::SrcLocation& loc, unsigned int_const) { - return new TypeExpr{loc, te_IntConst, (int)int_const}; + return new (AR) TypeExpr{loc, te_IntConst, (int)int_const}; } TypeExpr* TypeExpr::mk_intconst(const src::SrcLocation& loc, std::string int_const) { @@ -951,16 +953,16 @@ TypeExpr* TypeExpr::mk_mulint(const src::SrcLocation& loc, TypeExpr* expr1, Type return expr2; } // delete expr2; - return new TypeExpr{loc, te_MulConst, val, {expr1}, expr1->negated}; + return new (AR) TypeExpr{loc, te_MulConst, val, {expr1}, expr1->negated}; } TypeExpr* TypeExpr::mk_apply(const src::SrcLocation& loc, int tp, TypeExpr* expr1, TypeExpr* expr2) { - TypeExpr* expr = new TypeExpr{loc, tp, 0, {expr1, expr2}}; + TypeExpr* expr = new (AR) TypeExpr{loc, tp, 0, {expr1, expr2}}; return expr; } TypeExpr* TypeExpr::mk_cellref(const src::SrcLocation& loc, TypeExpr* expr1) { - TypeExpr* expr = new TypeExpr{loc, te_Ref, 0, {expr1}}; + TypeExpr* expr = new (AR) TypeExpr{loc, te_Ref, 0, {expr1}}; return expr; } @@ -1046,7 +1048,7 @@ bool TypeExpr::close(const src::SrcLocation& loc) { } TypeExpr* TypeExpr::mk_apply_empty(const src::SrcLocation& loc, sym_idx_t name, Type* type_applied) { - TypeExpr* expr = new TypeExpr{loc, te_Apply, name}; + TypeExpr* expr = new (AR) TypeExpr{loc, te_Apply, name}; expr->type_applied = type_applied; expr->is_nat_subtype = (type_applied->produces_nat && !type_applied->arity); return expr; @@ -1984,7 +1986,7 @@ void parse_field_list(Lexer& lex, Constructor& cs); TypeExpr* parse_anonymous_constructor(Lexer& lex, Constructor& cs) { sym::open_scope(lex); - Constructor* cs2 = new Constructor(lex.cur().loc); // anonymous constructor + Constructor* cs2 = new (AR) Constructor(lex.cur().loc); // anonymous constructor parse_field_list(lex, *cs2); if (lex.tp() != ']') { lex.expect(']'); @@ -2089,7 +2091,7 @@ TypeExpr* parse_term(Lexer& lex, Constructor& cs, int mode) { } int i = sym_val->idx; assert(i >= 0 && i < cs.fields_num); - auto res = new TypeExpr{lex.cur().loc, TypeExpr::te_Param, i}; + auto res = new (AR) TypeExpr{lex.cur().loc, TypeExpr::te_Param, i}; auto field_type = cs.fields[i].type; assert(field_type); if ((mode & 4) && !cs.fields[i].known) { @@ -2345,7 +2347,7 @@ void parse_constructor_def(Lexer& lex) { } //std::cerr << "parsing constructor `" << sym::symbols.get_name(constr_name) << "` with tag " << std::hex << tag // << std::dec << std::endl; - auto cs_ref = new Constructor(where, constr_name, 0, tag); + auto cs_ref = new (AR) Constructor(where, constr_name, 0, tag); Constructor& cs = *cs_ref; cs.is_special = is_special; parse_field_list(lex, cs); @@ -2417,7 +2419,9 @@ void parse_constructor_def(Lexer& lex) { * */ -bool parse_source(std::istream* is, const src::FileDescr* fdescr) { +std::vector source_fdescr; + +bool parse_source(std::istream* is, src::FileDescr* fdescr) { src::SourceReader reader{is, fdescr}; src::Lexer lex{reader, true, "(){}:;? #$. ^~ #", "//", "/*", "*/"}; while (lex.tp() != src::_Eof) { @@ -2432,6 +2436,7 @@ bool parse_source_file(const char* filename) { throw src::Fatal{"source file name is an empty string"}; } src::FileDescr* cur_source = new src::FileDescr{filename}; + source_fdescr.push_back(cur_source); std::ifstream ifs{filename}; if (ifs.fail()) { throw src::Fatal{std::string{"cannot open source file `"} + filename + "`"}; @@ -2440,7 +2445,9 @@ bool parse_source_file(const char* filename) { } bool parse_source_stdin() { - return parse_source(&std::cin, new src::FileDescr{"stdin", true}); + src::FileDescr* cur_source = new src::FileDescr{"stdin", true}; + source_fdescr.push_back(cur_source); + return parse_source(&std::cin, cur_source); } /* @@ -2466,7 +2473,7 @@ Type* define_builtin_type(std::string name_str, std::string args, bool produces_ } auto sym_def = sym::define_global_symbol(name, true); assert(sym_def); - sym_def->value = new SymValType{type}; + sym_def->value = new (AR) SymValType{type}; if (size < 0) { type->size = MinMaxSize::Any; } else if (min_size >= 0 && min_size != size) { diff --git a/submodules/ton/tonlib-src/crypto/vm/arithops.cpp b/submodules/ton/tonlib-src/crypto/vm/arithops.cpp index 25b6735386..823b440809 100644 --- a/submodules/ton/tonlib-src/crypto/vm/arithops.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/arithops.cpp @@ -789,7 +789,7 @@ void register_shift_logic_ops(OpcodeTable& cp0) { int exec_minmax(VmState* st, int mode) { Stack& stack = st->get_stack(); - VM_LOG(st) << "execute MINMAXOP " << mode; + VM_LOG(st) << "execute " << (mode & 1 ? "Q" : "") << (mode & 2 ? "MIN" : "") << (mode & 4 ? "MAX" : ""); stack.check_underflow(2); auto x = stack.pop_int(); auto y = stack.pop_int(); @@ -811,7 +811,7 @@ int exec_minmax(VmState* st, int mode) { int exec_abs(VmState* st, bool quiet) { Stack& stack = st->get_stack(); - VM_LOG(st) << "execute ABS"; + VM_LOG(st) << "execute " << (quiet ? "QABS" : "ABS"); stack.check_underflow(1); auto x = stack.pop_int(); if (x->is_valid() && x->sgn() < 0) { diff --git a/submodules/ton/tonlib-src/crypto/vm/boc.cpp b/submodules/ton/tonlib-src/crypto/vm/boc.cpp index fbb39dfe23..6ebab76e6e 100644 --- a/submodules/ton/tonlib-src/crypto/vm/boc.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/boc.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include #include @@ -94,10 +94,8 @@ td::Result> CellSerializationInfo::create_data_cell(td::Slice cell for (int k = 0; k < refs_cnt; k++) { cb.store_ref(std::move(refs[k])); } - auto res = cb.finalize_novm(special); - if (res.is_null()) { - return td::Status::Error("CellBuilder::finalize failed"); - } + TRY_RESULT(res, cb.finalize_novm_nothrow(special)); + CHECK(!res.is_null()); if (res->is_special() != special) { return td::Status::Error("is_special mismatch"); } @@ -654,10 +652,10 @@ long long BagOfCells::Info::parse_serialized_header(const td::Slice& slice) { ptr += 6; sz -= 6; if (sz < ref_byte_size) { - return -(int)roots_offset; + return -static_cast(roots_offset); } cell_count = (int)read_ref(ptr); - if (cell_count < 0) { + if (cell_count <= 0) { cell_count = -1; return 0; } @@ -671,7 +669,7 @@ long long BagOfCells::Info::parse_serialized_header(const td::Slice& slice) { } index_offset = roots_offset; if (magic == boc_generic) { - index_offset += root_count * ref_byte_size; + index_offset += (long long)root_count * ref_byte_size; has_roots = true; } else { if (root_count != 1) { @@ -690,12 +688,18 @@ long long BagOfCells::Info::parse_serialized_header(const td::Slice& slice) { return 0; } if (sz < 3 * ref_byte_size + offset_byte_size) { - return -(int)roots_offset; + return -static_cast(roots_offset); } data_size = read_offset(ptr + 3 * ref_byte_size); if (data_size > ((unsigned long long)cell_count << 10)) { return 0; } + if (data_size > (1ull << 40)) { + return 0; // bag of cells with more than 1TiB data is unlikely + } + if (data_size < cell_count * (2ull + ref_byte_size) - ref_byte_size) { + return 0; // invalid header, too many cells for this amount of data bytes + } valid = true; total_size = data_offset + data_size + (has_crc32c ? 4 : 0); return total_size; @@ -747,14 +751,13 @@ td::Result> BagOfCells::deserialize_cell(int idx, td::Slic return cell_info.create_data_cell(cell_slice, refs); } -td::Result BagOfCells::deserialize(const td::Slice& data) { +td::Result BagOfCells::deserialize(const td::Slice& data, int max_roots) { clear(); long long size_est = info.parse_serialized_header(data); //LOG(INFO) << "estimated size " << size_est << ", true size " << data.size(); if (size_est == 0) { return td::Status::Error(PSLICE() << "cannot deserialize bag-of-cells: invalid header, error " << size_est); } - if (size_est < 0) { //LOG(ERROR) << "cannot deserialize bag-of-cells: not enough bytes (" << data.size() << " present, " << -size_est //<< " required)"; @@ -767,6 +770,9 @@ td::Result BagOfCells::deserialize(const td::Slice& data) { return -size_est; } //LOG(INFO) << "estimated size " << size_est << ", true size " << data.size(); + if (info.root_count > max_roots) { + return td::Status::Error("Bag-of-cells has more root cells than expected"); + } if (info.has_crc32c) { unsigned crc_computed = td::crc32c(td::Slice{data.ubegin(), data.uend() - 4}); unsigned crc_stored = td::as(data.uend() - 4); @@ -906,7 +912,7 @@ td::Result> std_boc_deserialize(td::Slice data, bool can_be_empty) { return Ref(); } BagOfCells boc; - auto res = boc.deserialize(data); + auto res = boc.deserialize(data, 1); if (res.is_error()) { return res.move_as_error(); } @@ -923,12 +929,12 @@ td::Result> std_boc_deserialize(td::Slice data, bool can_be_empty) { return std::move(root); } -td::Result>> std_boc_deserialize_multi(td::Slice data) { +td::Result>> std_boc_deserialize_multi(td::Slice data, int max_roots) { if (data.empty()) { return std::vector>{}; } BagOfCells boc; - auto res = boc.deserialize(data); + auto res = boc.deserialize(data, max_roots); if (res.is_error()) { return res.move_as_error(); } diff --git a/submodules/ton/tonlib-src/crypto/vm/boc.h b/submodules/ton/tonlib-src/crypto/vm/boc.h index 29f582be70..740a6b64f5 100644 --- a/submodules/ton/tonlib-src/crypto/vm/boc.h +++ b/submodules/ton/tonlib-src/crypto/vm/boc.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include @@ -26,12 +26,6 @@ namespace vm { using td::Ref; -td::Result> std_boc_deserialize(td::Slice data, bool can_be_empty = false); -td::Result std_boc_serialize(Ref root, int mode = 0); - -td::Result>> std_boc_deserialize_multi(td::Slice data); -td::Result std_boc_serialize_multi(std::vector> root, int mode = 0); - class NewCellStorageStat { public: NewCellStorageStat() { @@ -159,7 +153,7 @@ struct CellSerializationInfo { class BagOfCells { public: - enum { hash_bytes = vm::Cell::hash_bytes }; + enum { hash_bytes = vm::Cell::hash_bytes, default_max_roots = 16384 }; enum Mode { WithIndex = 1, WithCRC32C = 2, WithTopHash = 4, WithIntHashes = 8, WithCacheBits = 16, max = 31 }; enum { max_cell_whs = 64 }; using Hash = Cell::Hash; @@ -259,9 +253,10 @@ class BagOfCells { std::size_t serialize_to(unsigned char* buffer, std::size_t buff_size, int mode = 0); std::string extract_string() const; - td::Result deserialize(const td::Slice& data); - td::Result deserialize(const unsigned char* buffer, std::size_t buff_size) { - return deserialize(td::Slice{buffer, buff_size}); + td::Result deserialize(const td::Slice& data, int max_roots = default_max_roots); + td::Result deserialize(const unsigned char* buffer, std::size_t buff_size, + int max_roots = default_max_roots) { + return deserialize(td::Slice{buffer, buff_size}, max_roots); } int get_root_count() const { return root_count; @@ -311,4 +306,11 @@ class BagOfCells { std::vector* cell_should_cache); }; +td::Result> std_boc_deserialize(td::Slice data, bool can_be_empty = false); +td::Result std_boc_serialize(Ref root, int mode = 0); + +td::Result>> std_boc_deserialize_multi(td::Slice data, + int max_roots = BagOfCells::default_max_roots); +td::Result std_boc_serialize_multi(std::vector> root, int mode = 0); + } // namespace vm diff --git a/submodules/ton/tonlib-src/crypto/vm/cellops.cpp b/submodules/ton/tonlib-src/crypto/vm/cellops.cpp index cc1102846e..1dfb69fbb7 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cellops.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/cellops.cpp @@ -58,14 +58,27 @@ std::string dump_push_ref(CellSlice& cs, unsigned args, int pfx_bits, std::strin return ""; } cs.advance(pfx_bits); - cs.advance_refs(1); - return name; + auto cell = cs.fetch_ref(); + return name + " (" + cell->get_hash().to_hex() + ")"; } int compute_len_push_ref(const CellSlice& cs, unsigned args, int pfx_bits) { return cs.have_refs(1) ? (0x10000 + pfx_bits) : 0; } +std::string dump_push_ref2(CellSlice& cs, unsigned args, int pfx_bits, std::string name) { + if (!cs.have_refs(2)) { + return ""; + } + cs.advance(pfx_bits); + auto cell1 = cs.fetch_ref(), cell2 = cs.fetch_ref(); + return name + " (" + cell1->get_hash().to_hex() + ") (" + cell2->get_hash().to_hex() + ")"; +} + +int compute_len_push_ref2(const CellSlice& cs, unsigned args, int pfx_bits) { + return cs.have_refs(2) ? (0x20000 + pfx_bits) : 0; +} + int exec_push_slice_common(VmState* st, CellSlice& cs, unsigned data_bits, unsigned refs, int pfx_bits) { if (!cs.have(pfx_bits + data_bits)) { throw VmError{Excno::inv_opcode, "not enough data bits for a PUSHSLICE instruction"}; diff --git a/submodules/ton/tonlib-src/crypto/vm/cellops.h b/submodules/ton/tonlib-src/crypto/vm/cellops.h index cc0f5ab864..1c08d8e348 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cellops.h +++ b/submodules/ton/tonlib-src/crypto/vm/cellops.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include "vm/cellslice.h" @@ -28,4 +28,7 @@ void register_cell_ops(OpcodeTable &cp0); std::string dump_push_ref(CellSlice &cs, unsigned args, int pfx_bits, std::string name); int compute_len_push_ref(const CellSlice &cs, unsigned args, int pfx_bits); +std::string dump_push_ref2(CellSlice &cs, unsigned args, int pfx_bits, std::string name); +int compute_len_push_ref2(const CellSlice &cs, unsigned args, int pfx_bits); + } // namespace vm diff --git a/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp b/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp index 1c3fcdef8a..dc7f5eb813 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.cpp @@ -67,9 +67,14 @@ Ref CellBuilder::finalize_copy(bool special) const { return cell; } -Ref CellBuilder::finalize_novm(bool special) { +td::Result> CellBuilder::finalize_novm_nothrow(bool special) { auto res = DataCell::create(data, size(), td::mutable_span(refs.data(), size_refs()), special); bits = refs_cnt = 0; + return res; +} + +Ref CellBuilder::finalize_novm(bool special) { + auto res = finalize_novm_nothrow(special); if (res.is_error()) { LOG(DEBUG) << res.error(); throw CellWriteError{}; @@ -570,11 +575,11 @@ CellBuilder* CellBuilder::make_copy() const { return c; } -CellSlice CellBuilder::as_cellslice() const & { +CellSlice CellBuilder::as_cellslice() const& { return CellSlice{finalize_copy()}; } -Ref CellBuilder::as_cellslice_ref() const & { +Ref CellBuilder::as_cellslice_ref() const& { return Ref{true, finalize_copy()}; } diff --git a/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.h b/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.h index bcd2434ecf..4efd90d8ba 100644 --- a/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.h +++ b/submodules/ton/tonlib-src/crypto/vm/cells/CellBuilder.h @@ -177,12 +177,13 @@ class CellBuilder : public td::CntObject { Ref finalize_copy(bool special = false) const; Ref finalize(bool special = false); Ref finalize_novm(bool special = false); + td::Result> finalize_novm_nothrow(bool special = false); bool finalize_to(Ref& res, bool special = false) { return (res = finalize(special)).not_null(); } - CellSlice as_cellslice() const &; + CellSlice as_cellslice() const&; CellSlice as_cellslice() &&; - Ref as_cellslice_ref() const &; + Ref as_cellslice_ref() const&; Ref as_cellslice_ref() &&; static td::int64 get_total_cell_builders() { return get_thread_safe_counter().sum(); diff --git a/submodules/ton/tonlib-src/crypto/vm/continuation.cpp b/submodules/ton/tonlib-src/crypto/vm/continuation.cpp index 243dfd5ea0..94d2012506 100644 --- a/submodules/ton/tonlib-src/crypto/vm/continuation.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/continuation.cpp @@ -610,30 +610,4 @@ Ref OrdCont::deserialize(CellSlice& cs, int mode) { : Ref{}; } -void VmState::init_cregs(bool same_c3, bool push_0) { - cr.set_c0(quit0); - cr.set_c1(quit1); - cr.set_c2(Ref{true}); - if (same_c3) { - cr.set_c3(Ref{true, code, cp}); - if (push_0) { - VM_LOG(this) << "implicit PUSH 0 at start\n"; - get_stack().push_smallint(0); - } - } else { - cr.set_c3(Ref{true, 11}); - } - if (cr.d[0].is_null() || cr.d[1].is_null()) { - auto empty_cell = CellBuilder{}.finalize(); - for (int i = 0; i < ControlRegs::dreg_num; i++) { - if (cr.d[i].is_null()) { - cr.d[i] = empty_cell; - } - } - } - if (cr.c7.is_null()) { - cr.set_c7(Ref{true}); - } -} - } // namespace vm diff --git a/submodules/ton/tonlib-src/crypto/vm/contops.cpp b/submodules/ton/tonlib-src/crypto/vm/contops.cpp index 63d5570539..c3cb36bb80 100644 --- a/submodules/ton/tonlib-src/crypto/vm/contops.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/contops.cpp @@ -26,10 +26,12 @@ #include "vm/excno.hpp" #include "vm/vm.h" +using namespace std::literals::string_literals; + namespace vm { int exec_execute(VmState* st) { - VM_LOG(st) << "execute EXECUTE\n"; + VM_LOG(st) << "execute EXECUTE"; auto cont = st->get_stack().pop_cont(); return st->call(std::move(cont)); } @@ -150,12 +152,58 @@ int exec_callcc_varargs(VmState* st) { int exec_do_with_ref(VmState* st, CellSlice& cs, int pfx_bits, const std::function)>& func, const char* name) { if (!cs.have_refs(1)) { - throw VmError{Excno::inv_opcode, "no references left for a CALLREF instruction"}; + throw VmError{Excno::inv_opcode, "no references left for a "s + name + " instruction"}; } cs.advance(pfx_bits); auto cell = cs.fetch_ref(); VM_LOG(st) << "execute " << name << " (" << cell->get_hash().to_hex() << ")"; - return func(st, Ref{true, load_cell_slice_ref(std::move(cell)), st->get_cp()}); + return func(st, st->ref_to_cont(std::move(cell))); +} + +int exec_do_with_cell(VmState* st, CellSlice& cs, int pfx_bits, const std::function)>& func, + const char* name) { + if (!cs.have_refs(1)) { + throw VmError{Excno::inv_opcode, "no references left for a "s + name + " instruction"}; + } + cs.advance(pfx_bits); + auto cell = cs.fetch_ref(); + VM_LOG(st) << "execute " << name << " (" << cell->get_hash().to_hex() << ")"; + return func(st, std::move(cell)); +} + +int exec_ifelse_ref(VmState* st, CellSlice& cs, int pfx_bits, bool mode) { + const char* name = mode ? "IFREFELSE" : "IFELSEREF"; + if (!cs.have_refs(1)) { + throw VmError{Excno::inv_opcode, "no references left for a "s + name + " instruction"}; + } + cs.advance(pfx_bits); + auto cell = cs.fetch_ref(); + Stack& stack = st->get_stack(); + VM_LOG(st) << "execute " << name << " (" << cell->get_hash().to_hex() << ")"; + stack.check_underflow(2); + auto cont = stack.pop_cont(); + if (stack.pop_bool() == mode) { + cont = st->ref_to_cont(std::move(cell)); + } else { + cell.clear(); + } + return st->call(std::move(cont)); +} + +int exec_ifref_elseref(VmState* st, CellSlice& cs, unsigned args, int pfx_bits) { + if (!cs.have_refs(2)) { + throw VmError{Excno::inv_opcode, "no references left for a IFREFELSEREF instruction"}; + } + cs.advance(pfx_bits); + auto cell1 = cs.fetch_ref(), cell2 = cs.fetch_ref(); + Stack& stack = st->get_stack(); + VM_LOG(st) << "execute IFREFELSEREF (" << cell1->get_hash().to_hex() << ") (" << cell2->get_hash().to_hex() << ")"; + if (!stack.pop_bool()) { + cell1 = std::move(cell2); + } else { + cell2.clear(); + } + return st->call(st->ref_to_cont(std::move(cell1))); } int exec_ret_data(VmState* st) { @@ -349,7 +397,7 @@ int exec_if_bit_jmpref(VmState* st, CellSlice& cs, unsigned args, int pfx_bits) bool val = x->get_bit(bit); stack.push_int(std::move(x)); if (val ^ negate) { - return st->jump(Ref{true, load_cell_slice_ref(std::move(cell)), st->get_cp()}); + return st->jump(st->ref_to_cont(std::move(cell))); } return 0; } @@ -365,66 +413,72 @@ std::string dump_if_bit_jmpref(CellSlice& cs, unsigned args, int pfx_bits) { return os.str(); } -int exec_repeat(VmState* st) { +int exec_repeat(VmState* st, bool brk) { Stack& stack = st->get_stack(); - VM_LOG(st) << "execute REPEAT\n"; + VM_LOG(st) << "execute REPEAT" << (brk ? "BRK" : ""); stack.check_underflow(2); auto cont = stack.pop_cont(); int c = stack.pop_smallint_range(0x7fffffff, 0x80000000); if (c <= 0) { return 0; } - return st->repeat(std::move(cont), st->extract_cc(1), c); + return st->repeat(std::move(cont), st->c1_envelope_if(brk, st->extract_cc(1)), c); } -int exec_repeat_end(VmState* st) { +int exec_repeat_end(VmState* st, bool brk) { Stack& stack = st->get_stack(); - VM_LOG(st) << "execute REPEATEND\n"; + VM_LOG(st) << "execute REPEATEND" << (brk ? "BRK" : ""); stack.check_underflow(1); int c = stack.pop_smallint_range(0x7fffffff, 0x80000000); if (c <= 0) { return st->ret(); } auto cont = st->extract_cc(0); - return st->repeat(std::move(cont), st->get_c0(), c); + return st->repeat(std::move(cont), st->c1_envelope_if(brk, st->get_c0()), c); } -int exec_until(VmState* st) { +int exec_until(VmState* st, bool brk) { Stack& stack = st->get_stack(); - VM_LOG(st) << "execute UNTIL\n"; + VM_LOG(st) << "execute UNTIL" << (brk ? "BRK" : ""); auto cont = stack.pop_cont(); - return st->until(std::move(cont), st->extract_cc(1)); + return st->until(std::move(cont), st->c1_envelope_if(brk, st->extract_cc(1))); } -int exec_until_end(VmState* st) { - VM_LOG(st) << "execute UNTILEND\n"; +int exec_until_end(VmState* st, bool brk) { + VM_LOG(st) << "execute UNTILEND" << (brk ? "BRK" : ""); auto cont = st->extract_cc(0); - return st->until(std::move(cont), st->get_c0()); + return st->until(std::move(cont), st->c1_envelope_if(brk, st->get_c0())); } -int exec_while(VmState* st) { +int exec_while(VmState* st, bool brk) { Stack& stack = st->get_stack(); - VM_LOG(st) << "execute WHILE\n"; + VM_LOG(st) << "execute WHILE" << (brk ? "BRK" : ""); stack.check_underflow(2); auto body = stack.pop_cont(); auto cond = stack.pop_cont(); - return st->loop_while(std::move(cond), std::move(body), st->extract_cc(1)); + return st->loop_while(std::move(cond), std::move(body), st->c1_envelope_if(brk, st->extract_cc(1))); } -int exec_while_end(VmState* st) { - VM_LOG(st) << "execute WHILEEND\n"; +int exec_while_end(VmState* st, bool brk) { + VM_LOG(st) << "execute WHILEEND" << (brk ? "BRK" : ""); auto cond = st->get_stack().pop_cont(); auto body = st->extract_cc(0); - return st->loop_while(std::move(cond), std::move(body), st->get_c0()); + return st->loop_while(std::move(cond), std::move(body), st->c1_envelope_if(brk, st->get_c0())); } -int exec_again(VmState* st) { - VM_LOG(st) << "execute AGAIN\n"; +int exec_again(VmState* st, bool brk) { + VM_LOG(st) << "execute AGAIN" << (brk ? "BRK" : ""); + if (brk) { + st->set_c1(st->extract_cc(3)); + } return st->again(st->get_stack().pop_cont()); } -int exec_again_end(VmState* st) { - VM_LOG(st) << "execute AGAINEND\n"; +int exec_again_end(VmState* st, bool brk) { + VM_LOG(st) << "execute AGAINEND" << (brk ? "BRK" : ""); + if (brk) { + st->c1_save_set(); + } return st->again(st->extract_cc(0)); } @@ -437,44 +491,70 @@ void register_continuation_cond_loop_ops(OpcodeTable& cp0) { .insert(OpcodeInstr::mksimple(0xe0, 8, "IFJMP", exec_if_jmp)) .insert(OpcodeInstr::mksimple(0xe1, 8, "IFNOTJMP", exec_ifnot_jmp)) .insert(OpcodeInstr::mksimple(0xe2, 8, "IFELSE", exec_if_else)) - .insert(OpcodeInstr::mkext( - 0xe300, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFREF"), - std::bind(exec_do_with_ref, _1, _2, _4, - [](auto st, auto cont) { return st->get_stack().pop_bool() ? st->call(std::move(cont)) : 0; }, - "IFREF"), - compute_len_push_ref)) - .insert(OpcodeInstr::mkext( - 0xe301, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFNOTREF"), - std::bind(exec_do_with_ref, _1, _2, _4, - [](auto st, auto cont) { return st->get_stack().pop_bool() ? 0 : st->call(std::move(cont)); }, - "IFNOTREF"), - compute_len_push_ref)) - .insert(OpcodeInstr::mkext( - 0xe302, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFJMPREF"), - std::bind(exec_do_with_ref, _1, _2, _4, - [](auto st, auto cont) { return st->get_stack().pop_bool() ? st->jump(std::move(cont)) : 0; }, - "IFJMPREF"), - compute_len_push_ref)) - .insert(OpcodeInstr::mkext( - 0xe303, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFNOTJMPREF"), - std::bind(exec_do_with_ref, _1, _2, _4, - [](auto st, auto cont) { return st->get_stack().pop_bool() ? 0 : st->jump(std::move(cont)); }, - "IFNOTJMPREF"), - compute_len_push_ref)) + .insert(OpcodeInstr::mkext(0xe300, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFREF"), + std::bind(exec_do_with_cell, _1, _2, _4, + [](auto st, auto cell) { + return st->get_stack().pop_bool() + ? st->call(st->ref_to_cont(std::move(cell))) + : 0; + }, + "IFREF"), + compute_len_push_ref)) + .insert(OpcodeInstr::mkext(0xe301, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFNOTREF"), + std::bind(exec_do_with_cell, _1, _2, _4, + [](auto st, auto cell) { + return st->get_stack().pop_bool() + ? 0 + : st->call(st->ref_to_cont(std::move(cell))); + }, + "IFNOTREF"), + compute_len_push_ref)) + .insert(OpcodeInstr::mkext(0xe302, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFJMPREF"), + std::bind(exec_do_with_cell, _1, _2, _4, + [](auto st, auto cell) { + return st->get_stack().pop_bool() + ? st->jump(st->ref_to_cont(std::move(cell))) + : 0; + }, + "IFJMPREF"), + compute_len_push_ref)) + .insert(OpcodeInstr::mkext(0xe303, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFNOTJMPREF"), + std::bind(exec_do_with_cell, _1, _2, _4, + [](auto st, auto cell) { + return st->get_stack().pop_bool() + ? 0 + : st->jump(st->ref_to_cont(std::move(cell))); + }, + "IFNOTJMPREF"), + compute_len_push_ref)) .insert(OpcodeInstr::mksimple(0xe304, 16, "CONDSEL", exec_condsel)) .insert(OpcodeInstr::mksimple(0xe305, 16, "CONDSELCHK", exec_condsel_chk)) .insert(OpcodeInstr::mksimple(0xe308, 16, "IFRETALT", exec_ifretalt)) .insert(OpcodeInstr::mksimple(0xe309, 16, "IFNOTRETALT", exec_ifnotretalt)) + .insert(OpcodeInstr::mkext(0xe30d, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFREFELSE"), + std::bind(exec_ifelse_ref, _1, _2, _4, true), compute_len_push_ref)) + .insert(OpcodeInstr::mkext(0xe30e, 16, 0, std::bind(dump_push_ref, _1, _2, _3, "IFELSEREF"), + std::bind(exec_ifelse_ref, _1, _2, _4, false), compute_len_push_ref)) + .insert(OpcodeInstr::mkext(0xe30f, 16, 0, std::bind(dump_push_ref2, _1, _2, _3, "IFREFELSEREF"), + exec_ifref_elseref, compute_len_push_ref2)) .insert(OpcodeInstr::mkfixed(0xe380 >> 6, 10, 6, dump_if_bit_jmp, exec_if_bit_jmp)) .insert(OpcodeInstr::mkext(0xe3c0 >> 6, 10, 6, dump_if_bit_jmpref, exec_if_bit_jmpref, compute_len_push_ref)) - .insert(OpcodeInstr::mksimple(0xe4, 8, "REPEAT", exec_repeat)) - .insert(OpcodeInstr::mksimple(0xe5, 8, "REPEATEND", exec_repeat_end)) - .insert(OpcodeInstr::mksimple(0xe6, 8, "UNTIL", exec_until)) - .insert(OpcodeInstr::mksimple(0xe7, 8, "UNTILEND", exec_until_end)) - .insert(OpcodeInstr::mksimple(0xe8, 8, "WHILE", exec_while)) - .insert(OpcodeInstr::mksimple(0xe9, 8, "WHILEEND", exec_while_end)) - .insert(OpcodeInstr::mksimple(0xea, 8, "AGAIN", exec_again)) - .insert(OpcodeInstr::mksimple(0xeb, 8, "AGAINEND", exec_again_end)); + .insert(OpcodeInstr::mksimple(0xe4, 8, "REPEAT", std::bind(exec_repeat, _1, false))) + .insert(OpcodeInstr::mksimple(0xe5, 8, "REPEATEND", std::bind(exec_repeat_end, _1, false))) + .insert(OpcodeInstr::mksimple(0xe6, 8, "UNTIL", std::bind(exec_until, _1, false))) + .insert(OpcodeInstr::mksimple(0xe7, 8, "UNTILEND", std::bind(exec_until_end, _1, false))) + .insert(OpcodeInstr::mksimple(0xe8, 8, "WHILE", std::bind(exec_while, _1, false))) + .insert(OpcodeInstr::mksimple(0xe9, 8, "WHILEEND", std::bind(exec_while_end, _1, false))) + .insert(OpcodeInstr::mksimple(0xea, 8, "AGAIN", std::bind(exec_again, _1, false))) + .insert(OpcodeInstr::mksimple(0xeb, 8, "AGAINEND", std::bind(exec_again_end, _1, false))) + .insert(OpcodeInstr::mksimple(0xe314, 16, "REPEATBRK", std::bind(exec_repeat, _1, true))) + .insert(OpcodeInstr::mksimple(0xe315, 16, "REPEATENDBRK", std::bind(exec_repeat_end, _1, true))) + .insert(OpcodeInstr::mksimple(0xe316, 16, "UNTILBRK", std::bind(exec_until, _1, true))) + .insert(OpcodeInstr::mksimple(0xe317, 16, "UNTILENDBRK", std::bind(exec_until_end, _1, true))) + .insert(OpcodeInstr::mksimple(0xe318, 16, "WHILEBRK", std::bind(exec_while, _1, true))) + .insert(OpcodeInstr::mksimple(0xe319, 16, "WHILEENDBRK", std::bind(exec_while_end, _1, true))) + .insert(OpcodeInstr::mksimple(0xe31a, 16, "AGAINBRK", std::bind(exec_again, _1, true))) + .insert(OpcodeInstr::mksimple(0xe31b, 16, "AGAINENDBRK", std::bind(exec_again_end, _1, true))); } int exec_setcontargs_common(VmState* st, int copy, int more) { @@ -492,6 +572,7 @@ int exec_setcontargs_common(VmState* st, int copy, int more) { } else { cdata->stack.write().move_from_stack(stack, copy); } + st->consume_stack_gas(cdata->stack); if (cdata->nargs >= 0) { cdata->nargs -= copy; } @@ -557,6 +638,7 @@ int exec_return_args_common(VmState* st, int count) { cdata->stack.write().move_from_stack(alt_stk.write(), copy); alt_stk.clear(); } + st->consume_stack_gas(cdata->stack); if (cdata->nargs >= 0) { cdata->nargs -= copy; } @@ -587,6 +669,7 @@ int exec_bless_args_common(VmState* st, int copy, int more) { stack.check_underflow(copy + 1); auto cs = stack.pop_cellslice(); auto new_stk = stack.split_top(copy); + st->consume_stack_gas(new_stk); stack.push_cont(Ref{true, std::move(cs), st->get_cp(), std::move(new_stk), more}); return 0; } @@ -703,6 +786,17 @@ int exec_save_ctr(VmState* st, unsigned args) { return 0; } +int exec_samealt(VmState* st, bool save) { + VM_LOG(st) << "execute SAMEALT" << (save ? "SAVE" : ""); + auto c0 = st->get_c0(); + if (save) { + force_cregs(c0)->define_c1(st->get_c1()); + st->set_c0(c0); + } + st->set_c1(std::move(c0)); + return 0; +} + int exec_savealt_ctr(VmState* st, unsigned args) { unsigned idx = args & 15; VM_LOG(st) << "execute SAVEALTCTR c" << idx; @@ -880,6 +974,8 @@ void register_continuation_change_ops(OpcodeTable& cp0) { .insert(OpcodeInstr::mksimple(0xedf7, 16, "THENRETALT", exec_thenret_alt)) .insert(OpcodeInstr::mksimple(0xedf8, 16, "INVERT", exec_invert)) .insert(OpcodeInstr::mksimple(0xedf9, 16, "BOOLEVAL", exec_booleval)) + .insert(OpcodeInstr::mksimple(0xedfa, 16, "SAMEALT", std::bind(exec_samealt, _1, false))) + .insert(OpcodeInstr::mksimple(0xedfb, 16, "SAMEALTSAVE", std::bind(exec_samealt, _1, true))) .insert(OpcodeInstr::mkfixed(0xee, 8, 8, std::bind(dump_setcontargs, _1, _2, "BLESSARGS"), exec_bless_args)); } diff --git a/submodules/ton/tonlib-src/crypto/vm/excno.hpp b/submodules/ton/tonlib-src/crypto/vm/excno.hpp index a18f890a36..31742e0835 100644 --- a/submodules/ton/tonlib-src/crypto/vm/excno.hpp +++ b/submodules/ton/tonlib-src/crypto/vm/excno.hpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once @@ -45,6 +45,7 @@ const char* get_exception_msg(Excno exc_no); class VmError { Excno exc_no; + bool msg_alloc = false; const char* msg; long long arg; @@ -55,6 +56,18 @@ class VmError { } VmError(Excno _excno, const char* _msg, long long _arg) : exc_no(_excno), msg(_msg), arg(_arg) { } + VmError(Excno _excno, std::string _msg, long long _arg = 0) : exc_no(_excno), msg_alloc(true), arg(_arg) { + msg_alloc = true; + char* p = (char*)malloc(_msg.size() + 1); + memcpy(p, _msg.data(), _msg.size()); + p[_msg.size()] = 0; + msg = p; + } + ~VmError() { + if (msg_alloc) { + free(const_cast(msg)); + } + } int get_errno() const { return static_cast(exc_no); } diff --git a/submodules/ton/tonlib-src/crypto/vm/vm.cpp b/submodules/ton/tonlib-src/crypto/vm/vm.cpp index 395e01d37d..a0b10a2bc1 100644 --- a/submodules/ton/tonlib-src/crypto/vm/vm.cpp +++ b/submodules/ton/tonlib-src/crypto/vm/vm.cpp @@ -72,6 +72,32 @@ VmState::VmState(Ref _code, Ref _stack, const GasLimits& gas, init_cregs(flags & 1, flags & 2); } +void VmState::init_cregs(bool same_c3, bool push_0) { + cr.set_c0(quit0); + cr.set_c1(quit1); + cr.set_c2(Ref{true}); + if (same_c3) { + cr.set_c3(Ref{true, code, cp}); + if (push_0) { + VM_LOG(this) << "implicit PUSH 0 at start\n"; + get_stack().push_smallint(0); + } + } else { + cr.set_c3(Ref{true, 11}); + } + if (cr.d[0].is_null() || cr.d[1].is_null()) { + auto empty_cell = CellBuilder{}.finalize(); + for (int i = 0; i < ControlRegs::dreg_num; i++) { + if (cr.d[i].is_null()) { + cr.d[i] = empty_cell; + } + } + } + if (cr.c7.is_null()) { + cr.set_c7(Ref{true}); + } +} + Ref VmState::convert_code_cell(Ref code_cell) { if (code_cell.is_null()) { return {}; @@ -176,8 +202,10 @@ int VmState::call(Ref cont, int pass_args, int ret_args) { if (skip > 0) { get_stack().pop_many(skip); } + consume_stack_gas(new_stk); } else if (copy >= 0) { new_stk = get_stack().split_top(copy, skip); + consume_stack_gas(new_stk); } else { new_stk = std::move(stack); stack.clear(); @@ -196,7 +224,13 @@ int VmState::call(Ref cont, int pass_args, int ret_args) { throw VmError{Excno::stk_und, "stack underflow while calling a continuation: not enough arguments on stack"}; } // create new stack from the top `pass_args` elements of the current stack - Ref new_stk = (pass_args >= 0 ? get_stack().split_top(pass_args) : std::move(stack)); + Ref new_stk; + if (pass_args >= 0) { + new_stk = get_stack().split_top(pass_args); + consume_stack_gas(new_stk); + } else { + new_stk = std::move(stack); + } // create return continuation using the remainder of the current stack Ref ret = Ref{true, std::move(code), cp, std::move(stack), ret_args}; ret.unique_write().get_cdata()->save.set_c0(std::move(cr.c[0])); @@ -251,10 +285,12 @@ int VmState::jump(Ref cont, int pass_args) { new_stk = cont_data->stack; } new_stk.write().move_from_stack(get_stack(), copy); + consume_stack_gas(new_stk); set_stack(std::move(new_stk)); } else { - if (copy >= 0) { + if (copy >= 0 && copy < stack->depth()) { get_stack().drop_bottom(stack->depth() - copy); + consume_stack_gas(copy); } } return jump_to(std::move(cont)); @@ -264,8 +300,10 @@ int VmState::jump(Ref cont, int pass_args) { int depth = get_stack().depth(); if (pass_args > depth) { throw VmError{Excno::stk_und, "stack underflow while jumping to a continuation: not enough arguments on stack"}; + } else if (pass_args < depth) { + get_stack().drop_bottom(depth - pass_args); + consume_stack_gas(pass_args); } - get_stack().drop_bottom(depth - pass_args); } return jump_to(std::move(cont)); } @@ -295,6 +333,22 @@ int VmState::ret_alt(int ret_args) { return jump(std::move(cont), ret_args); } +Ref VmState::c1_envelope(Ref cont, bool save) { + if (save) { + force_cregs(cont)->define_c1(cr.c[1]); + force_cregs(cont)->define_c0(cr.c[0]); + } + set_c1(cont); + return cont; +} + +void VmState::c1_save_set(bool save) { + if (save) { + force_cregs(cr.c[0])->define_c1(cr.c[1]); + } + set_c1(cr.c[0]); +} + Ref VmState::extract_cc(int save_cr, int stack_copy, int cc_args) { Ref new_stk; if (stack_copy < 0 || stack_copy == stack->depth()) { @@ -303,6 +357,7 @@ Ref VmState::extract_cc(int save_cr, int stack_copy, int cc_args) { } else if (stack_copy > 0) { stack->check_underflow(stack_copy); new_stk = get_stack().split_top(stack_copy); + consume_stack_gas(new_stk); } else { new_stk = Ref{true}; } @@ -332,7 +387,7 @@ int VmState::throw_exception(int excno) { stack_ref.push_smallint(0); stack_ref.push_smallint(excno); code.clear(); - consume_gas(exception_gas_price); + gas.consume_chk(exception_gas_price); return jump(get_c2()); } @@ -342,7 +397,7 @@ int VmState::throw_exception(int excno, StackEntry&& arg) { stack_ref.push(std::move(arg)); stack_ref.push_smallint(excno); code.clear(); - consume_gas(exception_gas_price); + gas.consume_chk(exception_gas_price); return jump(get_c2()); } @@ -375,7 +430,7 @@ void VmState::change_gas_limit(long long new_limit) { } int VmState::step() { - assert(!code.is_null()); + CHECK(code.not_null() && stack.not_null()); //VM_LOG(st) << "stack:"; stack->dump(VM_LOG(st)); //VM_LOG(st) << "; cr0.refcnt = " << get_c0()->get_refcnt() - 1 << std::endl; if (stack_trace) { @@ -397,13 +452,13 @@ int VmState::step() { } int VmState::run() { - if (code.is_null()) { - throw VmError{Excno::fatal, "cannot run an uninitialized VM"}; + if (code.is_null() || stack.is_null()) { + // throw VmError{Excno::fatal, "cannot run an uninitialized VM"}; + return (int)Excno::fatal; // no ~ for unhandled exceptions } int res; Guard guard(this); do { - // LOG(INFO) << "[BS] data cells: " << DataCell::get_total_data_cells(); try { try { try { @@ -419,12 +474,10 @@ int VmState::run() { } catch (const VmError& vme) { VM_LOG(this) << "handling exception code " << vme.get_errno() << ": " << vme.get_msg(); try { - // LOG(INFO) << "[EX] data cells: " << DataCell::get_total_data_cells(); ++steps; res = throw_exception(vme.get_errno()); } catch (const VmError& vme2) { VM_LOG(this) << "exception " << vme2.get_errno() << " while handling exception: " << vme.get_msg(); - // LOG(INFO) << "[EXX] data cells: " << DataCell::get_total_data_cells(); return ~vme2.get_errno(); } } @@ -437,7 +490,6 @@ int VmState::run() { return vmoog.get_errno(); // no ~ for unhandled exceptions (to make their faking impossible) } } while (!res); - // LOG(INFO) << "[EN] data cells: " << DataCell::get_total_data_cells(); if ((res | 1) == -1 && !try_commit()) { VM_LOG(this) << "automatic commit failed (new data or action cells too deep)"; get_stack().clear(); diff --git a/submodules/ton/tonlib-src/crypto/vm/vm.h b/submodules/ton/tonlib-src/crypto/vm/vm.h index 19c3829f11..0fef964284 100644 --- a/submodules/ton/tonlib-src/crypto/vm/vm.h +++ b/submodules/ton/tonlib-src/crypto/vm/vm.h @@ -106,6 +106,8 @@ class VmState final : public VmStateInterface { tuple_entry_gas_price = 1, implicit_jmpref_gas_price = 10, implicit_ret_gas_price = 5, + free_stack_depth = 32, + stack_entry_gas_price = 1, max_data_depth = 512 }; VmState(); @@ -141,11 +143,19 @@ class VmState final : public VmStateInterface { void consume_tuple_gas(unsigned tuple_len) { consume_gas(tuple_len * tuple_entry_gas_price); } - void consume_tuple_gas(const Ref& tup) { + void consume_tuple_gas(const Ref& tup) { if (tup.not_null()) { consume_tuple_gas((unsigned)tup->size()); } } + void consume_stack_gas(unsigned stack_depth) { + consume_gas((std::max(stack_depth, (unsigned)free_stack_depth) - free_stack_depth) * stack_entry_gas_price); + } + void consume_stack_gas(const Ref& stk) { + if (stk.not_null()) { + consume_stack_gas((unsigned)stk->depth()); + } + } GasLimits get_gas_limits() const { return gas; } @@ -287,6 +297,11 @@ class VmState final : public VmStateInterface { int throw_exception(int excno, StackEntry&& arg); int throw_exception(int excno); Ref extract_cc(int save_cr = 1, int stack_copy = -1, int cc_args = -1); + Ref c1_envelope(Ref cont, bool save = true); + Ref c1_envelope_if(bool cond, Ref cont, bool save = true) { + return cond ? c1_envelope(std::move(cont), save) : std::move(cont); + } + void c1_save_set(bool save = true); void fatal(void) const { throw VmFatal{}; } @@ -303,6 +318,9 @@ class VmState final : public VmStateInterface { bool get_chksig_always_succeed() const { return chksig_always_succeed; } + Ref ref_to_cont(Ref cell) const { + return td::make_ref(load_cell_slice_ref(std::move(cell)), get_cp()); + } private: void init_cregs(bool same_c3 = false, bool push_0 = true); diff --git a/submodules/ton/tonlib-src/tddb/td/db/RocksDb.cpp b/submodules/ton/tonlib-src/tddb/td/db/RocksDb.cpp index 47fdf4f5c2..e99cd43617 100644 --- a/submodules/ton/tonlib-src/tddb/td/db/RocksDb.cpp +++ b/submodules/ton/tonlib-src/tddb/td/db/RocksDb.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include "td/db/RocksDb.h" @@ -162,30 +162,32 @@ Result RocksDb::count(Slice prefix) { } Status RocksDb::begin_transaction() { - write_batch_ = std::make_unique(); - //transaction_.reset(db_->BeginTransaction({}, {})); + //write_batch_ = std::make_unique(); + rocksdb::WriteOptions options; + options.sync = true; + transaction_.reset(db_->BeginTransaction(options, {})); return Status::OK(); } Status RocksDb::commit_transaction() { - CHECK(write_batch_); - auto write_batch = std::move(write_batch_); - rocksdb::WriteOptions options; - options.sync = true; - TRY_STATUS(from_rocksdb(db_->Write(options, write_batch.get()))); - return Status::OK(); + //CHECK(write_batch_); + //auto write_batch = std::move(write_batch_); + //rocksdb::WriteOptions options; + //options.sync = true; + //TRY_STATUS(from_rocksdb(db_->Write(options, write_batch.get()))); + //return Status::OK(); - //CHECK(transaction_); - //auto res = from_rocksdb(transaction_->Commit()); - //transaction_.reset(); - //return res; + CHECK(transaction_); + auto res = from_rocksdb(transaction_->Commit()); + transaction_.reset(); + return res; } Status RocksDb::abort_transaction() { - CHECK(write_batch_); - write_batch_.reset(); - //CHECK(transaction_); - //transaction_.reset(); + //CHECK(write_batch_); + //write_batch_.reset(); + CHECK(transaction_); + transaction_.reset(); return Status::OK(); } diff --git a/submodules/ton/tonlib-src/tddb/test/key_value.cpp b/submodules/ton/tonlib-src/tddb/test/key_value.cpp index cf147e5721..c7d3c8f3fc 100644 --- a/submodules/ton/tonlib-src/tddb/test/key_value.cpp +++ b/submodules/ton/tonlib-src/tddb/test/key_value.cpp @@ -32,7 +32,11 @@ TEST(KeyValue, simple) { td::RocksDb::destroy(db_name).ignore(); std::unique_ptr kv = std::make_unique(td::RocksDb::open(db_name.str()).move_as_ok()); - auto set_value = [&](td::Slice key, td::Slice value) { kv->set(key, value); }; + auto set_value = [&](td::Slice key, td::Slice value) { + kv->begin_transaction(); + kv->set(key, value); + kv->commit_transaction(); + }; auto ensure_value = [&](td::Slice key, td::Slice value) { std::string kv_value; auto status = kv->get(key, kv_value).move_as_ok(); diff --git a/submodules/ton/tonlib-src/tdutils/td/utils/crypto.cpp b/submodules/ton/tonlib-src/tdutils/td/utils/crypto.cpp index 3898345f6d..d8a0d7b68b 100644 --- a/submodules/ton/tonlib-src/tdutils/td/utils/crypto.cpp +++ b/submodules/ton/tonlib-src/tdutils/td/utils/crypto.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #include "td/utils/crypto.h" @@ -299,16 +299,16 @@ void aes_cbc_decrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlic aes_cbc_xcrypt(aes_key, aes_iv, from, to, false); } -AesCbcState::AesCbcState(Slice key256, Slice iv128) : key_(key256), iv_(iv128) { - CHECK(key_.size() == 32); - CHECK(iv_.size() == 16); +AesCbcState::AesCbcState(Slice key256, Slice iv128) : raw_{td::SecureString(key256), td::SecureString(iv128)} { + CHECK(raw_.key.size() == 32); + CHECK(raw_.iv.size() == 16); } void AesCbcState::encrypt(Slice from, MutableSlice to) { - ::td::aes_cbc_encrypt(key_.as_slice(), iv_.as_mutable_slice(), from, to); + ::td::aes_cbc_encrypt(raw_.key.as_slice(), raw_.iv.as_mutable_slice(), from, to); } void AesCbcState::decrypt(Slice from, MutableSlice to) { - ::td::aes_cbc_decrypt(key_.as_slice(), iv_.as_mutable_slice(), from, to); + ::td::aes_cbc_decrypt(raw_.key.as_slice(), raw_.iv.as_mutable_slice(), from, to); } class AesCtrState::Impl { diff --git a/submodules/ton/tonlib-src/tdutils/td/utils/crypto.h b/submodules/ton/tonlib-src/tdutils/td/utils/crypto.h index 3cc0e9ab2d..b1e9777c27 100644 --- a/submodules/ton/tonlib-src/tdutils/td/utils/crypto.h +++ b/submodules/ton/tonlib-src/tdutils/td/utils/crypto.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once @@ -65,10 +65,17 @@ class AesCbcState { void encrypt(Slice from, MutableSlice to); void decrypt(Slice from, MutableSlice to); + struct Raw { + SecureString key; + SecureString iv; + }; + + const Raw &raw() const { + return raw_; + } private: - SecureString key_; - SecureString iv_; + Raw raw_; }; void sha1(Slice data, unsigned char output[20]); diff --git a/submodules/ton/tonlib-src/test/regression-tests.ans b/submodules/ton/tonlib-src/test/regression-tests.ans index f58e3ee10d..93fa16aee9 100644 --- a/submodules/ton/tonlib-src/test/regression-tests.ans +++ b/submodules/ton/tonlib-src/test/regression-tests.ans @@ -27,15 +27,18 @@ Test_Fift_testvmprog_default e5d0b2c68ee568280877c8495be558bfd0054ca5d99a99eebb5 Test_RefInt_main_default 768493e0aef8e09a401a6d369edd1ef503a9215fb09dc460f52b27a8bde767cb Test_VM_assert_code_not_null_default 05bc07e129181c972b976442f200de9487dee8bfb5ac53dd36ff61c5d4d4291d Test_VM_assert_extract_minmax_key_default c352309c61bdf62ba7a0ba7280d303c88b0696fe7efa550c05feb2c662275297 -Test_VM_assert_lookup_prefix_default 18e4fd70d6fa718bd352a6edf5d550a51355d4fb6f2fac58860a646c27a29bc9 +Test_VM_assert_lookup_prefix_default c5b45999b46d324e4008c07e5ce671bbcd833f4e15fb21a4a5136f7b980ca6fc Test_VM_assert_pfx_dict_lookup_default fa6e3f96b31cf2ed9a9dac6b279ec05acfedf13b8ed7b815789f167d1ed7352f Test_VM_bigint_default feeb473a4ac51133989e1c145d0f49defa77117d2ae8b66bd7d12e3579e91b9f Test_VM_bug_div_short_any_default f69aca6873f75d53dd37b6952151a2d858407a04589330762827dbc96d8b7c04 Test_VM_bug_exec_dict_getnear_default db314c2e25b49c1f7f044d271e225f36da546c66242a8ab12f6afae37628a81e Test_VM_bug_stack_overflow_default 7e0e3e96ca438ac96648d569c55213aa82154cf004e80265b1c481b1c4219719 +Test_VM_infinity_loop_1_default 670beda76229922806805e558d50d8f320017c642c3e7e34a7e1f2b7edb83cee +Test_VM_infinity_loop_2_default 22d9bd8cb41ff7b6cced5825e4ab73275b2fc07b1e3cd4588de815e2e6df2963 Test_VM_memory_leak_default e10dc118f3538720a16bcbd39be9a68c3ea07f76b3d2ed5719a5e866d91f0ab3 Test_VM_memory_leak_new_default fd2eec0a1d5ae49fb5ff8ba4b938fd9d0fe330be4a07b2b8be12bab249b00d90 Test_VM_memory_leak_old_default f3076ae38d14000c021597b824d2f0e51de4f00601429ec3e23cca1b32dba844 +Test_VM_oom_1_default 90862ddf3270840fbc9263c003c628ddd4a8bf6548b9bd3d53eb35a5c34bc325 Test_VM_report3_1_default 7bc6a8e66f9a0e40cd131e9829ff36fed16b464170d27c0b365a3f549df57282 Test_VM_report3_2_default 2231bc352cf431e72a84abad2261969bd5b0ee3d9051bb7a53b69fd8ea05f951 Test_VM_report3_3_default 9416187eb0600ed247795837ca820bccaffb39841bd9d2ff625816bfbba35d6d @@ -52,6 +55,8 @@ Test_VM_report3_loop_6_default 5c35b92144debdb61b2020d690669bffbdd96f75ecde827fd Test_VM_report3_qnot_default dc280444c7e3886cc3412f96f44c803c45287a07fcb9c638643e21bcdfe3905d Test_VM_simple_default f6733549069427c2beb1a85ee25635540e27aa68cb8ad101d8435e19afeae862 Test_VM_unhandled_exception_1_default 0abe2740dd3b6a6b91eb67fee573f638086fecc72653d2d81c956782186b5d78 +Test_VM_unhandled_exception_2_default 5ca67db5a0e957cc106bb47b744177ca959632a352f3629df376c34cbf03d51b +Test_VM_unhandled_exception_3_default b354e897e35a1177fd66d2c6ad7d77ae33a4e18f8678a518d79fea1388853307 Test_VM_unhandled_exception_4_default 412cbfe13745fde55cdcc5e41d7b15ba4d09f0e723f8e4421ae0b7066ca07b8f Test_VM_unhandled_exception_5_default d760e540cd9c200c207f71c540cdaf06d11c96e32ec19860b9c1046cb1e38855 Test_base64_main_default e90d541bd810871c4a81e162f1fffb555024b72807cb895414d16bc11494b789 diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp index b23e07ced9..94e392f6d7 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.cpp @@ -92,6 +92,8 @@ object_ptr Object::fetch(td::TlParser &p) { return adnl_address_udp::fetch(p); case adnl_address_udp6::ID: return adnl_address_udp6::fetch(p); + case adnl_address_tunnel::ID: + return adnl_address_tunnel::fetch(p); case adnl_addressList::ID: return adnl_addressList::fetch(p); case adnl_message_createChannel::ID: @@ -122,10 +124,20 @@ object_ptr Object::fetch(td::TlParser &p) { return adnl_proxy_none::fetch(p); case adnl_proxy_fast::ID: return adnl_proxy_fast::fetch(p); + case adnl_proxyControlPacketPing::ID: + return adnl_proxyControlPacketPing::fetch(p); + case adnl_proxyControlPacketPong::ID: + return adnl_proxyControlPacketPong::fetch(p); + case adnl_proxyControlPacketRegister::ID: + return adnl_proxyControlPacketRegister::fetch(p); + case adnl_proxyPacketHeader::ID: + return adnl_proxyPacketHeader::fetch(p); case adnl_proxyToFastHash::ID: return adnl_proxyToFastHash::fetch(p); case adnl_proxyToFast::ID: return adnl_proxyToFast::fetch(p); + case adnl_tunnelPacketContents::ID: + return adnl_tunnelPacketContents::fetch(p); case adnl_config_global::ID: return adnl_config_global::fetch(p); case adnl_db_node_key::ID: @@ -2225,6 +2237,8 @@ object_ptr adnl_Address::fetch(td::TlParser &p) { return adnl_address_udp::fetch(p); case adnl_address_udp6::ID: return adnl_address_udp6::fetch(p); + case adnl_address_tunnel::ID: + return adnl_address_tunnel::fetch(p); default: FAIL(PSTRING() << "Unknown constructor found " << td::format::as_hex(constructor)); } @@ -2319,6 +2333,50 @@ void adnl_address_udp6::store(td::TlStorerToString &s, const char *field_name) c } } +adnl_address_tunnel::adnl_address_tunnel() + : to_() + , pubkey_() +{} + +adnl_address_tunnel::adnl_address_tunnel(td::Bits256 const &to_, object_ptr &&pubkey_) + : to_(to_) + , pubkey_(std::move(pubkey_)) +{} + +const std::int32_t adnl_address_tunnel::ID; + +object_ptr adnl_address_tunnel::fetch(td::TlParser &p) { + return make_object(p); +} + +adnl_address_tunnel::adnl_address_tunnel(td::TlParser &p) +#define FAIL(error) p.set_error(error) + : to_(TlFetchInt256::parse(p)) + , pubkey_(TlFetchObject::parse(p)) +#undef FAIL +{} + +void adnl_address_tunnel::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + TlStoreBinary::store(to_, s); + TlStoreBoxedUnknown::store(pubkey_, s); +} + +void adnl_address_tunnel::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + TlStoreBinary::store(to_, s); + TlStoreBoxedUnknown::store(pubkey_, s); +} + +void adnl_address_tunnel::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "adnl_address_tunnel"); + s.store_field("to", to_); + if (pubkey_ == nullptr) { s.store_field("pubkey", "null"); } else { pubkey_->store(s, "pubkey"); } + s.store_class_end(); + } +} + adnl_addressList::adnl_addressList() : addrs_() , version_() @@ -3017,8 +3075,13 @@ object_ptr adnl_Proxy::fetch(td::TlParser &p) { #undef FAIL } -adnl_proxy_none::adnl_proxy_none() { -} +adnl_proxy_none::adnl_proxy_none() + : id_() +{} + +adnl_proxy_none::adnl_proxy_none(td::Bits256 const &id_) + : id_(id_) +{} const std::int32_t adnl_proxy_none::ID; @@ -3028,32 +3091,36 @@ object_ptr adnl_proxy_none::fetch(td::TlParser &p) { adnl_proxy_none::adnl_proxy_none(td::TlParser &p) #define FAIL(error) p.set_error(error) + : id_(TlFetchInt256::parse(p)) #undef FAIL -{ - (void)p; -} +{} void adnl_proxy_none::store(td::TlStorerCalcLength &s) const { (void)sizeof(s); + TlStoreBinary::store(id_, s); } void adnl_proxy_none::store(td::TlStorerUnsafe &s) const { (void)sizeof(s); + TlStoreBinary::store(id_, s); } void adnl_proxy_none::store(td::TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "adnl_proxy_none"); + s.store_field("id", id_); s.store_class_end(); } } adnl_proxy_fast::adnl_proxy_fast() - : shared_secret_() + : id_() + , shared_secret_() {} -adnl_proxy_fast::adnl_proxy_fast(td::BufferSlice &&shared_secret_) - : shared_secret_(std::move(shared_secret_)) +adnl_proxy_fast::adnl_proxy_fast(td::Bits256 const &id_, td::BufferSlice &&shared_secret_) + : id_(id_) + , shared_secret_(std::move(shared_secret_)) {} const std::int32_t adnl_proxy_fast::ID; @@ -3064,28 +3131,251 @@ object_ptr adnl_proxy_fast::fetch(td::TlParser &p) { adnl_proxy_fast::adnl_proxy_fast(td::TlParser &p) #define FAIL(error) p.set_error(error) - : shared_secret_(TlFetchBytes::parse(p)) + : id_(TlFetchInt256::parse(p)) + , shared_secret_(TlFetchBytes::parse(p)) #undef FAIL {} void adnl_proxy_fast::store(td::TlStorerCalcLength &s) const { (void)sizeof(s); + TlStoreBinary::store(id_, s); TlStoreString::store(shared_secret_, s); } void adnl_proxy_fast::store(td::TlStorerUnsafe &s) const { (void)sizeof(s); + TlStoreBinary::store(id_, s); TlStoreString::store(shared_secret_, s); } void adnl_proxy_fast::store(td::TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "adnl_proxy_fast"); + s.store_field("id", id_); s.store_bytes_field("shared_secret", shared_secret_); s.store_class_end(); } } +object_ptr adnl_ProxyControlPacket::fetch(td::TlParser &p) { +#define FAIL(error) p.set_error(error); return nullptr; + int constructor = p.fetch_int(); + switch (constructor) { + case adnl_proxyControlPacketPing::ID: + return adnl_proxyControlPacketPing::fetch(p); + case adnl_proxyControlPacketPong::ID: + return adnl_proxyControlPacketPong::fetch(p); + case adnl_proxyControlPacketRegister::ID: + return adnl_proxyControlPacketRegister::fetch(p); + default: + FAIL(PSTRING() << "Unknown constructor found " << td::format::as_hex(constructor)); + } +#undef FAIL +} + +adnl_proxyControlPacketPing::adnl_proxyControlPacketPing() + : id_() +{} + +adnl_proxyControlPacketPing::adnl_proxyControlPacketPing(td::Bits256 const &id_) + : id_(id_) +{} + +const std::int32_t adnl_proxyControlPacketPing::ID; + +object_ptr adnl_proxyControlPacketPing::fetch(td::TlParser &p) { + return make_object(p); +} + +adnl_proxyControlPacketPing::adnl_proxyControlPacketPing(td::TlParser &p) +#define FAIL(error) p.set_error(error) + : id_(TlFetchInt256::parse(p)) +#undef FAIL +{} + +void adnl_proxyControlPacketPing::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + TlStoreBinary::store(id_, s); +} + +void adnl_proxyControlPacketPing::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + TlStoreBinary::store(id_, s); +} + +void adnl_proxyControlPacketPing::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "adnl_proxyControlPacketPing"); + s.store_field("id", id_); + s.store_class_end(); + } +} + +adnl_proxyControlPacketPong::adnl_proxyControlPacketPong() + : id_() +{} + +adnl_proxyControlPacketPong::adnl_proxyControlPacketPong(td::Bits256 const &id_) + : id_(id_) +{} + +const std::int32_t adnl_proxyControlPacketPong::ID; + +object_ptr adnl_proxyControlPacketPong::fetch(td::TlParser &p) { + return make_object(p); +} + +adnl_proxyControlPacketPong::adnl_proxyControlPacketPong(td::TlParser &p) +#define FAIL(error) p.set_error(error) + : id_(TlFetchInt256::parse(p)) +#undef FAIL +{} + +void adnl_proxyControlPacketPong::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + TlStoreBinary::store(id_, s); +} + +void adnl_proxyControlPacketPong::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + TlStoreBinary::store(id_, s); +} + +void adnl_proxyControlPacketPong::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "adnl_proxyControlPacketPong"); + s.store_field("id", id_); + s.store_class_end(); + } +} + +adnl_proxyControlPacketRegister::adnl_proxyControlPacketRegister() + : ip_() + , port_() +{} + +adnl_proxyControlPacketRegister::adnl_proxyControlPacketRegister(std::int32_t ip_, std::int32_t port_) + : ip_(ip_) + , port_(port_) +{} + +const std::int32_t adnl_proxyControlPacketRegister::ID; + +object_ptr adnl_proxyControlPacketRegister::fetch(td::TlParser &p) { + return make_object(p); +} + +adnl_proxyControlPacketRegister::adnl_proxyControlPacketRegister(td::TlParser &p) +#define FAIL(error) p.set_error(error) + : ip_(TlFetchInt::parse(p)) + , port_(TlFetchInt::parse(p)) +#undef FAIL +{} + +void adnl_proxyControlPacketRegister::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + TlStoreBinary::store(ip_, s); + TlStoreBinary::store(port_, s); +} + +void adnl_proxyControlPacketRegister::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + TlStoreBinary::store(ip_, s); + TlStoreBinary::store(port_, s); +} + +void adnl_proxyControlPacketRegister::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "adnl_proxyControlPacketRegister"); + s.store_field("ip", ip_); + s.store_field("port", port_); + s.store_class_end(); + } +} + +adnl_proxyPacketHeader::adnl_proxyPacketHeader() + : proxy_id_() + , flags_() + , ip_() + , port_() + , adnl_start_time_() + , seqno_() + , date_() + , signature_() +{} + +adnl_proxyPacketHeader::adnl_proxyPacketHeader(td::Bits256 const &proxy_id_, std::int32_t flags_, std::int32_t ip_, std::int32_t port_, std::int32_t adnl_start_time_, std::int64_t seqno_, std::int32_t date_, td::Bits256 const &signature_) + : proxy_id_(proxy_id_) + , flags_(flags_) + , ip_(ip_) + , port_(port_) + , adnl_start_time_(adnl_start_time_) + , seqno_(seqno_) + , date_(date_) + , signature_(signature_) +{} + +const std::int32_t adnl_proxyPacketHeader::ID; + +object_ptr adnl_proxyPacketHeader::fetch(td::TlParser &p) { +#define FAIL(error) p.set_error(error); return nullptr; + object_ptr res = make_object(); + std::int32_t var0; + res->proxy_id_ = TlFetchInt256::parse(p); + if ((var0 = res->flags_ = TlFetchInt::parse(p)) < 0) { FAIL("Variable of type # can't be negative"); } + if (var0 & 1) { res->ip_ = TlFetchInt::parse(p); } + if (var0 & 1) { res->port_ = TlFetchInt::parse(p); } + if (var0 & 2) { res->adnl_start_time_ = TlFetchInt::parse(p); } + if (var0 & 4) { res->seqno_ = TlFetchLong::parse(p); } + if (var0 & 8) { res->date_ = TlFetchInt::parse(p); } + res->signature_ = TlFetchInt256::parse(p); + if (p.get_error()) { FAIL(""); } + return res; +#undef FAIL +} + +void adnl_proxyPacketHeader::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + std::int32_t var0; + TlStoreBinary::store(proxy_id_, s); + TlStoreBinary::store((var0 = flags_), s); + if (var0 & 1) { TlStoreBinary::store(ip_, s); } + if (var0 & 1) { TlStoreBinary::store(port_, s); } + if (var0 & 2) { TlStoreBinary::store(adnl_start_time_, s); } + if (var0 & 4) { TlStoreBinary::store(seqno_, s); } + if (var0 & 8) { TlStoreBinary::store(date_, s); } + TlStoreBinary::store(signature_, s); +} + +void adnl_proxyPacketHeader::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + std::int32_t var0; + TlStoreBinary::store(proxy_id_, s); + TlStoreBinary::store((var0 = flags_), s); + if (var0 & 1) { TlStoreBinary::store(ip_, s); } + if (var0 & 1) { TlStoreBinary::store(port_, s); } + if (var0 & 2) { TlStoreBinary::store(adnl_start_time_, s); } + if (var0 & 4) { TlStoreBinary::store(seqno_, s); } + if (var0 & 8) { TlStoreBinary::store(date_, s); } + TlStoreBinary::store(signature_, s); +} + +void adnl_proxyPacketHeader::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "adnl_proxyPacketHeader"); + std::int32_t var0; + s.store_field("proxy_id", proxy_id_); + s.store_field("flags", (var0 = flags_)); + if (var0 & 1) { s.store_field("ip", ip_); } + if (var0 & 1) { s.store_field("port", port_); } + if (var0 & 2) { s.store_field("adnl_start_time", adnl_start_time_); } + if (var0 & 4) { s.store_field("seqno", seqno_); } + if (var0 & 8) { s.store_field("date", date_); } + s.store_field("signature", signature_); + s.store_class_end(); + } +} + adnl_proxyToFastHash::adnl_proxyToFastHash() : ip_() , port_() @@ -3204,6 +3494,89 @@ void adnl_proxyToFast::store(td::TlStorerToString &s, const char *field_name) co } } +adnl_tunnelPacketContents::adnl_tunnelPacketContents() + : rand1_() + , flags_() + , from_ip_() + , from_port_() + , message_() + , statistics_() + , payment_() + , rand2_() +{} + +adnl_tunnelPacketContents::adnl_tunnelPacketContents(td::BufferSlice &&rand1_, std::int32_t flags_, std::int32_t from_ip_, std::int32_t from_port_, td::BufferSlice &&message_, td::BufferSlice &&statistics_, td::BufferSlice &&payment_, td::BufferSlice &&rand2_) + : rand1_(std::move(rand1_)) + , flags_(flags_) + , from_ip_(from_ip_) + , from_port_(from_port_) + , message_(std::move(message_)) + , statistics_(std::move(statistics_)) + , payment_(std::move(payment_)) + , rand2_(std::move(rand2_)) +{} + +const std::int32_t adnl_tunnelPacketContents::ID; + +object_ptr adnl_tunnelPacketContents::fetch(td::TlParser &p) { +#define FAIL(error) p.set_error(error); return nullptr; + object_ptr res = make_object(); + std::int32_t var0; + res->rand1_ = TlFetchBytes::parse(p); + if ((var0 = res->flags_ = TlFetchInt::parse(p)) < 0) { FAIL("Variable of type # can't be negative"); } + if (var0 & 1) { res->from_ip_ = TlFetchInt::parse(p); } + if (var0 & 1) { res->from_port_ = TlFetchInt::parse(p); } + if (var0 & 2) { res->message_ = TlFetchBytes::parse(p); } + if (var0 & 4) { res->statistics_ = TlFetchBytes::parse(p); } + if (var0 & 8) { res->payment_ = TlFetchBytes::parse(p); } + res->rand2_ = TlFetchBytes::parse(p); + if (p.get_error()) { FAIL(""); } + return res; +#undef FAIL +} + +void adnl_tunnelPacketContents::store(td::TlStorerCalcLength &s) const { + (void)sizeof(s); + std::int32_t var0; + TlStoreString::store(rand1_, s); + TlStoreBinary::store((var0 = flags_), s); + if (var0 & 1) { TlStoreBinary::store(from_ip_, s); } + if (var0 & 1) { TlStoreBinary::store(from_port_, s); } + if (var0 & 2) { TlStoreString::store(message_, s); } + if (var0 & 4) { TlStoreString::store(statistics_, s); } + if (var0 & 8) { TlStoreString::store(payment_, s); } + TlStoreString::store(rand2_, s); +} + +void adnl_tunnelPacketContents::store(td::TlStorerUnsafe &s) const { + (void)sizeof(s); + std::int32_t var0; + TlStoreString::store(rand1_, s); + TlStoreBinary::store((var0 = flags_), s); + if (var0 & 1) { TlStoreBinary::store(from_ip_, s); } + if (var0 & 1) { TlStoreBinary::store(from_port_, s); } + if (var0 & 2) { TlStoreString::store(message_, s); } + if (var0 & 4) { TlStoreString::store(statistics_, s); } + if (var0 & 8) { TlStoreString::store(payment_, s); } + TlStoreString::store(rand2_, s); +} + +void adnl_tunnelPacketContents::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "adnl_tunnelPacketContents"); + std::int32_t var0; + s.store_bytes_field("rand1", rand1_); + s.store_field("flags", (var0 = flags_)); + if (var0 & 1) { s.store_field("from_ip", from_ip_); } + if (var0 & 1) { s.store_field("from_port", from_port_); } + if (var0 & 2) { s.store_bytes_field("message", message_); } + if (var0 & 4) { s.store_bytes_field("statistics", statistics_); } + if (var0 & 8) { s.store_bytes_field("payment", payment_); } + s.store_bytes_field("rand2", rand2_); + s.store_class_end(); + } +} + adnl_config_global::adnl_config_global() : static_nodes_() {} diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h index 6187d3f427..ca0276abee 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.h @@ -78,10 +78,16 @@ class adnl_pong; class adnl_Proxy; +class adnl_ProxyControlPacket; + +class adnl_proxyPacketHeader; + class adnl_proxyToFastHash; class adnl_proxyToFast; +class adnl_tunnelPacketContents; + class adnl_config_global; class adnl_db_node_key; @@ -1279,6 +1285,31 @@ class adnl_address_udp6 final : public adnl_Address { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class adnl_address_tunnel final : public adnl_Address { + public: + td::Bits256 to_; + object_ptr pubkey_; + + adnl_address_tunnel(); + + adnl_address_tunnel(td::Bits256 const &to_, object_ptr &&pubkey_); + + static const std::int32_t ID = 153813739; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit adnl_address_tunnel(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class adnl_addressList final : public Object { public: std::vector> addrs_; @@ -1629,10 +1660,13 @@ class adnl_Proxy: public Object { class adnl_proxy_none final : public adnl_Proxy { public: + td::Bits256 id_; adnl_proxy_none(); - static const std::int32_t ID = -90551726; + explicit adnl_proxy_none(td::Bits256 const &id_); + + static const std::int32_t ID = 892487803; std::int32_t get_id() const final { return ID; } @@ -1650,13 +1684,14 @@ class adnl_proxy_none final : public adnl_Proxy { class adnl_proxy_fast final : public adnl_Proxy { public: + td::Bits256 id_; td::BufferSlice shared_secret_; adnl_proxy_fast(); - explicit adnl_proxy_fast(td::BufferSlice &&shared_secret_); + adnl_proxy_fast(td::Bits256 const &id_, td::BufferSlice &&shared_secret_); - static const std::int32_t ID = 554536094; + static const std::int32_t ID = 982205877; std::int32_t get_id() const final { return ID; } @@ -1672,6 +1707,115 @@ class adnl_proxy_fast final : public adnl_Proxy { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class adnl_ProxyControlPacket: public Object { + public: + + static object_ptr fetch(td::TlParser &p); +}; + +class adnl_proxyControlPacketPing final : public adnl_ProxyControlPacket { + public: + td::Bits256 id_; + + adnl_proxyControlPacketPing(); + + explicit adnl_proxyControlPacketPing(td::Bits256 const &id_); + + static const std::int32_t ID = 932635723; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit adnl_proxyControlPacketPing(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class adnl_proxyControlPacketPong final : public adnl_ProxyControlPacket { + public: + td::Bits256 id_; + + adnl_proxyControlPacketPong(); + + explicit adnl_proxyControlPacketPong(td::Bits256 const &id_); + + static const std::int32_t ID = 1272044540; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit adnl_proxyControlPacketPong(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class adnl_proxyControlPacketRegister final : public adnl_ProxyControlPacket { + public: + std::int32_t ip_; + std::int32_t port_; + + adnl_proxyControlPacketRegister(); + + adnl_proxyControlPacketRegister(std::int32_t ip_, std::int32_t port_); + + static const std::int32_t ID = -1022774721; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + explicit adnl_proxyControlPacketRegister(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class adnl_proxyPacketHeader final : public Object { + public: + td::Bits256 proxy_id_; + std::int32_t flags_; + std::int32_t ip_; + std::int32_t port_; + std::int32_t adnl_start_time_; + std::int64_t seqno_; + std::int32_t date_; + td::Bits256 signature_; + enum Flags : std::int32_t {IP_MASK = 1, PORT_MASK = 1, ADNL_START_TIME_MASK = 2, SEQNO_MASK = 4, DATE_MASK = 8}; + + adnl_proxyPacketHeader(); + + adnl_proxyPacketHeader(td::Bits256 const &proxy_id_, std::int32_t flags_, std::int32_t ip_, std::int32_t port_, std::int32_t adnl_start_time_, std::int64_t seqno_, std::int32_t date_, td::Bits256 const &signature_); + + static const std::int32_t ID = 141114488; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class adnl_proxyToFastHash final : public Object { public: std::int32_t ip_; @@ -1727,6 +1871,36 @@ class adnl_proxyToFast final : public Object { void store(td::TlStorerToString &s, const char *field_name) const final; }; +class adnl_tunnelPacketContents final : public Object { + public: + td::BufferSlice rand1_; + std::int32_t flags_; + std::int32_t from_ip_; + std::int32_t from_port_; + td::BufferSlice message_; + td::BufferSlice statistics_; + td::BufferSlice payment_; + td::BufferSlice rand2_; + enum Flags : std::int32_t {FROM_IP_MASK = 1, FROM_PORT_MASK = 1, MESSAGE_MASK = 2, STATISTICS_MASK = 4, PAYMENT_MASK = 8}; + + adnl_tunnelPacketContents(); + + adnl_tunnelPacketContents(td::BufferSlice &&rand1_, std::int32_t flags_, std::int32_t from_ip_, std::int32_t from_port_, td::BufferSlice &&message_, td::BufferSlice &&statistics_, td::BufferSlice &&payment_, td::BufferSlice &&rand2_); + + static const std::int32_t ID = -980338508; + std::int32_t get_id() const final { + return ID; + } + + static object_ptr fetch(td::TlParser &p); + + void store(td::TlStorerCalcLength &s) const final; + + void store(td::TlStorerUnsafe &s) const final; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + class adnl_config_global final : public Object { public: object_ptr static_nodes_; diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp index e4df697cbd..12ce4af376 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api.hpp @@ -116,6 +116,9 @@ bool downcast_call(Object &obj, const T &func) { case adnl_address_udp6::ID: func(static_cast(obj)); return true; + case adnl_address_tunnel::ID: + func(static_cast(obj)); + return true; case adnl_addressList::ID: func(static_cast(obj)); return true; @@ -161,12 +164,27 @@ bool downcast_call(Object &obj, const T &func) { case adnl_proxy_fast::ID: func(static_cast(obj)); return true; + case adnl_proxyControlPacketPing::ID: + func(static_cast(obj)); + return true; + case adnl_proxyControlPacketPong::ID: + func(static_cast(obj)); + return true; + case adnl_proxyControlPacketRegister::ID: + func(static_cast(obj)); + return true; + case adnl_proxyPacketHeader::ID: + func(static_cast(obj)); + return true; case adnl_proxyToFastHash::ID: func(static_cast(obj)); return true; case adnl_proxyToFast::ID: func(static_cast(obj)); return true; + case adnl_tunnelPacketContents::ID: + func(static_cast(obj)); + return true; case adnl_config_global::ID: func(static_cast(obj)); return true; @@ -1262,6 +1280,9 @@ bool downcast_call(adnl_Address &obj, const T &func) { case adnl_address_udp6::ID: func(static_cast(obj)); return true; + case adnl_address_tunnel::ID: + func(static_cast(obj)); + return true; default: return false; } @@ -1325,6 +1346,29 @@ bool downcast_call(adnl_Proxy &obj, const T &func) { } } +/** + * Calls specified function object with the specified object downcasted to the most-derived type. + * \param[in] obj Object to pass as an argument to the function object. + * \param[in] func Function object to which the object will be passed. + * \returns whether function object call has happened. Should always return true for correct parameters. + */ +template +bool downcast_call(adnl_ProxyControlPacket &obj, const T &func) { + switch (obj.get_id()) { + case adnl_proxyControlPacketPing::ID: + func(static_cast(obj)); + return true; + case adnl_proxyControlPacketPong::ID: + func(static_cast(obj)); + return true; + case adnl_proxyControlPacketRegister::ID: + func(static_cast(obj)); + return true; + default: + return false; + } +} + /** * Calls specified function object with the specified object downcasted to the most-derived type. * \param[in] obj Object to pass as an argument to the function object. diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp index 9cf8386668..c258df610b 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.cpp @@ -85,7 +85,8 @@ Result tl_constructor_from_string(ton_api::TestObject *object, const std: Result tl_constructor_from_string(ton_api::adnl_Address *object, const std::string &str) { static const std::unordered_map m = { {"adnl.address.udp", 1728947943}, - {"adnl.address.udp6", -484613126} + {"adnl.address.udp6", -484613126}, + {"adnl.address.tunnel", 153813739} }; auto it = m.find(str); if (it == m.end()) { @@ -112,8 +113,20 @@ Result tl_constructor_from_string(ton_api::adnl_Message *object, const st } Result tl_constructor_from_string(ton_api::adnl_Proxy *object, const std::string &str) { static const std::unordered_map m = { - {"adnl.proxy.none", -90551726}, - {"adnl.proxy.fast", 554536094} + {"adnl.proxy.none", 892487803}, + {"adnl.proxy.fast", 982205877} + }; + auto it = m.find(str); + if (it == m.end()) { + return Status::Error(str + "Unknown class"); + } + return it->second; +} +Result tl_constructor_from_string(ton_api::adnl_ProxyControlPacket *object, const std::string &str) { + static const std::unordered_map m = { + {"adnl.proxyControlPacketPing", 932635723}, + {"adnl.proxyControlPacketPong", 1272044540}, + {"adnl.proxyControlPacketRegister", -1022774721} }; auto it = m.find(str); if (it == m.end()) { @@ -557,6 +570,7 @@ Result tl_constructor_from_string(ton_api::Object *object, const std::str {"testVectorBytes", 1267407827}, {"adnl.address.udp", 1728947943}, {"adnl.address.udp6", -484613126}, + {"adnl.address.tunnel", 153813739}, {"adnl.addressList", 573040216}, {"adnl.message.createChannel", -428620869}, {"adnl.message.confirmChannel", 1625103721}, @@ -570,10 +584,15 @@ Result tl_constructor_from_string(ton_api::Object *object, const std::str {"adnl.nodes", -1576412330}, {"adnl.packetContents", -784151159}, {"adnl.pong", 544504846}, - {"adnl.proxy.none", -90551726}, - {"adnl.proxy.fast", 554536094}, + {"adnl.proxy.none", 892487803}, + {"adnl.proxy.fast", 982205877}, + {"adnl.proxyControlPacketPing", 932635723}, + {"adnl.proxyControlPacketPong", 1272044540}, + {"adnl.proxyControlPacketRegister", -1022774721}, + {"adnl.proxyPacketHeader", 141114488}, {"adnl.proxyToFastHash", -574752674}, {"adnl.proxyToFast", -1259462186}, + {"adnl.tunnelPacketContents", -980338508}, {"adnl.config.global", -1099988784}, {"adnl.db.node.key", -979114962}, {"adnl.db.node.value", 1415390983}, @@ -1361,6 +1380,21 @@ Status from_json(ton_api::adnl_address_udp6 &to, JsonObject &from) { } return Status::OK(); } +Status from_json(ton_api::adnl_address_tunnel &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "to", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.to_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "pubkey", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.pubkey_, value)); + } + } + return Status::OK(); +} Status from_json(ton_api::adnl_addressList &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "addrs", JsonValue::Type::Null, true)); @@ -1641,9 +1675,21 @@ Status from_json(ton_api::adnl_pong &to, JsonObject &from) { return Status::OK(); } Status from_json(ton_api::adnl_proxy_none &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.id_, value)); + } + } return Status::OK(); } Status from_json(ton_api::adnl_proxy_fast &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.id_, value)); + } + } { TRY_RESULT(value, get_json_object_field(from, "shared_secret", JsonValue::Type::Null, true)); if (value.type() != JsonValue::Type::Null) { @@ -1652,6 +1698,90 @@ Status from_json(ton_api::adnl_proxy_fast &to, JsonObject &from) { } return Status::OK(); } +Status from_json(ton_api::adnl_proxyControlPacketPing &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.id_, value)); + } + } + return Status::OK(); +} +Status from_json(ton_api::adnl_proxyControlPacketPong &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.id_, value)); + } + } + return Status::OK(); +} +Status from_json(ton_api::adnl_proxyControlPacketRegister &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "ip", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.ip_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "port", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.port_, value)); + } + } + return Status::OK(); +} +Status from_json(ton_api::adnl_proxyPacketHeader &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "proxy_id", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.proxy_id_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "flags", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.flags_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "ip", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.ip_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "port", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.port_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "adnl_start_time", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.adnl_start_time_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "seqno", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.seqno_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "date", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.date_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "signature", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.signature_, value)); + } + } + return Status::OK(); +} Status from_json(ton_api::adnl_proxyToFastHash &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "ip", JsonValue::Type::Null, true)); @@ -1712,6 +1842,57 @@ Status from_json(ton_api::adnl_proxyToFast &to, JsonObject &from) { } return Status::OK(); } +Status from_json(ton_api::adnl_tunnelPacketContents &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "rand1", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.rand1_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "flags", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.flags_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "from_ip", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.from_ip_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "from_port", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.from_port_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "message", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.message_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "statistics", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.statistics_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "payment", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.payment_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "rand2", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.rand2_, value)); + } + } + return Status::OK(); +} Status from_json(ton_api::adnl_config_global &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "static_nodes", JsonValue::Type::Null, true)); @@ -6499,6 +6680,14 @@ void to_json(JsonValueScope &jv, const ton_api::adnl_address_udp6 &object) { jo << ctie("ip", ToJson(object.ip_)); jo << ctie("port", ToJson(object.port_)); } +void to_json(JsonValueScope &jv, const ton_api::adnl_address_tunnel &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "adnl.address.tunnel"); + jo << ctie("to", ToJson(object.to_)); + if (object.pubkey_) { + jo << ctie("pubkey", ToJson(object.pubkey_)); + } +} void to_json(JsonValueScope &jv, const ton_api::adnl_addressList &object) { auto jo = jv.enter_object(); jo << ctie("@type", "adnl.addressList"); @@ -6616,12 +6805,47 @@ void to_json(JsonValueScope &jv, const ton_api::adnl_Proxy &object) { void to_json(JsonValueScope &jv, const ton_api::adnl_proxy_none &object) { auto jo = jv.enter_object(); jo << ctie("@type", "adnl.proxy.none"); + jo << ctie("id", ToJson(object.id_)); } void to_json(JsonValueScope &jv, const ton_api::adnl_proxy_fast &object) { auto jo = jv.enter_object(); jo << ctie("@type", "adnl.proxy.fast"); + jo << ctie("id", ToJson(object.id_)); jo << ctie("shared_secret", ToJson(JsonBytes{object.shared_secret_})); } +void to_json(JsonValueScope &jv, const ton_api::adnl_ProxyControlPacket &object) { + ton_api::downcast_call(const_cast(object), [&jv](const auto &object) { to_json(jv, object); }); +} +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyControlPacketPing &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "adnl.proxyControlPacketPing"); + jo << ctie("id", ToJson(object.id_)); +} +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyControlPacketPong &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "adnl.proxyControlPacketPong"); + jo << ctie("id", ToJson(object.id_)); +} +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyControlPacketRegister &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "adnl.proxyControlPacketRegister"); + jo << ctie("ip", ToJson(object.ip_)); + jo << ctie("port", ToJson(object.port_)); +} +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyPacketHeader &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "adnl.proxyPacketHeader"); + jo << ctie("proxy_id", ToJson(object.proxy_id_)); + if (object.flags_) { + jo << ctie("flags", ToJson(object.flags_)); + } + jo << ctie("ip", ToJson(object.ip_)); + jo << ctie("port", ToJson(object.port_)); + jo << ctie("adnl_start_time", ToJson(object.adnl_start_time_)); + jo << ctie("seqno", ToJson(JsonInt64{object.seqno_})); + jo << ctie("date", ToJson(object.date_)); + jo << ctie("signature", ToJson(object.signature_)); +} void to_json(JsonValueScope &jv, const ton_api::adnl_proxyToFastHash &object) { auto jo = jv.enter_object(); jo << ctie("@type", "adnl.proxyToFastHash"); @@ -6639,6 +6863,20 @@ void to_json(JsonValueScope &jv, const ton_api::adnl_proxyToFast &object) { jo << ctie("date", ToJson(object.date_)); jo << ctie("signature", ToJson(object.signature_)); } +void to_json(JsonValueScope &jv, const ton_api::adnl_tunnelPacketContents &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "adnl.tunnelPacketContents"); + jo << ctie("rand1", ToJson(JsonBytes{object.rand1_})); + if (object.flags_) { + jo << ctie("flags", ToJson(object.flags_)); + } + jo << ctie("from_ip", ToJson(object.from_ip_)); + jo << ctie("from_port", ToJson(object.from_port_)); + jo << ctie("message", ToJson(JsonBytes{object.message_})); + jo << ctie("statistics", ToJson(JsonBytes{object.statistics_})); + jo << ctie("payment", ToJson(JsonBytes{object.payment_})); + jo << ctie("rand2", ToJson(JsonBytes{object.rand2_})); +} void to_json(JsonValueScope &jv, const ton_api::adnl_config_global &object) { auto jo = jv.enter_object(); jo << ctie("@type", "adnl.config.global"); diff --git a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h index d7cc42728f..aa31ee45ed 100644 --- a/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h +++ b/submodules/ton/tonlib-src/tl/generate/auto/tl/ton_api_json.h @@ -18,6 +18,7 @@ Result tl_constructor_from_string(ton_api::TestObject *object, const std: Result tl_constructor_from_string(ton_api::adnl_Address *object, const std::string &str); Result tl_constructor_from_string(ton_api::adnl_Message *object, const std::string &str); Result tl_constructor_from_string(ton_api::adnl_Proxy *object, const std::string &str); +Result tl_constructor_from_string(ton_api::adnl_ProxyControlPacket *object, const std::string &str); Result tl_constructor_from_string(ton_api::catchain_BlockResult *object, const std::string &str); Result tl_constructor_from_string(ton_api::catchain_Difference *object, const std::string &str); Result tl_constructor_from_string(ton_api::catchain_block_inner_Data *object, const std::string &str); @@ -87,6 +88,7 @@ Status from_json(ton_api::testInt &to, JsonObject &from); Status from_json(ton_api::testVectorBytes &to, JsonObject &from); Status from_json(ton_api::adnl_address_udp &to, JsonObject &from); Status from_json(ton_api::adnl_address_udp6 &to, JsonObject &from); +Status from_json(ton_api::adnl_address_tunnel &to, JsonObject &from); Status from_json(ton_api::adnl_addressList &to, JsonObject &from); Status from_json(ton_api::adnl_message_createChannel &to, JsonObject &from); Status from_json(ton_api::adnl_message_confirmChannel &to, JsonObject &from); @@ -102,8 +104,13 @@ Status from_json(ton_api::adnl_packetContents &to, JsonObject &from); Status from_json(ton_api::adnl_pong &to, JsonObject &from); Status from_json(ton_api::adnl_proxy_none &to, JsonObject &from); Status from_json(ton_api::adnl_proxy_fast &to, JsonObject &from); +Status from_json(ton_api::adnl_proxyControlPacketPing &to, JsonObject &from); +Status from_json(ton_api::adnl_proxyControlPacketPong &to, JsonObject &from); +Status from_json(ton_api::adnl_proxyControlPacketRegister &to, JsonObject &from); +Status from_json(ton_api::adnl_proxyPacketHeader &to, JsonObject &from); Status from_json(ton_api::adnl_proxyToFastHash &to, JsonObject &from); Status from_json(ton_api::adnl_proxyToFast &to, JsonObject &from); +Status from_json(ton_api::adnl_tunnelPacketContents &to, JsonObject &from); Status from_json(ton_api::adnl_config_global &to, JsonObject &from); Status from_json(ton_api::adnl_db_node_key &to, JsonObject &from); Status from_json(ton_api::adnl_db_node_value &to, JsonObject &from); @@ -446,6 +453,7 @@ void to_json(JsonValueScope &jv, const ton_api::testVectorBytes &object); void to_json(JsonValueScope &jv, const ton_api::adnl_Address &object); void to_json(JsonValueScope &jv, const ton_api::adnl_address_udp &object); void to_json(JsonValueScope &jv, const ton_api::adnl_address_udp6 &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_address_tunnel &object); void to_json(JsonValueScope &jv, const ton_api::adnl_addressList &object); void to_json(JsonValueScope &jv, const ton_api::adnl_Message &object); void to_json(JsonValueScope &jv, const ton_api::adnl_message_createChannel &object); @@ -463,8 +471,14 @@ void to_json(JsonValueScope &jv, const ton_api::adnl_pong &object); void to_json(JsonValueScope &jv, const ton_api::adnl_Proxy &object); void to_json(JsonValueScope &jv, const ton_api::adnl_proxy_none &object); void to_json(JsonValueScope &jv, const ton_api::adnl_proxy_fast &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_ProxyControlPacket &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyControlPacketPing &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyControlPacketPong &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyControlPacketRegister &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_proxyPacketHeader &object); void to_json(JsonValueScope &jv, const ton_api::adnl_proxyToFastHash &object); void to_json(JsonValueScope &jv, const ton_api::adnl_proxyToFast &object); +void to_json(JsonValueScope &jv, const ton_api::adnl_tunnelPacketContents &object); void to_json(JsonValueScope &jv, const ton_api::adnl_config_global &object); void to_json(JsonValueScope &jv, const ton_api::adnl_db_node_key &object); void to_json(JsonValueScope &jv, const ton_api::adnl_db_node_value &object); 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 1b6fb98d11..938caa69c3 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 @@ -1288,32 +1288,94 @@ void msg_dataEncryptedText::store(td::TlStorerToString &s, const char *field_nam } } -msg_dataArray::msg_dataArray() +msg_dataDecrypted::msg_dataDecrypted() + : proof_() + , data_() +{} + +msg_dataDecrypted::msg_dataDecrypted(std::string const &proof_, object_ptr &&data_) + : proof_(std::move(proof_)) + , data_(std::move(data_)) +{} + +const std::int32_t msg_dataDecrypted::ID; + +void msg_dataDecrypted::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "msg_dataDecrypted"); + s.store_bytes_field("proof", proof_); + if (data_ == nullptr) { s.store_field("data", "null"); } else { data_->store(s, "data"); } + s.store_class_end(); + } +} + +msg_dataDecryptedArray::msg_dataDecryptedArray() : elements_() {} -msg_dataArray::msg_dataArray(std::vector> &&elements_) +msg_dataDecryptedArray::msg_dataDecryptedArray(std::vector> &&elements_) : elements_(std::move(elements_)) {} -const std::int32_t msg_dataArray::ID; +const std::int32_t msg_dataDecryptedArray::ID; -void msg_dataArray::store(td::TlStorerToString &s, const char *field_name) const { +void msg_dataDecryptedArray::store(td::TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "msg_dataArray"); - { const std::vector> &v = elements_; const std::uint32_t multiplicity = static_cast(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("elements", vector_name.c_str()); for (std::uint32_t i = 0; i < multiplicity; i++) { if (v[i] == nullptr) { s.store_field("", "null"); } else { v[i]->store(s, ""); } } s.store_class_end(); } + s.store_class_begin(field_name, "msg_dataDecryptedArray"); + { const std::vector> &v = elements_; const std::uint32_t multiplicity = static_cast(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("elements", vector_name.c_str()); for (std::uint32_t i = 0; i < multiplicity; i++) { if (v[i] == nullptr) { s.store_field("", "null"); } else { v[i]->store(s, ""); } } s.store_class_end(); } + s.store_class_end(); + } +} + +msg_dataEncrypted::msg_dataEncrypted() + : source_() + , data_() +{} + +msg_dataEncrypted::msg_dataEncrypted(object_ptr &&source_, object_ptr &&data_) + : source_(std::move(source_)) + , data_(std::move(data_)) +{} + +const std::int32_t msg_dataEncrypted::ID; + +void msg_dataEncrypted::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "msg_dataEncrypted"); + if (source_ == nullptr) { s.store_field("source", "null"); } else { source_->store(s, "source"); } + if (data_ == nullptr) { s.store_field("data", "null"); } else { data_->store(s, "data"); } + s.store_class_end(); + } +} + +msg_dataEncryptedArray::msg_dataEncryptedArray() + : elements_() +{} + +msg_dataEncryptedArray::msg_dataEncryptedArray(std::vector> &&elements_) + : elements_(std::move(elements_)) +{} + +const std::int32_t msg_dataEncryptedArray::ID; + +void msg_dataEncryptedArray::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "msg_dataEncryptedArray"); + { const std::vector> &v = elements_; const std::uint32_t multiplicity = static_cast(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("elements", vector_name.c_str()); for (std::uint32_t i = 0; i < multiplicity; i++) { if (v[i] == nullptr) { s.store_field("", "null"); } else { v[i]->store(s, ""); } } s.store_class_end(); } s.store_class_end(); } } msg_message::msg_message() : destination_() + , public_key_() , amount_() , data_() {} -msg_message::msg_message(object_ptr &&destination_, std::int64_t amount_, object_ptr &&data_) +msg_message::msg_message(object_ptr &&destination_, std::string const &public_key_, std::int64_t amount_, object_ptr &&data_) : destination_(std::move(destination_)) + , public_key_(std::move(public_key_)) , amount_(amount_) , data_(std::move(data_)) {} @@ -1324,6 +1386,7 @@ void msg_message::store(td::TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "msg_message"); if (destination_ == nullptr) { s.store_field("destination", "null"); } else { destination_->store(s, "destination"); } + s.store_field("public_key", public_key_); s.store_field("amount", amount_); if (data_ == nullptr) { s.store_field("data", "null"); } else { data_->store(s, "data"); } s.store_class_end(); @@ -1458,7 +1521,7 @@ raw_message::raw_message() , msg_data_() {} -raw_message::raw_message(std::string const &source_, std::string const &destination_, std::int64_t value_, std::int64_t fwd_fee_, std::int64_t ihr_fee_, std::int64_t created_lt_, std::string const &body_hash_, object_ptr &&msg_data_) +raw_message::raw_message(object_ptr &&source_, object_ptr &&destination_, std::int64_t value_, std::int64_t fwd_fee_, std::int64_t ihr_fee_, std::int64_t created_lt_, std::string const &body_hash_, object_ptr &&msg_data_) : source_(std::move(source_)) , destination_(std::move(destination_)) , value_(value_) @@ -1474,8 +1537,8 @@ const std::int32_t raw_message::ID; void raw_message::store(td::TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "raw_message"); - s.store_field("source", source_); - s.store_field("destination", destination_); + if (source_ == nullptr) { s.store_field("source", "null"); } else { source_->store(s, "source"); } + if (destination_ == nullptr) { s.store_field("destination", "null"); } else { destination_->store(s, "destination"); } s.store_field("value", value_); s.store_field("fwd_fee", fwd_fee_); s.store_field("ihr_fee", ihr_fee_); @@ -2409,7 +2472,7 @@ msg_decrypt::msg_decrypt() , data_() {} -msg_decrypt::msg_decrypt(object_ptr &&input_key_, object_ptr &&data_) +msg_decrypt::msg_decrypt(object_ptr &&input_key_, object_ptr &&data_) : input_key_(std::move(input_key_)) , data_(std::move(data_)) {} @@ -2425,6 +2488,27 @@ void msg_decrypt::store(td::TlStorerToString &s, const char *field_name) const { } } +msg_decryptWithProof::msg_decryptWithProof() + : proof_() + , data_() +{} + +msg_decryptWithProof::msg_decryptWithProof(std::string const &proof_, object_ptr &&data_) + : proof_(std::move(proof_)) + , data_(std::move(data_)) +{} + +const std::int32_t msg_decryptWithProof::ID; + +void msg_decryptWithProof::store(td::TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "msg_decryptWithProof"); + s.store_bytes_field("proof", proof_); + if (data_ == nullptr) { s.store_field("data", "null"); } else { data_->store(s, "data"); } + s.store_class_end(); + } +} + onLiteServerQueryError::onLiteServerQueryError() : id_() , error_() 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 5247ecddfa..1abee6a8dc 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 @@ -114,7 +114,13 @@ class liteServer_info; class msg_Data; -class msg_dataArray; +class msg_dataDecrypted; + +class msg_dataDecryptedArray; + +class msg_dataEncrypted; + +class msg_dataEncryptedArray; class msg_message; @@ -1292,15 +1298,65 @@ class msg_dataEncryptedText final : public msg_Data { void store(td::TlStorerToString &s, const char *field_name) const final; }; -class msg_dataArray final : public Object { +class msg_dataDecrypted final : public Object { public: - std::vector> elements_; + std::string proof_; + object_ptr data_; - msg_dataArray(); + msg_dataDecrypted(); - explicit msg_dataArray(std::vector> &&elements_); + msg_dataDecrypted(std::string const &proof_, object_ptr &&data_); - static const std::int32_t ID = 1248461374; + static const std::int32_t ID = 195649769; + std::int32_t get_id() const final { + return ID; + } + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class msg_dataDecryptedArray final : public Object { + public: + std::vector> elements_; + + msg_dataDecryptedArray(); + + explicit msg_dataDecryptedArray(std::vector> &&elements_); + + static const std::int32_t ID = -480491767; + std::int32_t get_id() const final { + return ID; + } + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class msg_dataEncrypted final : public Object { + public: + object_ptr source_; + object_ptr data_; + + msg_dataEncrypted(); + + msg_dataEncrypted(object_ptr &&source_, object_ptr &&data_); + + static const std::int32_t ID = 564215121; + std::int32_t get_id() const final { + return ID; + } + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class msg_dataEncryptedArray final : public Object { + public: + std::vector> elements_; + + msg_dataEncryptedArray(); + + explicit msg_dataEncryptedArray(std::vector> &&elements_); + + static const std::int32_t ID = 608655794; std::int32_t get_id() const final { return ID; } @@ -1311,14 +1367,15 @@ class msg_dataArray final : public Object { class msg_message final : public Object { public: object_ptr destination_; + std::string public_key_; std::int64_t amount_; object_ptr data_; msg_message(); - msg_message(object_ptr &&destination_, std::int64_t amount_, object_ptr &&data_); + msg_message(object_ptr &&destination_, std::string const &public_key_, std::int64_t amount_, object_ptr &&data_); - static const std::int32_t ID = 1349943761; + static const std::int32_t ID = -2110533580; std::int32_t get_id() const final { return ID; } @@ -1417,8 +1474,8 @@ class raw_fullAccountState final : public Object { class raw_message final : public Object { public: - std::string source_; - std::string destination_; + object_ptr source_; + object_ptr destination_; std::int64_t value_; std::int64_t fwd_fee_; std::int64_t ihr_fee_; @@ -1428,9 +1485,9 @@ class raw_message final : public Object { raw_message(); - raw_message(std::string const &source_, std::string const &destination_, std::int64_t value_, std::int64_t fwd_fee_, std::int64_t ihr_fee_, std::int64_t created_lt_, std::string const &body_hash_, object_ptr &&msg_data_); + raw_message(object_ptr &&source_, object_ptr &&destination_, std::int64_t value_, std::int64_t fwd_fee_, std::int64_t ihr_fee_, std::int64_t created_lt_, std::string const &body_hash_, object_ptr &&msg_data_); - static const std::int32_t ID = -32842388; + static const std::int32_t ID = 1368093263; std::int32_t get_id() const final { return ID; } @@ -2276,18 +2333,37 @@ class liteServer_getInfo final : public Function { class msg_decrypt final : public Function { public: object_ptr input_key_; - object_ptr data_; + object_ptr data_; msg_decrypt(); - msg_decrypt(object_ptr &&input_key_, object_ptr &&data_); + msg_decrypt(object_ptr &&input_key_, object_ptr &&data_); - static const std::int32_t ID = 1131086633; + static const std::int32_t ID = 223596297; std::int32_t get_id() const final { return ID; } - using ReturnType = object_ptr; + using ReturnType = object_ptr; + + void store(td::TlStorerToString &s, const char *field_name) const final; +}; + +class msg_decryptWithProof final : public Function { + public: + std::string proof_; + object_ptr data_; + + msg_decryptWithProof(); + + msg_decryptWithProof(std::string const &proof_, object_ptr &&data_); + + static const std::int32_t ID = -2111649663; + std::int32_t get_id() const final { + return ID; + } + + using ReturnType = object_ptr; void store(td::TlStorerToString &s, const char *field_name) const final; }; 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 ad2ac76a43..74249ee7e7 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 @@ -215,8 +215,17 @@ bool downcast_call(Object &obj, const T &func) { case msg_dataEncryptedText::ID: func(static_cast(obj)); return true; - case msg_dataArray::ID: - func(static_cast(obj)); + case msg_dataDecrypted::ID: + func(static_cast(obj)); + return true; + case msg_dataDecryptedArray::ID: + func(static_cast(obj)); + return true; + case msg_dataEncrypted::ID: + func(static_cast(obj)); + return true; + case msg_dataEncryptedArray::ID: + func(static_cast(obj)); return true; case msg_message::ID: func(static_cast(obj)); @@ -397,6 +406,9 @@ bool downcast_call(Function &obj, const T &func) { case msg_decrypt::ID: func(static_cast(obj)); return true; + case msg_decryptWithProof::ID: + func(static_cast(obj)); + return true; case onLiteServerQueryError::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 335cbbc3d5..aae12df910 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 @@ -251,14 +251,17 @@ Result tl_constructor_from_string(tonlib_api::Object *object, const std:: {"msg.dataText", -341560688}, {"msg.dataDecryptedText", -1289133895}, {"msg.dataEncryptedText", -296612902}, - {"msg.dataArray", 1248461374}, - {"msg.message", 1349943761}, + {"msg.dataDecrypted", 195649769}, + {"msg.dataDecryptedArray", -480491767}, + {"msg.dataEncrypted", 564215121}, + {"msg.dataEncryptedArray", 608655794}, + {"msg.message", -2110533580}, {"options.configInfo", 451217371}, {"options.info", -64676736}, {"query.fees", 1614616510}, {"query.info", 1588635915}, {"raw.fullAccountState", -1465398385}, - {"raw.message", -32842388}, + {"raw.message", 1368093263}, {"raw.transaction", 1887601793}, {"raw.transactions", -2063931155}, {"smc.info", 1134270012}, @@ -315,7 +318,8 @@ Result tl_constructor_from_string(tonlib_api::Function *object, const std {"init", -1000594762}, {"kdf", -1667861635}, {"liteServer.getInfo", 1435327470}, - {"msg.decrypt", 1131086633}, + {"msg.decrypt", 223596297}, + {"msg.decryptWithProof", -2111649663}, {"onLiteServerQueryError", -677427533}, {"onLiteServerQueryResult", 2056444510}, {"options.setConfig", 1870064579}, @@ -1132,7 +1136,46 @@ Status from_json(tonlib_api::msg_dataEncryptedText &to, JsonObject &from) { } return Status::OK(); } -Status from_json(tonlib_api::msg_dataArray &to, JsonObject &from) { +Status from_json(tonlib_api::msg_dataDecrypted &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "proof", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.proof_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "data", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.data_, value)); + } + } + return Status::OK(); +} +Status from_json(tonlib_api::msg_dataDecryptedArray &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "elements", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.elements_, value)); + } + } + return Status::OK(); +} +Status from_json(tonlib_api::msg_dataEncrypted &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "source", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.source_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "data", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.data_, value)); + } + } + return Status::OK(); +} +Status from_json(tonlib_api::msg_dataEncryptedArray &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "elements", JsonValue::Type::Null, true)); if (value.type() != JsonValue::Type::Null) { @@ -1148,6 +1191,12 @@ Status from_json(tonlib_api::msg_message &to, JsonObject &from) { TRY_STATUS(from_json(to.destination_, value)); } } + { + TRY_RESULT(value, get_json_object_field(from, "public_key", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.public_key_, value)); + } + } { TRY_RESULT(value, get_json_object_field(from, "amount", JsonValue::Type::Null, true)); if (value.type() != JsonValue::Type::Null) { @@ -1936,6 +1985,21 @@ Status from_json(tonlib_api::msg_decrypt &to, JsonObject &from) { } return Status::OK(); } +Status from_json(tonlib_api::msg_decryptWithProof &to, JsonObject &from) { + { + TRY_RESULT(value, get_json_object_field(from, "proof", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json_bytes(to.proof_, value)); + } + } + { + TRY_RESULT(value, get_json_object_field(from, "data", JsonValue::Type::Null, true)); + if (value.type() != JsonValue::Type::Null) { + TRY_STATUS(from_json(to.data_, value)); + } + } + return Status::OK(); +} Status from_json(tonlib_api::onLiteServerQueryError &to, JsonObject &from) { { TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true)); @@ -2670,9 +2734,32 @@ void to_json(JsonValueScope &jv, const tonlib_api::msg_dataEncryptedText &object jo << ctie("@type", "msg.dataEncryptedText"); jo << ctie("text", ToJson(JsonBytes{object.text_})); } -void to_json(JsonValueScope &jv, const tonlib_api::msg_dataArray &object) { +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataDecrypted &object) { auto jo = jv.enter_object(); - jo << ctie("@type", "msg.dataArray"); + jo << ctie("@type", "msg.dataDecrypted"); + jo << ctie("proof", ToJson(JsonBytes{object.proof_})); + if (object.data_) { + jo << ctie("data", ToJson(object.data_)); + } +} +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataDecryptedArray &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "msg.dataDecryptedArray"); + jo << ctie("elements", ToJson(object.elements_)); +} +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataEncrypted &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "msg.dataEncrypted"); + if (object.source_) { + jo << ctie("source", ToJson(object.source_)); + } + if (object.data_) { + jo << ctie("data", ToJson(object.data_)); + } +} +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataEncryptedArray &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "msg.dataEncryptedArray"); jo << ctie("elements", ToJson(object.elements_)); } void to_json(JsonValueScope &jv, const tonlib_api::msg_message &object) { @@ -2681,6 +2768,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::msg_message &object) { if (object.destination_) { jo << ctie("destination", ToJson(object.destination_)); } + jo << ctie("public_key", ToJson(object.public_key_)); jo << ctie("amount", ToJson(JsonInt64{object.amount_})); if (object.data_) { jo << ctie("data", ToJson(object.data_)); @@ -2731,8 +2819,12 @@ void to_json(JsonValueScope &jv, const tonlib_api::raw_fullAccountState &object) void to_json(JsonValueScope &jv, const tonlib_api::raw_message &object) { auto jo = jv.enter_object(); jo << ctie("@type", "raw.message"); - jo << ctie("source", ToJson(object.source_)); - jo << ctie("destination", ToJson(object.destination_)); + if (object.source_) { + jo << ctie("source", ToJson(object.source_)); + } + if (object.destination_) { + jo << ctie("destination", ToJson(object.destination_)); + } jo << ctie("value", ToJson(JsonInt64{object.value_})); jo << ctie("fwd_fee", ToJson(JsonInt64{object.fwd_fee_})); jo << ctie("ihr_fee", ToJson(JsonInt64{object.ihr_fee_})); @@ -3076,6 +3168,14 @@ void to_json(JsonValueScope &jv, const tonlib_api::msg_decrypt &object) { jo << ctie("data", ToJson(object.data_)); } } +void to_json(JsonValueScope &jv, const tonlib_api::msg_decryptWithProof &object) { + auto jo = jv.enter_object(); + jo << ctie("@type", "msg.decryptWithProof"); + jo << ctie("proof", ToJson(JsonBytes{object.proof_})); + if (object.data_) { + jo << ctie("data", ToJson(object.data_)); + } +} void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryError &object) { auto jo = jv.enter_object(); jo << ctie("@type", "onLiteServerQueryError"); 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 4c1c430fc7..9d1c00b5cd 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 @@ -93,7 +93,10 @@ Status from_json(tonlib_api::msg_dataRaw &to, JsonObject &from); Status from_json(tonlib_api::msg_dataText &to, JsonObject &from); Status from_json(tonlib_api::msg_dataDecryptedText &to, JsonObject &from); Status from_json(tonlib_api::msg_dataEncryptedText &to, JsonObject &from); -Status from_json(tonlib_api::msg_dataArray &to, JsonObject &from); +Status from_json(tonlib_api::msg_dataDecrypted &to, JsonObject &from); +Status from_json(tonlib_api::msg_dataDecryptedArray &to, JsonObject &from); +Status from_json(tonlib_api::msg_dataEncrypted &to, JsonObject &from); +Status from_json(tonlib_api::msg_dataEncryptedArray &to, JsonObject &from); Status from_json(tonlib_api::msg_message &to, JsonObject &from); Status from_json(tonlib_api::options_configInfo &to, JsonObject &from); Status from_json(tonlib_api::options_info &to, JsonObject &from); @@ -149,6 +152,7 @@ Status from_json(tonlib_api::init &to, JsonObject &from); Status from_json(tonlib_api::kdf &to, JsonObject &from); Status from_json(tonlib_api::liteServer_getInfo &to, JsonObject &from); Status from_json(tonlib_api::msg_decrypt &to, JsonObject &from); +Status from_json(tonlib_api::msg_decryptWithProof &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); @@ -253,7 +257,10 @@ void to_json(JsonValueScope &jv, const tonlib_api::msg_dataRaw &object); void to_json(JsonValueScope &jv, const tonlib_api::msg_dataText &object); void to_json(JsonValueScope &jv, const tonlib_api::msg_dataDecryptedText &object); void to_json(JsonValueScope &jv, const tonlib_api::msg_dataEncryptedText &object); -void to_json(JsonValueScope &jv, const tonlib_api::msg_dataArray &object); +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataDecrypted &object); +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataDecryptedArray &object); +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataEncrypted &object); +void to_json(JsonValueScope &jv, const tonlib_api::msg_dataEncryptedArray &object); void to_json(JsonValueScope &jv, const tonlib_api::msg_message &object); void to_json(JsonValueScope &jv, const tonlib_api::options_configInfo &object); void to_json(JsonValueScope &jv, const tonlib_api::options_info &object); @@ -311,6 +318,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::init &object); void to_json(JsonValueScope &jv, const tonlib_api::kdf &object); void to_json(JsonValueScope &jv, const tonlib_api::liteServer_getInfo &object); void to_json(JsonValueScope &jv, const tonlib_api::msg_decrypt &object); +void to_json(JsonValueScope &jv, const tonlib_api::msg_decryptWithProof &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); diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl index 1f819d5dd3..329c134b57 100644 --- a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl +++ b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tl @@ -58,8 +58,8 @@ adnl.id.short id:int256 = adnl.id.Short; adnl.proxyToFastHash ip:int port:int date:int data_hash:int256 shared_secret:int256 = adnl.ProxyTo; adnl.proxyToFast ip:int port:int date:int signature:int256 = adnl.ProxyToSign; -adnl.proxy.none = adnl.Proxy; -adnl.proxy.fast shared_secret:bytes = adnl.Proxy; +adnl.proxy.none id:int256 = adnl.Proxy; +adnl.proxy.fast id:int256 shared_secret:bytes = adnl.Proxy; adnl.address.udp ip:int port:int = adnl.Address; @@ -67,7 +67,7 @@ adnl.address.udp6 ip:int128 port:int = adnl.Address; //adnl.address.tcp ip:int port:int = adnl.Address; //adnl.address.tcp6 ip:int128 port:int = adnl.Address; -//adnl.address.tunnel to:adnl.Address tunid: = adnl.Address; +adnl.address.tunnel to:int256 pubkey:PublicKey = adnl.Address; adnl.addressList addrs:(vector adnl.Address) version:int reinit_date:int priority:int expire_at:int = adnl.AddressList; @@ -97,6 +97,34 @@ adnl.packetContents rand2:bytes = adnl.PacketContents; +adnl.tunnelPacketContents + rand1:bytes + flags:# + from_ip:flags.0?int + from_port:flags.0?int + message:flags.1?bytes + statistics:flags.2?bytes + payment:flags.3?bytes + rand2:bytes + = adnl.TunnelPacketContents; + + +// flag 16 - packet is outbound +// flag 17 - control packet +adnl.proxyPacketHeader + proxy_id:int256 + flags:# + ip:flags.0?int + port:flags.0?int + adnl_start_time:flags.1?int + seqno:flags.2?long + date:flags.3?int + signature:int256 = adnl.ProxyPacketHeader; + +adnl.proxyControlPacketPing id:int256 = adnl.ProxyControlPacket; +adnl.proxyControlPacketPong id:int256 = adnl.ProxyControlPacket; +adnl.proxyControlPacketRegister ip:int port:int = adnl.ProxyControlPacket; + adnl.message.createChannel key:int256 date:int = adnl.Message; adnl.message.confirmChannel key:int256 peer_key:int256 date:int = adnl.Message; diff --git a/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tlo b/submodules/ton/tonlib-src/tl/generate/scheme/ton_api.tlo index 5507d156b03e7a5d235a813ccb89d400f963730a..57e7ef67d85a74de0e55bfef506357f4fc9d5e6a 100644 GIT binary patch delta 984 zcmaEIjQPbyX5L4$^{p77VE0De*-V1pj$8NgB&Ou$=sBjO6r~myPrfKBz4;0g3nR-p z-ktoD?=Y*#cJ%t~7YC~eD9W#>bk5H!Day|YNKDR7En%MMC@x)LlgS~5PymtfNKH&h zEtDNJnX7VKF|V1lIfcPiBtpERR|2*QZWd6n z^t1b#OeOh~<1MAw3QCi*Q!6LmuakwC*<%{P3N~{xZja z7Jz)OmzSTH3Jw~9Ac@HZMLd%o3^_DF0?2OJ>e_9EtSK$AxCE@}!gP(vAM7P2E7*&e zplkAeGR<5XVG~L?2V~}@gW_Q_lC35n0c2bM+`j0I(|~+T18mU^u;0XaSRRK9f>P5n zi%U|AKza~Sv%s9w0nHVN)Bp}Jw!f46K=WO^GnI=z+ z7N5Mvo`Vx6$2?gP6qh@|vBUzheY1uA21ZRpa)hK2h$CUik%0ju4|eC|Olxmm_Ozn> z-1y7_h`SukWCXwh1^GoK3{b~1YDiD!un}NnoNVYPF3JUTWeG5}GLwrT@<3-Yfn)^P z3lb}Hfk__WK%nSk6+0Cckd>S7IGizH1*eP2fd$hyyA-Lgf%DxVW^c+)Cic*V%#Uz{ z26@f;#SgZipeVnhQZFw*FBN3+&0|77AeR(5v*~cywjBhC!JKwgjw@zf53eG!zO=;R y5|}>5$$<{WVE1iyao)hVImhjQ0fcK%zK0FM`cRwV%L+Dha^l75n?IcXAp-z(Eok5X 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 beb5d64a0c..64ab40f973 100644 --- a/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl +++ b/submodules/ton/tonlib-src/tl/generate/scheme/tonlib_api.tl @@ -51,7 +51,7 @@ ton.blockId workchain:int32 shard:int64 seqno:int32 = internal.BlockId; ton.blockIdExt workchain:int32 shard:int64 seqno:int32 root_hash:bytes file_hash:bytes = ton.BlockIdExt; 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:string destination:string value:int64 fwd_fee:int64 ihr_fee:int64 created_lt:int64 body_hash:bytes msg_data:msg.Data = raw.Message; +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.Transaction; raw.transactions transactions:vector previous_transaction_id:internal.transactionId = raw.Transactions; @@ -88,9 +88,13 @@ msg.dataText text:bytes = msg.Data; msg.dataDecryptedText text:bytes = msg.Data; msg.dataEncryptedText text:bytes = msg.Data; -msg.dataArray elements:vector = msg.DataArray; +msg.dataEncrypted source:accountAddress data:msg.Data = msg.DataEncrypted; +msg.dataDecrypted proof:bytes data:msg.Data = msg.DataDecrypted; -msg.message destination:accountAddress amount:int64 data:msg.Data = msg.Message; +msg.dataEncryptedArray elements:vector = msg.DataEncryptedArray; +msg.dataDecryptedArray elements:vector = msg.DataDecryptedArray; + +msg.message destination:accountAddress public_key:string amount:int64 data:msg.Data = msg.Message; // // DNS @@ -216,7 +220,8 @@ guessAccountRevision initial_account_state:InitialAccountState = AccountRevision getAccountState account_address:accountAddress = FullAccountState; createQuery private_key:InputKey address:accountAddress timeout:int32 action:Action = query.Info; -msg.decrypt input_key:InputKey data:msg.dataArray = msg.DataArray; +msg.decrypt input_key:InputKey data:msg.dataEncryptedArray = msg.DataDecryptedArray; +msg.decryptWithProof proof:bytes data:msg.dataEncrypted = msg.Data; query.send id:int53 = Ok; query.forget id:int53 = 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 6a730d89e12188541e71d228f12c42ccf3111558..f513bc63e21428874d0345dfcf249ae6ef3a860d 100644 GIT binary patch delta 727 zcmaE{gmJ+tM&3uW^{p77z+)rtadxqn2`jk;bBojUToOwXT~d>aDho8YJMMuN{Bn|WFRXMI0xMxs|fp`WaH+hD(i7QAGBUD$BGn)>FZQDVR zB(gzpUxN&SdyRnsBo21Z#_D4@BE63bzF zK>W!k^ku*<=I~aTEMaf~5*u#}co@N~$$tz@AVMZaA?%Enn>#Jtc||zS2lIlWP%j0N zXuyG}V`TvHb{NQ|=&nZ($i@>&O(IAJglCpy1c2fY=*2rJeOs_cE(<7NCNI!Z*zDo1 GzzqO|fahia delta 311 zcmZ3mit)t~M&3uW^{p77z;z?. - Copyright 2017-2019 Telegram Systems LLP + Copyright 2017-2020 Telegram Systems LLP */ #pragma once @@ -56,7 +56,13 @@ constexpr unsigned min_split_merge_interval = 30; // split/merge interval must constexpr unsigned max_split_merge_delay = 1000; // end of split/merge interval must be at most 1000 seconds in the future -enum GlobalCapabilities { capIhrEnabled = 1, capCreateStatsEnabled = 2 }; +enum GlobalCapabilities { + capIhrEnabled = 1, + capCreateStatsEnabled = 2, + capBounceMsgBody = 4, + capReportVersion = 8, + capSplitMergeTransactions = 16 +}; inline int shard_pfx_len(ShardId shard) { return shard ? 63 - td::count_trailing_zeroes_non_zero64(shard) : 0; diff --git a/submodules/ton/tonlib-src/tonlib/test/offline.cpp b/submodules/ton/tonlib-src/tonlib/test/offline.cpp index 223c8edad2..799c246fed 100644 --- a/submodules/ton/tonlib-src/tonlib/test/offline.cpp +++ b/submodules/ton/tonlib-src/tonlib/test/offline.cpp @@ -155,6 +155,13 @@ TEST(Tonlib, InitClose) { } } +td::Slice to_data(const td::SecureString &str) { + return str.as_slice(); +} +td::Slice to_data(const tonlib::SimpleEncryptionV2::Decrypted &str) { + return str.data.as_slice(); +} + template void test_encryption() { std::string secret = "secret"; @@ -164,7 +171,7 @@ void test_encryption() { auto encrypted_data = Encryption::encrypt_data(data, secret); LOG(ERROR) << encrypted_data.size(); auto decrypted_data = Encryption::decrypt_data(encrypted_data, secret).move_as_ok(); - CHECK(data == decrypted_data); + CHECK(data == to_data(decrypted_data)); Encryption::decrypt_data(encrypted_data, wrong_secret).ensure_error(); Encryption::decrypt_data("", secret).ensure_error(); Encryption::decrypt_data(std::string(32, 'a'), secret).ensure_error(); @@ -177,7 +184,7 @@ void test_encryption() { auto data = td::rand_string('a', 'z', static_cast(i)); auto encrypted_data = Encryption::encrypt_data(data, secret); auto decrypted_data = Encryption::decrypt_data(encrypted_data, secret).move_as_ok(); - CHECK(data == decrypted_data); + CHECK(data == to_data(decrypted_data)); } } TEST(Tonlib, SimpleEncryption) { @@ -199,24 +206,33 @@ TEST(Tonlib, SimpleEncryptionAsym) { auto encrypted_data = SimpleEncryptionV2::encrypt_data(data, public_key, other_private_key).move_as_ok(); LOG(ERROR) << encrypted_data.size(); auto decrypted_data = SimpleEncryptionV2::decrypt_data(encrypted_data, private_key).move_as_ok(); - CHECK(data == decrypted_data); + CHECK(data == decrypted_data.data); auto decrypted_data2 = SimpleEncryptionV2::decrypt_data(encrypted_data, other_private_key).move_as_ok(); - CHECK(data == decrypted_data2); + CHECK(data == decrypted_data2.data); + + CHECK(decrypted_data.proof == decrypted_data2.proof); + + auto decrypted_data3 = + SimpleEncryptionV2::decrypt_data_with_proof(encrypted_data, decrypted_data.proof).move_as_ok(); + CHECK(data == decrypted_data3); + SimpleEncryptionV2::decrypt_data(encrypted_data, wrong_private_key).ensure_error(); SimpleEncryptionV2::decrypt_data("", private_key).ensure_error(); SimpleEncryptionV2::decrypt_data(std::string(32, 'a'), private_key).ensure_error(); SimpleEncryptionV2::decrypt_data(std::string(33, 'a'), private_key).ensure_error(); SimpleEncryptionV2::decrypt_data(std::string(64, 'a'), private_key).ensure_error(); SimpleEncryptionV2::decrypt_data(std::string(128, 'a'), private_key).ensure_error(); + + SimpleEncryptionV2::decrypt_data_with_proof(encrypted_data, decrypted_data.proof, "bad salt").ensure_error(); } for (size_t i = 0; i < 255; i++) { auto data = td::rand_string('a', 'z', static_cast(i)); auto encrypted_data = SimpleEncryptionV2::encrypt_data(data, public_key, other_private_key).move_as_ok(); auto decrypted_data = SimpleEncryptionV2::decrypt_data(encrypted_data, private_key).move_as_ok(); - CHECK(data == decrypted_data); + CHECK(data == decrypted_data.data); auto decrypted_data2 = SimpleEncryptionV2::decrypt_data(encrypted_data, other_private_key).move_as_ok(); - CHECK(data == decrypted_data2); + CHECK(data == decrypted_data2.data); } } @@ -518,19 +534,30 @@ TEST(Tonlib, KeysApi) { auto other_public_key = td::Ed25519::generate_private_key().move_as_ok().get_public_key().move_as_ok(); std::string text = "hello world"; - std::vector> elements; - elements.push_back(make_object( - SimpleEncryptionV2::encrypt_data(text, other_public_key, pkey).move_as_ok().as_slice().str())); + std::vector> elements; + td::Slice addr = "Ef9Tj6fMJP-OqhAdhKXxq36DL-HYSzCc3-9O6UNzqsgPfYFX"; + auto encrypted = SimpleEncryptionV2::encrypt_data(text, other_public_key, pkey, addr).move_as_ok().as_slice().str(); + elements.push_back(make_object( + make_object(addr.str()), make_object(encrypted))); auto decrypted = sync_send(client, make_object( make_object( make_object(key->public_key_, raw_imported_key->secret_.copy()), new_local_password.copy()), - make_object(std::move(elements)))) + make_object(std::move(elements)))) .move_as_ok(); - downcast_call(*decrypted->elements_[0], + auto proof = decrypted->elements_[0]->proof_; + downcast_call(*decrypted->elements_[0]->data_, + td::overloaded([](auto &) { UNREACHABLE(); }, + [&](tonlib_api::msg_dataDecryptedText &decrypted) { CHECK(decrypted.text_ == text); })); + auto decrypted2 = sync_send(client, make_object( + proof, make_object( + make_object(addr.str()), + make_object(encrypted)))) + .move_as_ok(); + downcast_call(*decrypted2, td::overloaded([](auto &) { UNREACHABLE(); }, [&](tonlib_api::msg_dataDecryptedText &decrypted) { CHECK(decrypted.text_ == text); })); } diff --git a/submodules/ton/tonlib-src/tonlib/test/online.cpp b/submodules/ton/tonlib-src/tonlib/test/online.cpp index d6d4a8944a..6aba742d86 100644 --- a/submodules/ton/tonlib-src/tonlib/test/online.cpp +++ b/submodules/ton/tonlib-src/tonlib/test/online.cpp @@ -239,7 +239,7 @@ td::Result create_send_grams_query(Client& client, const Wallet& source data = tonlib_api::make_object(std::move(message)); } msgs.push_back(tonlib_api::make_object( - tonlib_api::make_object(destination), amount, std::move(data))); + tonlib_api::make_object(destination), "", amount, std::move(data))); auto r_id = sync_send(client, tonlib_api::make_object( @@ -392,9 +392,9 @@ td::Status transfer_grams(Client& client, const Wallet& wallet, std::string addr if (transfer_all) { ASSERT_EQ(amount - first_fee, txn->in_msg_->value_); } else { - ASSERT_EQ(new_src_state.address, txn->in_msg_->source_); + ASSERT_EQ(new_src_state.address, txn->in_msg_->source_->account_address_); } - ASSERT_EQ(new_src_state.address, txn->in_msg_->source_); + ASSERT_EQ(new_src_state.address, txn->in_msg_->source_->account_address_); if (!encrypt) { ASSERT_EQ(message, read_text(*txn->in_msg_->msg_data_)); } diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp index f031596167..6af5669458 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.cpp @@ -1368,6 +1368,7 @@ bool TonlibClient::is_static_request(td::int32 id) { case tonlib_api::encrypt::ID: case tonlib_api::decrypt::ID: case tonlib_api::kdf::ID: + case tonlib_api::msg_decryptWithProof::ID: return true; default: return false; @@ -1687,6 +1688,29 @@ const MasterConfig& get_default_master_config() { "init_block": {"workchain":-1,"shard":-9223372036854775808,"seqno":870721,"root_hash":"jYKhSQ1xeSPprzgjqiUOnAWwc2yqs7nCVAU21k922s4=","file_hash":"kHidF02CZpaz2ia9jtXUJLp0AiWMWwfzprTUIsddHSo="} } +})abc"); + res.add_config("testnet2", R"abc({ + "liteservers": [ + { + "ip": 1137658550, + "port": 4924, + "id": { + "@type": "pub.ed25519", + "key": "peJTw/arlRfssgTuf9BMypJzqOi7SXEqSPSWiEw2U1M=" + } + } + ], + "validator": { + "@type": "validator.config.global", + "zero_state": { + "workchain": -1, + "shard": -9223372036854775808, + "seqno": 0, + "root_hash": "F6OpKZKqvqeFp6CQmFomXNMfMj2EnaUSOXN+Mh+wVWk=", + "file_hash": "XplPz01CXAps5qeSWUtxcyBfdAo5zVb1N979KLSKD24=" + }, + "init_block": {"workchain":-1,"shard":-9223372036854775808,"seqno":2908451,"root_hash":"5+7X1QHVUBFLFMwa/yd/2fGzt2KeQtwr+o6UUFOQ7Qc=","file_hash":"gmiUgrtAbvEJZYDEkcbeNOhGPS3g+qCepSOEBFLZFzk="} + } })abc"); return res; }(); @@ -1841,39 +1865,41 @@ struct ToRawTransactions { auto body_cell = vm::CellBuilder().append_cellslice(*body).finalize(); auto body_hash = body_cell->get_hash().as_slice().str(); - tonlib_api::object_ptr data; - if (body->size() >= 32 && static_cast(body->prefetch_long(32)) <= 1) { - auto type = body.write().fetch_long(32); - td::Status status; + auto get_data = [body = std::move(body), body_cell, this](td::Slice salt) mutable { + tonlib_api::object_ptr data; + if (body->size() >= 32 && static_cast(body->prefetch_long(32)) <= 1) { + auto type = body.write().fetch_long(32); + td::Status status; - auto r_body_message = vm::CellString::load(body.write()); - LOG_IF(WARNING, r_body_message.is_error()) << "Failed to parse a message: " << r_body_message.error(); + auto r_body_message = vm::CellString::load(body.write()); + LOG_IF(WARNING, r_body_message.is_error()) << "Failed to parse a message: " << r_body_message.error(); - if (r_body_message.is_ok()) { - if (type == 0) { - LOG(ERROR) << "OK " << r_body_message.ok(); - data = tonlib_api::make_object(r_body_message.move_as_ok()); - } else { - LOG(ERROR) << "TRY DECRYPT"; - auto encrypted_message = r_body_message.move_as_ok(); - auto r_decrypted_message = [&]() -> td::Result { - if (!private_key_) { - return TonlibError::EmptyField("private_key"); - } - TRY_RESULT(decrypted, SimpleEncryptionV2::decrypt_data(encrypted_message, private_key_.value())); - return decrypted.as_slice().str(); - }(); - if (r_decrypted_message.is_ok()) { - data = tonlib_api::make_object(r_decrypted_message.move_as_ok()); + if (r_body_message.is_ok()) { + if (type == 0) { + data = tonlib_api::make_object(r_body_message.move_as_ok()); } else { - data = tonlib_api::make_object(encrypted_message); + LOG(ERROR) << "TRY DECRYPT"; + auto encrypted_message = r_body_message.move_as_ok(); + auto r_decrypted_message = [&]() -> td::Result { + if (!private_key_) { + return TonlibError::EmptyField("private_key"); + } + TRY_RESULT(decrypted, SimpleEncryptionV2::decrypt_data(encrypted_message, private_key_.value(), salt)); + return decrypted.data.as_slice().str(); + }(); + if (r_decrypted_message.is_ok()) { + data = tonlib_api::make_object(r_decrypted_message.move_as_ok()); + } else { + data = tonlib_api::make_object(encrypted_message); + } } } } - } - if (!data) { - data = tonlib_api::make_object(to_bytes(std::move(body_cell))); - } + if (!data) { + data = tonlib_api::make_object(to_bytes(std::move(body_cell))); + } + return data; + }; auto tag = block::gen::CommonMsgInfo().get_tag(*message.info); if (tag < 0) { @@ -1893,9 +1919,10 @@ struct ToRawTransactions { TRY_RESULT(ihr_fee, to_balance(msg_info.ihr_fee)); auto created_lt = static_cast(msg_info.created_lt); - return tonlib_api::make_object(std::move(src), std::move(dest), balance, fwd_fee, - ihr_fee, created_lt, std::move(body_hash), - std::move(data)); + return tonlib_api::make_object( + tonlib_api::make_object(src), + tonlib_api::make_object(std::move(dest)), balance, fwd_fee, ihr_fee, created_lt, + std::move(body_hash), get_data(src)); } case block::gen::CommonMsgInfo::ext_in_msg_info: { block::gen::CommonMsgInfo::Record_ext_in_msg_info msg_info; @@ -1903,8 +1930,10 @@ struct ToRawTransactions { return td::Status::Error("Failed to unpack CommonMsgInfo::ext_in_msg_info"); } TRY_RESULT(dest, to_std_address(msg_info.dest)); - return tonlib_api::make_object("", std::move(dest), 0, 0, 0, 0, std::move(body_hash), - std::move(data)); + return tonlib_api::make_object( + tonlib_api::make_object(), + tonlib_api::make_object(std::move(dest)), 0, 0, 0, 0, std::move(body_hash), + get_data("")); } case block::gen::CommonMsgInfo::ext_out_msg_info: { block::gen::CommonMsgInfo::Record_ext_out_msg_info msg_info; @@ -1912,8 +1941,9 @@ struct ToRawTransactions { return td::Status::Error("Failed to unpack CommonMsgInfo::ext_out_msg_info"); } TRY_RESULT(src, to_std_address(msg_info.src)); - return tonlib_api::make_object(std::move(src), "", 0, 0, 0, 0, std::move(body_hash), - std::move(data)); + return tonlib_api::make_object( + tonlib_api::make_object(src), + tonlib_api::make_object(), 0, 0, 0, 0, std::move(body_hash), get_data(src)); } } @@ -2177,6 +2207,8 @@ class GenericCreateSendGrams : public TonlibQueryActor { std::string message; td::Ref body; + + td::optional o_public_key; }; bool allow_send_to_uninited_{false}; std::vector actions_; @@ -2210,6 +2242,11 @@ class GenericCreateSendGrams : public TonlibQueryActor { return TonlibError::InvalidField("amount", "can't be negative"); } res.amount = message.amount_; + if (!message.public_key_.empty()) { + TRY_RESULT(public_key, get_public_key(message.public_key_)); + auto key = td::Ed25519::PublicKey(td::SecureString(public_key.key)); + res.o_public_key = std::move(key); + } auto status = downcast_call2(*message.data_, td::overloaded( [&](tonlib_api::msg_dataRaw& text) { @@ -2243,7 +2280,7 @@ class GenericCreateSendGrams : public TonlibQueryActor { return TonlibError::MessageTooLong(); } TRY_STATUS(std::move(status)); - return res; + return std::move(res); } td::Result to_dns_action(tonlib_api::dns_Action& action) { @@ -2465,15 +2502,35 @@ class GenericCreateSendGrams : public TonlibQueryActor { if (!private_key_) { return TonlibError::EmptyField("private_key"); } - if (!destination->is_wallet()) { + + auto o_public_key = std::move(action.o_public_key); + if (!o_public_key && destination->is_wallet()) { + auto wallet = destination->get_wallet(); + auto r_public_key = wallet->get_public_key(); + if (r_public_key.is_ok()) { + o_public_key = r_public_key.move_as_ok(); + } + } + + if (!o_public_key) { + auto smc = ton::SmartContract::create(destination->get_smc_state()); + auto r_public_key = ton::GenericAccount::get_public_key(destination->get_smc_state()); + if (r_public_key.is_ok()) { + o_public_key = r_public_key.move_as_ok(); + } + } + + if (!o_public_key) { return TonlibError::MessageEncryption("Get public key (in destination)"); } - auto wallet = destination->get_wallet(); - TRY_RESULT_PREFIX(public_key, wallet->get_public_key(), - TonlibError::AccountActionUnsupported(PSLICE() << "Get public key (in destination) : " - << destination->get_wallet_type())); + + auto addr = source_->get_address(); + addr.bounceable = true; + addr.testnet = false; + TRY_RESULT_PREFIX(encrypted_message, - SimpleEncryptionV2::encrypt_data(action.message, public_key, private_key_.value()), + SimpleEncryptionV2::encrypt_data(action.message, o_public_key.unwrap(), private_key_.value(), + addr.rserialize(true)), TonlibError::Internal()); gift.message = encrypted_message.as_slice().str(); gift.is_encrypted = true; @@ -2548,7 +2605,7 @@ td::Status TonlibClient::do_request(tonlib_api::createQuery& request, } td::Status TonlibClient::do_request(tonlib_api::msg_decrypt& request, - td::Promise>&& promise) { + td::Promise>&& promise) { if (!request.input_key_) { return TonlibError::EmptyField("input_key"); } @@ -2556,27 +2613,44 @@ td::Status TonlibClient::do_request(tonlib_api::msg_decrypt& request, return TonlibError::EmptyField("data"); } TRY_RESULT(input_key, from_tonlib(*request.input_key_)); + using ReturnType = tonlib_api::object_ptr; make_request( int_api::GetPrivateKey{std::move(input_key)}, promise.wrap([elements = std::move(request.data_)](auto key) mutable { auto private_key = td::Ed25519::PrivateKey(std::move(key.private_key)); - elements->elements_ = td::transform(std::move(elements->elements_), [&private_key](auto msg) { + auto new_elements = td::transform(std::move(elements->elements_), [&private_key](auto msg) -> ReturnType { + auto res = tonlib_api::make_object(); if (!msg) { - return std::move(msg); + return res; + } + if (!msg->data_) { + return res; + } + res->data_ = std::move(msg->data_); + if (!msg->source_) { + return res; + } + auto r_account_address = get_account_address(msg->source_->account_address_); + if (r_account_address.is_error()) { + return res; } - using ReturnType = tonlib_api::object_ptr; return downcast_call2( - *msg, td::overloaded([&msg](auto&) { return std::move(msg); }, - [&msg, &private_key](tonlib_api::msg_dataEncryptedText& encrypted) -> ReturnType { - auto r_decrypted = SimpleEncryptionV2::decrypt_data(encrypted.text_, private_key); - if (r_decrypted.is_error()) { - return std::move(msg); - } - return tonlib_api::make_object( - r_decrypted.move_as_ok().as_slice().str()); - })); + *res->data_, + td::overloaded( + [&res](auto&) { return std::move(res); }, + [&res, &private_key, &msg](tonlib_api::msg_dataEncryptedText& encrypted) -> ReturnType { + auto r_decrypted = + SimpleEncryptionV2::decrypt_data(encrypted.text_, private_key, msg->source_->account_address_); + if (r_decrypted.is_error()) { + return std::move(res); + } + auto decrypted = r_decrypted.move_as_ok(); + return tonlib_api::make_object( + decrypted.proof.as_slice().str(), + tonlib_api::make_object(decrypted.data.as_slice().str())); + })); }); - return std::move(elements); + return tonlib_api::make_object(std::move(new_elements)); })); return td::Status::OK(); } @@ -3230,6 +3304,32 @@ tonlib_api::object_ptr TonlibClient::do_static_request(const SimpleEncryption::kdf(request.password_, request.salt_, request.iterations_)); } +tonlib_api::object_ptr TonlibClient::do_static_request( + const tonlib_api::msg_decryptWithProof& request) { + if (!request.data_) { + return status_to_tonlib_api(TonlibError::EmptyField("data")); + } + if (!request.data_->data_) { + TonlibError::EmptyField("data.data"); + } + if (!request.data_->source_) { + TonlibError::EmptyField("data.source"); + } + using ReturnType = tonlib_api::object_ptr; + return downcast_call2( + *request.data_->data_, + td::overloaded([&request](auto&) { return std::move(request.data_->data_); }, + [&request](tonlib_api::msg_dataEncryptedText& encrypted) -> ReturnType { + auto r_decrypted = SimpleEncryptionV2::decrypt_data_with_proof( + encrypted.text_, request.proof_, request.data_->source_->account_address_); + if (r_decrypted.is_error()) { + return std::move(request.data_->data_); + } + auto decrypted = r_decrypted.move_as_ok(); + return tonlib_api::make_object(decrypted.as_slice().str()); + })); +} + td::Status TonlibClient::do_request(int_api::GetAccountState request, td::Promise>&& promise) { auto actor_id = actor_id_++; @@ -3378,4 +3478,9 @@ td::Status TonlibClient::do_request(const tonlib_api::kdf& request, P&&) { UNREACHABLE(); return TonlibError::Internal(); } +template +td::Status TonlibClient::do_request(const tonlib_api::msg_decryptWithProof& request, P&&) { + UNREACHABLE(); + return TonlibError::Internal(); +} } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h index 786e4e7760..eaec1fcf8f 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/TonlibClient.h @@ -160,6 +160,8 @@ class TonlibClient : public td::actor::Actor { static object_ptr do_static_request(const tonlib_api::decrypt& request); static object_ptr do_static_request(const tonlib_api::kdf& request); + static object_ptr do_static_request(const tonlib_api::msg_decryptWithProof& request); + template td::Status do_request(const tonlib_api::runTests& request, P&&); template @@ -194,6 +196,8 @@ class TonlibClient : public td::actor::Actor { td::Status do_request(const tonlib_api::decrypt& request, P&&); template td::Status do_request(const tonlib_api::kdf& request, P&&); + template + td::Status do_request(const tonlib_api::msg_decryptWithProof& request, P&&); void make_any_request(tonlib_api::Function& function, QueryContext query_context, td::Promise>&& promise); @@ -281,7 +285,8 @@ class TonlibClient : public td::actor::Actor { td::Status do_request(tonlib_api::createQuery& request, td::Promise>&& promise); - td::Status do_request(tonlib_api::msg_decrypt& request, td::Promise>&& promise); + td::Status do_request(tonlib_api::msg_decrypt& request, + td::Promise>&& promise); td::int64 next_smc_id_{0}; std::map> smcs_; diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp index 456abf9968..00b90b6c90 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.cpp @@ -23,7 +23,7 @@ namespace tonlib { td::AesCbcState SimpleEncryption::calc_aes_cbc_state_hash(td::Slice hash) { - CHECK(hash.size() == 64); + CHECK(hash.size() >= 48); td::SecureString key(32); key.as_mutable_slice().copy_from(hash.substr(0, 32)); td::SecureString iv(16); @@ -34,7 +34,7 @@ td::AesCbcState SimpleEncryption::calc_aes_cbc_state_hash(td::Slice hash) { td::AesCbcState SimpleEncryption::calc_aes_cbc_state_sha512(td::Slice seed) { td::SecureString hash(64); sha512(seed, hash.as_mutable_slice()); - return calc_aes_cbc_state_hash(hash.as_slice()); + return calc_aes_cbc_state_hash(hash.as_slice().substr(0, 48)); } td::SecureString SimpleEncryption::gen_random_prefix(td::int64 data_size, td::int64 min_padding) { @@ -106,10 +106,10 @@ td::Result SimpleEncryption::decrypt_data(td::Slice encrypted_ return td::SecureString(decrypted_data.as_slice().substr(prefix_size)); } -td::Result SimpleEncryptionV2::encrypt_data(td::Slice data, - const td::Ed25519::PublicKey &public_key) { +td::Result SimpleEncryptionV2::encrypt_data(td::Slice data, const td::Ed25519::PublicKey &public_key, + td::Slice salt) { TRY_RESULT(tmp_private_key, td::Ed25519::generate_private_key()); - return encrypt_data(data, public_key, tmp_private_key); + return encrypt_data(data, public_key, tmp_private_key, salt); } namespace { @@ -124,9 +124,10 @@ td::SecureString secure_xor(td::Slice a, td::Slice b) { } // namespace td::Result SimpleEncryptionV2::encrypt_data(td::Slice data, const td::Ed25519::PublicKey &public_key, - const td::Ed25519::PrivateKey &private_key) { + const td::Ed25519::PrivateKey &private_key, + td::Slice salt) { TRY_RESULT(shared_secret, td::Ed25519::compute_shared_secret(public_key, private_key)); - auto encrypted = encrypt_data(data, shared_secret.as_slice()); + auto encrypted = encrypt_data(data, shared_secret.as_slice(), salt); TRY_RESULT(tmp_public_key, private_key.get_public_key()); td::SecureString prefixed_encrypted(tmp_public_key.LENGTH + encrypted.size()); prefixed_encrypted.as_mutable_slice().copy_from(tmp_public_key.as_octet_string()); @@ -136,8 +137,9 @@ td::Result SimpleEncryptionV2::encrypt_data(td::Slice data, co return std::move(prefixed_encrypted); } -td::Result SimpleEncryptionV2::decrypt_data(td::Slice data, - const td::Ed25519::PrivateKey &private_key) { +td::Result SimpleEncryptionV2::decrypt_data(td::Slice data, + const td::Ed25519::PrivateKey &private_key, + td::Slice salt) { if (data.size() < td::Ed25519::PublicKey::LENGTH) { return td::Status::Error("Failed to decrypte: data is too small"); } @@ -145,17 +147,19 @@ td::Result SimpleEncryptionV2::decrypt_data(td::Slice data, auto tmp_public_key = td::Ed25519::PublicKey(secure_xor(data.substr(0, td::Ed25519::PublicKey::LENGTH), public_key.as_octet_string())); TRY_RESULT(shared_secret, td::Ed25519::compute_shared_secret(tmp_public_key, private_key)); - TRY_RESULT(decrypted, decrypt_data(data.substr(td::Ed25519::PublicKey::LENGTH), shared_secret.as_slice())); + TRY_RESULT(decrypted, decrypt_data(data.substr(td::Ed25519::PublicKey::LENGTH), shared_secret.as_slice(), salt)); return std::move(decrypted); } -td::SecureString SimpleEncryptionV2::encrypt_data(td::Slice data, td::Slice secret) { + +td::SecureString SimpleEncryptionV2::encrypt_data(td::Slice data, td::Slice secret, td::Slice salt) { auto prefix = SimpleEncryption::gen_random_prefix(data.size(), 16); td::SecureString combined(prefix.size() + data.size()); combined.as_mutable_slice().copy_from(prefix); combined.as_mutable_slice().substr(prefix.size()).copy_from(data); - return encrypt_data_with_prefix(combined.as_slice(), secret); + return encrypt_data_with_prefix(combined.as_slice(), secret, salt); } -td::Result SimpleEncryptionV2::decrypt_data(td::Slice encrypted_data, td::Slice secret) { + +td::Result> unpack_encrypted_data(td::Slice encrypted_data) { if (encrypted_data.size() < 17) { return td::Status::Error("Failed to decrypt: data is too small"); } @@ -163,13 +167,18 @@ td::Result SimpleEncryptionV2::decrypt_data(td::Slice encrypte return td::Status::Error("Failed to decrypt: data size is not divisible by 16"); } auto msg_key = encrypted_data.substr(0, 16); - encrypted_data = encrypted_data.substr(16); + auto data = encrypted_data.substr(16); + return std::make_pair(msg_key, data); +} - auto cbc_state = SimpleEncryption::calc_aes_cbc_state_hash(SimpleEncryption::combine_secrets(secret, msg_key)); +td::Result SimpleEncryptionV2::do_decrypt(td::Slice cbc_state_secret, td::Slice msg_key, + td::Slice encrypted_data, td::Slice salt) { + auto cbc_state = SimpleEncryption::calc_aes_cbc_state_hash(cbc_state_secret); td::SecureString decrypted_data(encrypted_data.size(), 0); + auto iv_copy = cbc_state.raw().key.copy(); cbc_state.decrypt(encrypted_data, decrypted_data.as_mutable_slice()); - auto data_hash = SimpleEncryption::combine_secrets(decrypted_data, secret); + auto data_hash = SimpleEncryption::combine_secrets(salt, decrypted_data); auto got_msg_key = data_hash.as_slice().substr(0, 16); // check hash if (msg_key != got_msg_key) { @@ -183,9 +192,35 @@ td::Result SimpleEncryptionV2::decrypt_data(td::Slice encrypte return td::SecureString(decrypted_data.as_slice().substr(prefix_size)); } -td::SecureString SimpleEncryptionV2::encrypt_data_with_prefix(td::Slice data, td::Slice secret) { + +td::Result SimpleEncryptionV2::decrypt_data(td::Slice encrypted_data, td::Slice secret, + td::Slice salt) { + TRY_RESULT(p, unpack_encrypted_data(encrypted_data)); + auto msg_key = p.first; + auto data = p.second; + auto cbc_state_secret = td::SecureString(SimpleEncryption::combine_secrets(secret, msg_key).as_slice().substr(0, 48)); + TRY_RESULT(res, do_decrypt(cbc_state_secret.as_slice(), msg_key, data, salt)); + return Decrypted{std::move(cbc_state_secret), std::move(res)}; +} + +td::Result SimpleEncryptionV2::decrypt_data_with_proof(td::Slice encrypted_data, td::Slice proof, + td::Slice salt) { + if (encrypted_data.size() < td::Ed25519::PublicKey::LENGTH) { + return td::Status::Error("Failed to decrypte: data is too small"); + } + if (proof.size() != 48) { + return td::Status::Error("Invalid proof size"); + } + encrypted_data = encrypted_data.substr(td::Ed25519::PublicKey::LENGTH); + TRY_RESULT(p, unpack_encrypted_data(encrypted_data)); + auto msg_key = p.first; + auto data = p.second; + return do_decrypt(proof, msg_key, data, salt); +} + +td::SecureString SimpleEncryptionV2::encrypt_data_with_prefix(td::Slice data, td::Slice secret, td::Slice salt) { CHECK(data.size() % 16 == 0); - auto data_hash = SimpleEncryption::combine_secrets(data, secret); + auto data_hash = SimpleEncryption::combine_secrets(salt, data); auto msg_key = data_hash.as_slice().substr(0, 16); td::SecureString res_buf(data.size() + 16, 0); diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.h b/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.h index d170c26bce..bb613d7fed 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.h +++ b/submodules/ton/tonlib-src/tonlib/tonlib/keys/SimpleEncryption.h @@ -43,14 +43,27 @@ class SimpleEncryption { class SimpleEncryptionV2 { public: - static td::Result encrypt_data(td::Slice data, const td::Ed25519::PublicKey &public_key); - static td::Result decrypt_data(td::Slice data, const td::Ed25519::PrivateKey &private_key); static td::Result encrypt_data(td::Slice data, const td::Ed25519::PublicKey &public_key, - const td::Ed25519::PrivateKey &private_key); - static td::SecureString encrypt_data(td::Slice data, td::Slice secret); - static td::Result decrypt_data(td::Slice encrypted_data, td::Slice secret); + td::Slice salt = {}); + struct Decrypted { + td::SecureString proof; + td::SecureString data; + }; + + static td::Result decrypt_data(td::Slice data, const td::Ed25519::PrivateKey &private_key, + td::Slice sallt = {}); + static td::Result encrypt_data(td::Slice data, const td::Ed25519::PublicKey &public_key, + const td::Ed25519::PrivateKey &private_key, td::Slice salt = {}); + + static td::Result decrypt_data_with_proof(td::Slice encrypted_data, td::Slice proof, + td::Slice salt = {}); + + static td::SecureString encrypt_data(td::Slice data, td::Slice secret, td::Slice salt = {}); + static td::Result decrypt_data(td::Slice encrypted_data, td::Slice secret, td::Slice salt = {}); private: - static td::SecureString encrypt_data_with_prefix(td::Slice data, td::Slice secret); + static td::SecureString encrypt_data_with_prefix(td::Slice data, td::Slice secret, td::Slice salt = {}); + static td::Result do_decrypt(td::Slice cbc_state_secret, td::Slice msg_key, + td::Slice encrypted_data, td::Slice salt); }; } // namespace tonlib diff --git a/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp b/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp index 2f37df6851..44096f1287 100644 --- a/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp +++ b/submodules/ton/tonlib-src/tonlib/tonlib/tonlib-cli.cpp @@ -1384,10 +1384,10 @@ class TonlibCli : public td::actor::Actor { sb << "-" << Grams{td::uint64(-balance)}; } sb << " Fee: " << Grams{td::uint64(t->fee_)}; - if (t->in_msg_->source_.empty()) { + if (!t->in_msg_->source_->account_address_.empty()) { sb << " External "; } else { - sb << " From " << t->in_msg_->source_; + sb << " From " << t->in_msg_->source_->account_address_; } auto print_msg_data = [](td::StringBuilder& sb, tonlib_api::object_ptr& msg_data) { @@ -1406,10 +1406,10 @@ class TonlibCli : public td::actor::Actor { print_msg_data(sb, t->in_msg_->msg_data_); for (auto& ot : t->out_msgs_) { sb << "\n\t"; - if (ot->destination_.empty()) { + if (ot->destination_->account_address_.empty()) { sb << " External "; } else { - sb << " To " << ot->destination_; + sb << " To " << ot->destination_->account_address_; } sb << " " << Grams{td::uint64(ot->value_)}; print_msg_data(sb, ot->msg_data_); @@ -1476,8 +1476,8 @@ class TonlibCli : public td::actor::Actor { } else { data = tonlib_api::make_object(message.str()); } - messages.push_back( - tonlib_api::make_object(std::move(address.address), amount.nano, std::move(data))); + messages.push_back(tonlib_api::make_object(std::move(address.address), "", amount.nano, + std::move(data))); return td::Status::OK(); };