Update API

This commit is contained in:
Peter 2019-09-20 22:02:25 +04:00
parent 0f8c455216
commit 2c13c51e4f
52 changed files with 1524 additions and 560 deletions

View file

@ -51,18 +51,28 @@ NS_ASSUME_NONNULL_BEGIN
@interface TONTransaction : NSObject
@property (nonatomic, strong, readonly) NSData * _Nonnull data;
@property (nonatomic, strong, readonly) TONTransactionId * _Nonnull previousTransactionId;
@property (nonatomic, strong, readonly) TONTransactionId * _Nonnull transactionId;
@property (nonatomic, readonly) int64_t timestamp;
@property (nonatomic, readonly) int64_t fee;
@property (nonatomic, strong, readonly) TONTransactionMessage * _Nullable inMessage;
@property (nonatomic, strong, readonly) NSArray<TONTransactionMessage *> * _Nonnull outMessages;
- (instancetype)initWithData:(NSData * _Nonnull)data previousTransactionId:(TONTransactionId * _Nonnull)previousTransactionId inMessage:(TONTransactionMessage * _Nullable)inMessage outMessages:(NSArray<TONTransactionMessage *> * _Nonnull)outMessages;
- (instancetype)initWithData:(NSData * _Nonnull)data transactionId:(TONTransactionId * _Nonnull)transactionId timestamp:(int64_t)timestamp fee:(int64_t)fee inMessage:(TONTransactionMessage * _Nullable)inMessage outMessages:(NSArray<TONTransactionMessage *> * _Nonnull)outMessages;
@end
@interface TONExternalRequest : NSObject
@property (nonatomic, strong, readonly) NSData * _Nonnull data;
@property (nonatomic, copy, readonly) void (^onResult)(NSData * _Nullable, NSString * _Nullable);
- (instancetype)initWithData:(NSData * _Nonnull)data onResult:(void (^)(NSData * _Nullable, NSString * _Nullable))onResult;
@end
@interface TON : NSObject
- (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config;
- (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config performExternalRequest:(void (^)(TONExternalRequest * _Nonnull))performExternalRequest;
- (MTSignal *)createKeyWithLocalPassword:(NSData *)localPassword mnemonicPassword:(NSData *)mnemonicPassword;
- (MTSignal *)getTestWalletAccountAddressWithPublicKey:(NSString *)publicKey;

View file

@ -105,11 +105,13 @@ static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::obj
@implementation TONTransaction
- (instancetype)initWithData:(NSData * _Nonnull)data previousTransactionId:(TONTransactionId * _Nonnull)previousTransactionId inMessage:(TONTransactionMessage * _Nullable)inMessage outMessages:(NSArray<TONTransactionMessage *> * _Nonnull)outMessages {
- (instancetype)initWithData:(NSData * _Nonnull)data transactionId:(TONTransactionId * _Nonnull)transactionId timestamp:(int64_t)timestamp fee:(int64_t)fee inMessage:(TONTransactionMessage * _Nullable)inMessage outMessages:(NSArray<TONTransactionMessage *> * _Nonnull)outMessages {
self = [super init];
if (self != nil) {
_data = data;
_previousTransactionId = previousTransactionId;
_transactionId = transactionId;
_timestamp = timestamp;
_fee = fee;
_inMessage = inMessage;
_outMessages = outMessages;
}
@ -118,6 +120,19 @@ static TONTransactionMessage * _Nullable parseTransactionMessage(tonlib_api::obj
@end
@implementation TONExternalRequest
- (instancetype)initWithData:(NSData * _Nonnull)data onResult:(void (^)(NSData * _Nullable, NSString * _Nullable))onResult {
self = [super init];
if (self != nil) {
_data = data;
_onResult = [onResult copy];
}
return self;
}
@end
using tonlib_api::make_object;
@interface TONReceiveThreadParams : NSObject
@ -197,7 +212,7 @@ typedef enum {
}
}
- (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config {
- (instancetype)initWithKeystoreDirectory:(NSString *)keystoreDirectory config:(NSString *)config performExternalRequest:(void (^)(TONExternalRequest * _Nonnull))performExternalRequest {
self = [super init];
if (self != nil) {
_requestHandlersLock = [[NSLock alloc] init];
@ -208,9 +223,40 @@ typedef enum {
_client = std::make_shared<tonlib::Client>();
std::weak_ptr<tonlib::Client> weakClient = _client;
NSLock *requestHandlersLock = _requestHandlersLock;
NSMutableDictionary *requestHandlers = _requestHandlers;
NSThread *thread = [[NSThread alloc] initWithTarget:[self class] selector:@selector(receiveThread:) object:[[TONReceiveThreadParams alloc] initWithClient:_client received:^(tonlib::Client::Response &response) {
if (response.object->get_id() == tonlib_api::updateSendLiteServerQuery::ID) {
auto result = tonlib_api::move_object_as<tonlib_api::updateSendLiteServerQuery>(response.object);
int64_t requestId = result->id_;
NSData *data = makeData(result->data_);
if (performExternalRequest) {
performExternalRequest([[TONExternalRequest alloc] initWithData:data onResult:^(NSData * _Nullable result, NSString * _Nullable error) {
auto strongClient = weakClient.lock();
if (strongClient != nullptr) {
if (result != nil) {
auto query = make_object<tonlib_api::onLiteServerQueryResult>(
requestId,
makeString(result)
);
strongClient->send({ 1, std::move(query) });
} else if (error != nil) {
auto query = make_object<tonlib_api::onLiteServerQueryError>(
requestId,
make_object<tonlib_api::error>(
400,
error.UTF8String
)
);
strongClient->send({ 1, std::move(query) });
}
}
}]);
}
return;
}
NSNumber *requestId = @(response.id);
[requestHandlersLock lock];
TONRequestHandler *handler = requestHandlers[requestId];
@ -252,7 +298,11 @@ typedef enum {
}
}];
auto query = make_object<tonlib_api::init>(make_object<tonlib_api::options>(configString.UTF8String, keystoreDirectory.UTF8String));
auto query = make_object<tonlib_api::init>(make_object<tonlib_api::options>(
configString.UTF8String,
keystoreDirectory.UTF8String,
false
));
_client->send({ requestId, std::move(query) });
return [[MTBlockDisposable alloc] initWithBlock:^{
@ -656,7 +706,7 @@ typedef enum {
auto result = tonlib_api::move_object_as<tonlib_api::raw_transactions>(object);
NSMutableArray<TONTransaction *> *transactions = [[NSMutableArray alloc] init];
for (auto &it : result->transactions_) {
TONTransactionId *previousTransactionId = [[TONTransactionId alloc] initWithLt:it->previous_transaction_id_->lt_ transactionHash:makeData(it->previous_transaction_id_->hash_)];
TONTransactionId *transactionId = [[TONTransactionId alloc] initWithLt:it->transaction_id_->lt_ transactionHash:makeData(it->transaction_id_->hash_)];
TONTransactionMessage *inMessage = parseTransactionMessage(it->in_msg_);
NSMutableArray<TONTransactionMessage *> * outMessages = [[NSMutableArray alloc] init];
for (auto &messageIt : it->out_msgs_) {
@ -665,7 +715,7 @@ typedef enum {
[outMessages addObject:outMessage];
}
}
[transactions addObject:[[TONTransaction alloc] initWithData:makeData(it->data_) previousTransactionId:previousTransactionId inMessage:inMessage outMessages:outMessages]];
[transactions addObject:[[TONTransaction alloc] initWithData:makeData(it->data_) transactionId:transactionId timestamp:it->utime_ fee:it->fee_ inMessage:inMessage outMessages:outMessages]];
}
[subscriber putNext:transactions];
[subscriber putCompletion];

View file

@ -5,7 +5,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[570911930] = { return $0.readInt64() }
dict[571523412] = { return $0.readDouble() }
dict[-1255641564] = { return parseString($0) }
dict[-475111160] = { return Api.MessageReactionsList.parse_messageReactionsList($0) }
dict[-1240849242] = { return Api.messages.StickerSet.parse_stickerSet($0) }
dict[-457104426] = { return Api.InputGeoPoint.parse_inputGeoPointEmpty($0) }
dict[-206066487] = { return Api.InputGeoPoint.parse_inputGeoPoint($0) }
@ -96,7 +95,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[483104362] = { return Api.RichText.parse_textPhone($0) }
dict[136105807] = { return Api.RichText.parse_textImage($0) }
dict[894777186] = { return Api.RichText.parse_textAnchor($0) }
dict[-1684333439] = { return Api.UserFull.parse_userFull($0) }
dict[-302941166] = { return Api.UserFull.parse_userFull($0) }
dict[-292807034] = { return Api.InputChannel.parse_inputChannelEmpty($0) }
dict[-1343524562] = { return Api.InputChannel.parse_inputChannel($0) }
dict[414687501] = { return Api.DcOption.parse_dcOption($0) }
@ -167,7 +166,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1777000467] = { return Api.PrivacyKey.parse_privacyKeyProfilePhoto($0) }
dict[-778378131] = { return Api.PrivacyKey.parse_privacyKeyPhoneNumber($0) }
dict[1124062251] = { return Api.PrivacyKey.parse_privacyKeyAddedByPhone($0) }
dict[963559926] = { return Api.PrivacyKey.parse_privacyKeyWalletAddress($0) }
dict[522914557] = { return Api.Update.parse_updateNewMessage($0) }
dict[1318109142] = { return Api.Update.parse_updateMessageID($0) }
dict[-1576161051] = { return Api.Update.parse_updateDeleteMessages($0) }
@ -242,7 +240,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[967122427] = { return Api.Update.parse_updateNewScheduledMessage($0) }
dict[-1870238482] = { return Api.Update.parse_updateDeleteScheduledMessages($0) }
dict[-2112423005] = { return Api.Update.parse_updateTheme($0) }
dict[357013699] = { return Api.Update.parse_updateMessageReactions($0) }
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
@ -284,7 +281,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1012306921] = { return Api.InputTheme.parse_inputTheme($0) }
dict[-175567375] = { return Api.InputTheme.parse_inputThemeSlug($0) }
dict[1158290442] = { return Api.messages.FoundGifs.parse_foundGifs($0) }
dict[-1199954735] = { return Api.MessageReactions.parse_messageReactions($0) }
dict[-1132476723] = { return Api.FileLocation.parse_fileLocationToBeDeprecated($0) }
dict[-716006138] = { return Api.Poll.parse_poll($0) }
dict[423314455] = { return Api.InputNotifyPeer.parse_inputNotifyUsers($0) }
@ -452,7 +448,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1461304012] = { return Api.InputPrivacyKey.parse_inputPrivacyKeyProfilePhoto($0) }
dict[55761658] = { return Api.InputPrivacyKey.parse_inputPrivacyKeyPhoneNumber($0) }
dict[-786326563] = { return Api.InputPrivacyKey.parse_inputPrivacyKeyAddedByPhone($0) }
dict[-640916697] = { return Api.InputPrivacyKey.parse_inputPrivacyKeyWalletAddress($0) }
dict[235081943] = { return Api.help.RecentMeUrls.parse_recentMeUrls($0) }
dict[-1606526075] = { return Api.ReplyMarkup.parse_replyKeyboardHide($0) }
dict[-200242528] = { return Api.ReplyMarkup.parse_replyKeyboardForceReply($0) }
@ -564,7 +559,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1820043071] = { return Api.User.parse_user($0) }
dict[-2082087340] = { return Api.Message.parse_messageEmpty($0) }
dict[-1642487306] = { return Api.Message.parse_messageService($0) }
dict[-1752573244] = { return Api.Message.parse_message($0) }
dict[1160515173] = { return Api.Message.parse_message($0) }
dict[186120336] = { return Api.messages.RecentStickers.parse_recentStickersNotModified($0) }
dict[586395571] = { return Api.messages.RecentStickers.parse_recentStickers($0) }
dict[-182231723] = { return Api.InputFileLocation.parse_inputEncryptedFileLocation($0) }
@ -618,7 +613,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1625153079] = { return Api.InputWebFileLocation.parse_inputWebFileGeoPointLocation($0) }
dict[-332168592] = { return Api.MessageFwdHeader.parse_messageFwdHeader($0) }
dict[398898678] = { return Api.help.Support.parse_support($0) }
dict[1873957073] = { return Api.ReactionCount.parse_reactionCount($0) }
dict[1474492012] = { return Api.MessagesFilter.parse_inputMessagesFilterEmpty($0) }
dict[-1777752804] = { return Api.MessagesFilter.parse_inputMessagesFilterPhotos($0) }
dict[-1614803355] = { return Api.MessagesFilter.parse_inputMessagesFilterVideo($0) }
@ -646,7 +640,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1449145777] = { return Api.upload.CdnFile.parse_cdnFile($0) }
dict[1984136919] = { return Api.wallet.LiteResponse.parse_liteResponse($0) }
dict[415997816] = { return Api.help.InviteText.parse_inviteText($0) }
dict[-764945220] = { return Api.MessageUserReaction.parse_messageUserReaction($0) }
dict[-1937807902] = { return Api.BotInlineMessage.parse_botInlineMessageText($0) }
dict[982505656] = { return Api.BotInlineMessage.parse_botInlineMessageMediaGeo($0) }
dict[1984755728] = { return Api.BotInlineMessage.parse_botInlineMessageMediaAuto($0) }
@ -846,8 +839,6 @@ public struct Api {
public static func serializeObject(_ object: Any, buffer: Buffer, boxed: Swift.Bool) {
switch object {
case let _1 as Api.MessageReactionsList:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.StickerSet:
_1.serialize(buffer, boxed)
case let _1 as Api.InputGeoPoint:
@ -980,8 +971,6 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.messages.FoundGifs:
_1.serialize(buffer, boxed)
case let _1 as Api.MessageReactions:
_1.serialize(buffer, boxed)
case let _1 as Api.FileLocation:
_1.serialize(buffer, boxed)
case let _1 as Api.Poll:
@ -1272,8 +1261,6 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.help.Support:
_1.serialize(buffer, boxed)
case let _1 as Api.ReactionCount:
_1.serialize(buffer, boxed)
case let _1 as Api.MessagesFilter:
_1.serialize(buffer, boxed)
case let _1 as Api.messages.Dialogs:
@ -1286,8 +1273,6 @@ public struct Api {
_1.serialize(buffer, boxed)
case let _1 as Api.help.InviteText:
_1.serialize(buffer, boxed)
case let _1 as Api.MessageUserReaction:
_1.serialize(buffer, boxed)
case let _1 as Api.BotInlineMessage:
_1.serialize(buffer, boxed)
case let _1 as Api.InputPeerNotifySettings:

View file

@ -1,66 +1,4 @@
public extension Api {
public enum MessageReactionsList: TypeConstructorDescription {
case messageReactionsList(flags: Int32, count: Int32, reactions: [Api.MessageUserReaction], users: [Api.User], nextOffset: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .messageReactionsList(let flags, let count, let reactions, let users, let nextOffset):
if boxed {
buffer.appendInt32(-475111160)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(reactions.count))
for item in reactions {
item.serialize(buffer, true)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count))
for item in users {
item.serialize(buffer, true)
}
if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .messageReactionsList(let flags, let count, let reactions, let users, let nextOffset):
return ("messageReactionsList", [("flags", flags), ("count", count), ("reactions", reactions), ("users", users), ("nextOffset", nextOffset)])
}
}
public static func parse_messageReactionsList(_ reader: BufferReader) -> MessageReactionsList? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: [Api.MessageUserReaction]?
if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageUserReaction.self)
}
var _4: [Api.User]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
var _5: String?
if Int(_1!) & Int(1 << 0) != 0 {_5 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.MessageReactionsList.messageReactionsList(flags: _1!, count: _2!, reactions: _3!, users: _4!, nextOffset: _5)
}
else {
return nil
}
}
}
public enum InputGeoPoint: TypeConstructorDescription {
case inputGeoPointEmpty
case inputGeoPoint(lat: Double, long: Double)
@ -2650,13 +2588,13 @@ public extension Api {
}
public enum UserFull: TypeConstructorDescription {
case userFull(flags: Int32, user: Api.User, about: String?, settings: Api.PeerSettings, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, walletAddress: String?)
case userFull(flags: Int32, user: Api.User, about: String?, settings: Api.PeerSettings, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let walletAddress):
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId):
if boxed {
buffer.appendInt32(-1684333439)
buffer.appendInt32(-302941166)
}
serializeInt32(flags, buffer: buffer, boxed: false)
user.serialize(buffer, true)
@ -2668,15 +2606,14 @@ public extension Api {
if Int(flags) & Int(1 << 6) != 0 {serializeInt32(pinnedMsgId!, buffer: buffer, boxed: false)}
serializeInt32(commonChatsCount, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(folderId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {serializeString(walletAddress!, buffer: buffer, boxed: false)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let walletAddress):
return ("userFull", [("flags", flags), ("user", user), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId), ("walletAddress", walletAddress)])
case .userFull(let flags, let user, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId):
return ("userFull", [("flags", flags), ("user", user), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId)])
}
}
@ -2711,8 +2648,6 @@ public extension Api {
_9 = reader.readInt32()
var _10: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
var _11: String?
if Int(_1!) & Int(1 << 13) != 0 {_11 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
@ -2723,9 +2658,8 @@ public extension Api {
let _c8 = (Int(_1!) & Int(1 << 6) == 0) || _8 != nil
let _c9 = _9 != nil
let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 13) == 0) || _11 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
return Api.UserFull.userFull(flags: _1!, user: _2!, about: _3, settings: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10, walletAddress: _11)
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
return Api.UserFull.userFull(flags: _1!, user: _2!, about: _3, settings: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10)
}
else {
return nil
@ -3972,7 +3906,6 @@ public extension Api {
case privacyKeyProfilePhoto
case privacyKeyPhoneNumber
case privacyKeyAddedByPhone
case privacyKeyWalletAddress
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -4023,12 +3956,6 @@ public extension Api {
buffer.appendInt32(1124062251)
}
break
case .privacyKeyWalletAddress:
if boxed {
buffer.appendInt32(963559926)
}
break
}
}
@ -4051,8 +3978,6 @@ public extension Api {
return ("privacyKeyPhoneNumber", [])
case .privacyKeyAddedByPhone:
return ("privacyKeyAddedByPhone", [])
case .privacyKeyWalletAddress:
return ("privacyKeyWalletAddress", [])
}
}
@ -4080,9 +4005,6 @@ public extension Api {
public static func parse_privacyKeyAddedByPhone(_ reader: BufferReader) -> PrivacyKey? {
return Api.PrivacyKey.privacyKeyAddedByPhone
}
public static func parse_privacyKeyWalletAddress(_ reader: BufferReader) -> PrivacyKey? {
return Api.PrivacyKey.privacyKeyWalletAddress
}
}
public enum Update: TypeConstructorDescription {
@ -4160,7 +4082,6 @@ public extension Api {
case updateNewScheduledMessage(message: Api.Message)
case updateDeleteScheduledMessages(peer: Api.Peer, messages: [Int32])
case updateTheme(theme: Api.Theme)
case updateMessageReactions(peer: Api.Peer, msgId: Int32, reactions: Api.MessageReactions)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -4785,14 +4706,6 @@ public extension Api {
}
theme.serialize(buffer, true)
break
case .updateMessageReactions(let peer, let msgId, let reactions):
if boxed {
buffer.appendInt32(357013699)
}
peer.serialize(buffer, true)
serializeInt32(msgId, buffer: buffer, boxed: false)
reactions.serialize(buffer, true)
break
}
}
@ -4946,8 +4859,6 @@ public extension Api {
return ("updateDeleteScheduledMessages", [("peer", peer), ("messages", messages)])
case .updateTheme(let theme):
return ("updateTheme", [("theme", theme)])
case .updateMessageReactions(let peer, let msgId, let reactions):
return ("updateMessageReactions", [("peer", peer), ("msgId", msgId), ("reactions", reactions)])
}
}
@ -6206,27 +6117,6 @@ public extension Api {
return nil
}
}
public static func parse_updateMessageReactions(_ reader: BufferReader) -> Update? {
var _1: Api.Peer?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _2: Int32?
_2 = reader.readInt32()
var _3: Api.MessageReactions?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.MessageReactions
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateMessageReactions(peer: _1!, msgId: _2!, reactions: _3!)
}
else {
return nil
}
}
}
public enum PopularContact: TypeConstructorDescription {
@ -7182,50 +7072,6 @@ public extension Api {
}
}
}
public enum MessageReactions: TypeConstructorDescription {
case messageReactions(flags: Int32, results: [Api.ReactionCount])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .messageReactions(let flags, let results):
if boxed {
buffer.appendInt32(-1199954735)
}
serializeInt32(flags, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(results.count))
for item in results {
item.serialize(buffer, true)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .messageReactions(let flags, let results):
return ("messageReactions", [("flags", flags), ("results", results)])
}
}
public static func parse_messageReactions(_ reader: BufferReader) -> MessageReactions? {
var _1: Int32?
_1 = reader.readInt32()
var _2: [Api.ReactionCount]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ReactionCount.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.MessageReactions.messageReactions(flags: _1!, results: _2!)
}
else {
return nil
}
}
}
public enum FileLocation: TypeConstructorDescription {
case fileLocationToBeDeprecated(volumeId: Int64, localId: Int32)
@ -11074,7 +10920,6 @@ public extension Api {
case inputPrivacyKeyProfilePhoto
case inputPrivacyKeyPhoneNumber
case inputPrivacyKeyAddedByPhone
case inputPrivacyKeyWalletAddress
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -11125,12 +10970,6 @@ public extension Api {
buffer.appendInt32(-786326563)
}
break
case .inputPrivacyKeyWalletAddress:
if boxed {
buffer.appendInt32(-640916697)
}
break
}
}
@ -11153,8 +10992,6 @@ public extension Api {
return ("inputPrivacyKeyPhoneNumber", [])
case .inputPrivacyKeyAddedByPhone:
return ("inputPrivacyKeyAddedByPhone", [])
case .inputPrivacyKeyWalletAddress:
return ("inputPrivacyKeyWalletAddress", [])
}
}
@ -11182,9 +11019,6 @@ public extension Api {
public static func parse_inputPrivacyKeyAddedByPhone(_ reader: BufferReader) -> InputPrivacyKey? {
return Api.InputPrivacyKey.inputPrivacyKeyAddedByPhone
}
public static func parse_inputPrivacyKeyWalletAddress(_ reader: BufferReader) -> InputPrivacyKey? {
return Api.InputPrivacyKey.inputPrivacyKeyWalletAddress
}
}
public enum ReplyMarkup: TypeConstructorDescription {
@ -14350,7 +14184,7 @@ public extension Api {
public enum Message: TypeConstructorDescription {
case messageEmpty(id: Int32)
case messageService(flags: Int32, id: Int32, fromId: Int32?, toId: Api.Peer, replyToMsgId: Int32?, date: Int32, action: Api.MessageAction)
case message(flags: Int32, id: Int32, fromId: Int32?, toId: Api.Peer, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyToMsgId: Int32?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?)
case message(flags: Int32, id: Int32, fromId: Int32?, toId: Api.Peer, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyToMsgId: Int32?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, restrictionReason: [Api.RestrictionReason]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -14372,9 +14206,9 @@ public extension Api {
serializeInt32(date, buffer: buffer, boxed: false)
action.serialize(buffer, true)
break
case .message(let flags, let id, let fromId, let toId, let fwdFrom, let viaBotId, let replyToMsgId, let date, let message, let media, let replyMarkup, let entities, let views, let editDate, let postAuthor, let groupedId, let reactions, let restrictionReason):
case .message(let flags, let id, let fromId, let toId, let fwdFrom, let viaBotId, let replyToMsgId, let date, let message, let media, let replyMarkup, let entities, let views, let editDate, let postAuthor, let groupedId, let restrictionReason):
if boxed {
buffer.appendInt32(-1752573244)
buffer.appendInt32(1160515173)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
@ -14396,7 +14230,6 @@ public extension Api {
if Int(flags) & Int(1 << 15) != 0 {serializeInt32(editDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 16) != 0 {serializeString(postAuthor!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 17) != 0 {serializeInt64(groupedId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 20) != 0 {reactions!.serialize(buffer, true)}
if Int(flags) & Int(1 << 22) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(restrictionReason!.count))
for item in restrictionReason! {
@ -14412,8 +14245,8 @@ public extension Api {
return ("messageEmpty", [("id", id)])
case .messageService(let flags, let id, let fromId, let toId, let replyToMsgId, let date, let action):
return ("messageService", [("flags", flags), ("id", id), ("fromId", fromId), ("toId", toId), ("replyToMsgId", replyToMsgId), ("date", date), ("action", action)])
case .message(let flags, let id, let fromId, let toId, let fwdFrom, let viaBotId, let replyToMsgId, let date, let message, let media, let replyMarkup, let entities, let views, let editDate, let postAuthor, let groupedId, let reactions, let restrictionReason):
return ("message", [("flags", flags), ("id", id), ("fromId", fromId), ("toId", toId), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyToMsgId", replyToMsgId), ("date", date), ("message", message), ("media", media), ("replyMarkup", replyMarkup), ("entities", entities), ("views", views), ("editDate", editDate), ("postAuthor", postAuthor), ("groupedId", groupedId), ("reactions", reactions), ("restrictionReason", restrictionReason)])
case .message(let flags, let id, let fromId, let toId, let fwdFrom, let viaBotId, let replyToMsgId, let date, let message, let media, let replyMarkup, let entities, let views, let editDate, let postAuthor, let groupedId, let restrictionReason):
return ("message", [("flags", flags), ("id", id), ("fromId", fromId), ("toId", toId), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyToMsgId", replyToMsgId), ("date", date), ("message", message), ("media", media), ("replyMarkup", replyMarkup), ("entities", entities), ("views", views), ("editDate", editDate), ("postAuthor", postAuthor), ("groupedId", groupedId), ("restrictionReason", restrictionReason)])
}
}
@ -14504,13 +14337,9 @@ public extension Api {
if Int(_1!) & Int(1 << 16) != 0 {_15 = parseString(reader) }
var _16: Int64?
if Int(_1!) & Int(1 << 17) != 0 {_16 = reader.readInt64() }
var _17: Api.MessageReactions?
if Int(_1!) & Int(1 << 20) != 0 {if let signature = reader.readInt32() {
_17 = Api.parse(reader, signature: signature) as? Api.MessageReactions
} }
var _18: [Api.RestrictionReason]?
var _17: [Api.RestrictionReason]?
if Int(_1!) & Int(1 << 22) != 0 {if let _ = reader.readInt32() {
_18 = Api.parseVector(reader, elementSignature: 0, elementType: Api.RestrictionReason.self)
_17 = Api.parseVector(reader, elementSignature: 0, elementType: Api.RestrictionReason.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
@ -14528,10 +14357,9 @@ public extension Api {
let _c14 = (Int(_1!) & Int(1 << 15) == 0) || _14 != nil
let _c15 = (Int(_1!) & Int(1 << 16) == 0) || _15 != nil
let _c16 = (Int(_1!) & Int(1 << 17) == 0) || _16 != nil
let _c17 = (Int(_1!) & Int(1 << 20) == 0) || _17 != nil
let _c18 = (Int(_1!) & Int(1 << 22) == 0) || _18 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 {
return Api.Message.message(flags: _1!, id: _2!, fromId: _3, toId: _4!, fwdFrom: _5, viaBotId: _6, replyToMsgId: _7, date: _8!, message: _9!, media: _10, replyMarkup: _11, entities: _12, views: _13, editDate: _14, postAuthor: _15, groupedId: _16, reactions: _17, restrictionReason: _18)
let _c17 = (Int(_1!) & Int(1 << 22) == 0) || _17 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 {
return Api.Message.message(flags: _1!, id: _2!, fromId: _3, toId: _4!, fwdFrom: _5, viaBotId: _6, replyToMsgId: _7, date: _8!, message: _9!, media: _10, replyMarkup: _11, entities: _12, views: _13, editDate: _14, postAuthor: _15, groupedId: _16, restrictionReason: _17)
}
else {
return nil
@ -16024,48 +15852,6 @@ public extension Api {
}
}
}
public enum ReactionCount: TypeConstructorDescription {
case reactionCount(flags: Int32, reaction: String, count: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .reactionCount(let flags, let reaction, let count):
if boxed {
buffer.appendInt32(1873957073)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(reaction, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .reactionCount(let flags, let reaction, let count):
return ("reactionCount", [("flags", flags), ("reaction", reaction), ("count", count)])
}
}
public static func parse_reactionCount(_ reader: BufferReader) -> ReactionCount? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.ReactionCount.reactionCount(flags: _1!, reaction: _2!, count: _3!)
}
else {
return nil
}
}
}
public enum MessagesFilter: TypeConstructorDescription {
case inputMessagesFilterEmpty
@ -16378,44 +16164,6 @@ public extension Api {
}
}
}
public enum MessageUserReaction: TypeConstructorDescription {
case messageUserReaction(userId: Int32, reaction: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .messageUserReaction(let userId, let reaction):
if boxed {
buffer.appendInt32(-764945220)
}
serializeInt32(userId, buffer: buffer, boxed: false)
serializeString(reaction, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .messageUserReaction(let userId, let reaction):
return ("messageUserReaction", [("userId", userId), ("reaction", reaction)])
}
}
public static func parse_messageUserReaction(_ reader: BufferReader) -> MessageUserReaction? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.MessageUserReaction.messageUserReaction(userId: _1!, reaction: _2!)
}
else {
return nil
}
}
}
public enum BotInlineMessage: TypeConstructorDescription {
case botInlineMessageText(flags: Int32, message: String, entities: [Api.MessageEntity]?, replyMarkup: Api.ReplyMarkup?)

View file

@ -3161,61 +3161,6 @@ public extension Api {
return result
})
}
public static func sendReaction(flags: Int32, peer: Api.InputPeer, msgId: Int32, reaction: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(627641572)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(msgId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(reaction!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.sendReaction", parameters: [("flags", flags), ("peer", peer), ("msgId", msgId), ("reaction", reaction)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
public static func getMessagesReactions(peer: Api.InputPeer, id: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-1950707482)
peer.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(id.count))
for item in id {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "messages.getMessagesReactions", parameters: [("peer", peer), ("id", id)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
public static func getMessageReactionsList(flags: Int32, peer: Api.InputPeer, id: Int32, reaction: String?, offset: String?, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.MessageReactionsList>) {
let buffer = Buffer()
buffer.appendInt32(363935594)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(id, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeString(reaction!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {serializeString(offset!, buffer: buffer, boxed: false)}
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getMessageReactionsList", parameters: [("flags", flags), ("peer", peer), ("id", id), ("reaction", reaction), ("offset", offset), ("limit", limit)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.MessageReactionsList? in
let reader = BufferReader(buffer)
var result: Api.MessageReactionsList?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.MessageReactionsList
}
return result
})
}
}
public struct channels {
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
@ -5890,20 +5835,6 @@ public extension Api {
return result
})
}
public static func setWalletAddress(walletAddress: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1588431790)
serializeString(walletAddress, buffer: buffer, boxed: false)
return (FunctionDescription(name: "account.setWalletAddress", parameters: [("walletAddress", walletAddress)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public struct wallet {
public static func sendLiteRequest(body: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.wallet.LiteResponse>) {

View file

@ -57,7 +57,7 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
var updatedTimestamp: Int32?
if let apiMessage = apiMessage {
switch apiMessage {
case let .message(_, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _):
case let .message(_, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _):
updatedTimestamp = date
case .messageEmpty:
break

View file

@ -82,7 +82,7 @@ private final class MessageReactionCategoryContext {
self.state.loadingMore = true
self.statePromise.set(self.state)
var flags: Int32 = 0
/*var flags: Int32 = 0
var reaction: String?
switch self.category {
case .all:
@ -150,7 +150,7 @@ private final class MessageReactionCategoryContext {
})
}, error: { _ in
}))
}))*/
}
}

View file

@ -61,7 +61,8 @@ private enum RequestUpdateMessageReactionError {
}
private func requestUpdateMessageReaction(postbox: Postbox, network: Network, stateManager: AccountStateManager, messageId: MessageId) -> Signal<Never, RequestUpdateMessageReactionError> {
return postbox.transaction { transaction -> (Peer, String?)? in
return .complete()
/*return postbox.transaction { transaction -> (Peer, String?)? in
guard let peer = transaction.getPeer(messageId.peerId) else {
return nil
}
@ -117,7 +118,7 @@ private func requestUpdateMessageReaction(postbox: Postbox, network: Network, st
|> introduceError(RequestUpdateMessageReactionError.self)
|> ignoreValues
}
}
}*/
}
private final class ManagedApplyPendingMessageReactionsActionsHelper {

View file

@ -46,7 +46,7 @@ public final class ReactionsMessageAttribute: MessageAttribute {
encoder.encodeObjectArray(self.reactions, forKey: "r")
}
func withUpdatedResults(_ reactions: Api.MessageReactions) -> ReactionsMessageAttribute {
/*func withUpdatedResults(_ reactions: Api.MessageReactions) -> ReactionsMessageAttribute {
switch reactions {
case let .messageReactions(flags, results):
let min = (flags & (1 << 0)) != 0
@ -74,7 +74,7 @@ public final class ReactionsMessageAttribute: MessageAttribute {
}
return ReactionsMessageAttribute(reactions: reactions)
}
}
}*/
}
public func mergedMessageReactions(attributes: [MessageAttribute]) -> ReactionsMessageAttribute? {
@ -147,7 +147,7 @@ public final class PendingReactionsMessageAttribute: MessageAttribute {
}
}
extension ReactionsMessageAttribute {
/*extension ReactionsMessageAttribute {
convenience init(apiReactions: Api.MessageReactions) {
switch apiReactions {
case let .messageReactions(_, results):
@ -159,4 +159,4 @@ extension ReactionsMessageAttribute {
})
}
}
}
}*/

View file

@ -111,7 +111,10 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
func apiMessagePeerId(_ messsage: Api.Message) -> PeerId? {
switch messsage {
case let .message(flags, _, fromId, toId, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(message):
let flags = message.flags
let fromId = message.fromId
let toId = message.toId
switch toId {
case let .peerUser(userId):
return PeerId(namespace: Namespaces.Peer.CloudUser, id: (flags & Int32(2)) != 0 ? userId : (fromId ?? userId))
@ -136,7 +139,7 @@ func apiMessagePeerId(_ messsage: Api.Message) -> PeerId? {
func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
switch message {
case let .message(flags, _, fromId, toId, fwdHeader, viaBotId, _, _, _, media, _, entities, _, _, _, _, _, _):
case let .message(flags, _, fromId, toId, fwdHeader, viaBotId, _, _, _, media, _, entities, _, _, _, _, _):
let peerId: PeerId
switch toId {
case let .peerUser(userId):
@ -240,7 +243,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
func apiMessageAssociatedMessageIds(_ message: Api.Message) -> [MessageId]? {
switch message {
case let .message(flags, _, fromId, toId, _, _, replyToMsgId, _, _, _, _, _, _, _, _, _, _, _):
case let .message(flags, _, fromId, toId, _, _, replyToMsgId, _, _, _, _, _, _, _, _, _, _):
if let replyToMsgId = replyToMsgId {
let peerId: PeerId
switch toId {
@ -382,7 +385,7 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
extension StoreMessage {
convenience init?(apiMessage: Api.Message, namespace: MessageId.Namespace = Namespaces.Message.Cloud) {
switch apiMessage {
case let .message(flags, id, fromId, toId, fwdFrom, viaBotId, replyToMsgId, date, message, media, replyMarkup, entities, views, editDate, postAuthor, groupingId, reactions, restrictionReason):
case let .message(flags, id, fromId, toId, fwdFrom, viaBotId, replyToMsgId, date, message, media, replyMarkup, entities, views, editDate, postAuthor, groupingId, restrictionReason):
let peerId: PeerId
var authorId: PeerId?
switch toId {
@ -537,9 +540,9 @@ extension StoreMessage {
attributes.append(ContentRequiresValidationMessageAttribute())
}
if let reactions = reactions {
/*if let reactions = reactions {
attributes.append(ReactionsMessageAttribute(apiReactions: reactions))
}
}*/
if let restrictionReason = restrictionReason {
attributes.append(RestrictedContentMessageAttribute(rules: restrictionReason.map(RestrictionRule.init(apiReason:))))

View file

@ -69,7 +69,7 @@ class UpdateMessageService: NSObject, MTMessageService {
self.putNext(groups)
}
case let .updateShortChatMessage(flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyToMsgId, entities):
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: fromId, toId: Api.Peer.peerChat(chatId: chatId), fwdFrom: fwdFrom, viaBotId: viaBotId, replyToMsgId: replyToMsgId, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil)
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: fromId, toId: Api.Peer.peerChat(chatId: chatId), fwdFrom: fwdFrom, viaBotId: viaBotId, replyToMsgId: replyToMsgId, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil)
let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
if groups.count != 0 {
@ -86,7 +86,7 @@ class UpdateMessageService: NSObject, MTMessageService {
generatedToId = Api.Peer.peerUser(userId: self.peerId.id)
}
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, toId: generatedToId, fwdFrom: fwdFrom, viaBotId: viaBotId, replyToMsgId: replyToMsgId, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, editDate: nil, postAuthor: nil, groupedId: nil, reactions: nil, restrictionReason: nil)
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, toId: generatedToId, fwdFrom: fwdFrom, viaBotId: viaBotId, replyToMsgId: replyToMsgId, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil)
let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
if groups.count != 0 {

View file

@ -100,8 +100,8 @@ extension Api.MessageMedia {
extension Api.Message {
var rawId: Int32 {
switch self {
case let .message(_, id, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
return id
case let .message(message):
return message.id
case let .messageEmpty(id):
return id
case let .messageService(_, id, _, _, _, _, _):
@ -111,7 +111,12 @@ extension Api.Message {
func id(namespace: MessageId.Namespace = Namespaces.Message.Cloud) -> MessageId? {
switch self {
case let .message(flags, id, fromId, toId, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
case let .message(message):
let flags = message.flags
let id = message.id
let fromId = message.fromId
let toId = message.toId
let peerId: PeerId
switch toId {
case let .peerUser(userId):
@ -146,10 +151,10 @@ extension Api.Message {
var timestamp: Int32? {
switch self {
case let .message(_, _, _, _, _, _, _, date, _, _, _, _, _, _, _, _, _, _):
return date
case let .messageService(_, _, _, _, _, date, _):
return date
case let .message(message):
return message.date
case let .messageService(messageService):
return messageService.date
case .messageEmpty:
return nil
}
@ -157,8 +162,8 @@ extension Api.Message {
var preCachedResources: [(MediaResource, Data)]? {
switch self {
case let .message(_, _, _, _, _, _, _, _, _, media, _, _, _, _, _, _, _, _):
return media?.preCachedResources
case let .message(message):
return message.media?.preCachedResources
default:
return nil
}

View file

@ -25,12 +25,14 @@ private final class TonInstanceImpl {
private let queue: Queue
private let basePath: String
private let config: String
private let network: Network
private var instance: TON?
init(queue: Queue, basePath: String, config: String) {
init(queue: Queue, basePath: String, config: String, network: Network) {
self.queue = queue
self.basePath = basePath
self.config = config
self.network = network
}
func withInstance(_ f: (TON) -> Void) {
@ -38,7 +40,17 @@ private final class TonInstanceImpl {
if let current = self.instance {
instance = current
} else {
instance = TON(keystoreDirectory: self.basePath + "/ton-keystore", config: self.config)
let network = self.network
instance = TON(keystoreDirectory: self.basePath + "/ton-keystore", config: self.config, performExternalRequest: { request in
let _ = (network.request(Api.functions.wallet.sendLiteRequest(body: Buffer(data: request.data)))).start(next: { result in
switch result {
case let .liteResponse(response):
request.onResult(response.makeData(), nil)
}
}, error: { error in
request.onResult(nil, error.errorDescription)
})
})
self.instance = instance
}
f(instance)
@ -49,11 +61,11 @@ public final class TonInstance {
private let queue: Queue
private let impl: QueueLocalObject<TonInstanceImpl>
public init(basePath: String, config: String) {
public init(basePath: String, config: String, network: Network) {
self.queue = .mainQueue()
let queue = self.queue
self.impl = QueueLocalObject(queue: queue, generate: {
return TonInstanceImpl(queue: queue, basePath: basePath, config: config)
return TonInstanceImpl(queue: queue, basePath: basePath, config: config, network: network)
})
}
@ -557,7 +569,8 @@ private extension WalletTransactionMessage {
public final class WalletTransaction: Equatable {
public let data: Data
public let previousTransactionId: WalletTransactionId
public let transactionId: WalletTransactionId
public let timestamp: Int64
public let fee: Int64
public let inMessage: WalletTransactionMessage?
public let outMessages: [WalletTransactionMessage]
@ -574,9 +587,10 @@ public final class WalletTransaction: Equatable {
return value
}
init(data: Data, previousTransactionId: WalletTransactionId, fee: Int64, inMessage: WalletTransactionMessage?, outMessages: [WalletTransactionMessage]) {
init(data: Data, transactionId: WalletTransactionId, timestamp: Int64, fee: Int64, inMessage: WalletTransactionMessage?, outMessages: [WalletTransactionMessage]) {
self.data = data
self.previousTransactionId = previousTransactionId
self.transactionId = transactionId
self.timestamp = timestamp
self.fee = fee
self.inMessage = inMessage
self.outMessages = outMessages
@ -586,7 +600,10 @@ public final class WalletTransaction: Equatable {
if lhs.data != rhs.data {
return false
}
if lhs.previousTransactionId != rhs.previousTransactionId {
if lhs.transactionId != rhs.transactionId {
return false
}
if lhs.timestamp != rhs.timestamp {
return false
}
if lhs.fee != rhs.fee {
@ -604,7 +621,7 @@ public final class WalletTransaction: Equatable {
private extension WalletTransaction {
convenience init(tonTransaction: TONTransaction) {
self.init(data: tonTransaction.data, previousTransactionId: WalletTransactionId(tonTransactionId: tonTransaction.previousTransactionId), fee: tonTransaction.fee, inMessage: tonTransaction.inMessage.flatMap(WalletTransactionMessage.init(tonTransactionMessage:)), outMessages: tonTransaction.outMessages.map(WalletTransactionMessage.init(tonTransactionMessage:)))
self.init(data: tonTransaction.data, transactionId: WalletTransactionId(tonTransactionId: tonTransaction.transactionId), timestamp: tonTransaction.timestamp, fee: tonTransaction.fee, inMessage: tonTransaction.inMessage.flatMap(WalletTransactionMessage.init(tonTransactionMessage:)), outMessages: tonTransaction.outMessages.map(WalletTransactionMessage.init(tonTransactionMessage:)))
}
}

View file

@ -923,7 +923,7 @@ final class SharedApplicationContext {
return accountAndSettings.flatMap { account, limitsConfiguration, callListSettings in
var tonContext: TonContext?
if let path = getAppBundle().path(forResource: "cfg", ofType: "txt"), let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let config = String(data: data, encoding: .utf8) {
tonContext = TonContext(instance: TonInstance(basePath: account.basePath, config: config), keychain: tonKeychain)
tonContext = TonContext(instance: TonInstance(basePath: account.basePath, config: config, network: account.network), keychain: tonKeychain)
}
let context = AccountContextImpl(sharedContext: sharedApplicationContext.sharedContext, account: account, tonContext: tonContext, limitsConfiguration: limitsConfiguration)
return AuthorizedApplicationContext(sharedApplicationContext: sharedApplicationContext, mainWindow: self.mainWindow, watchManagerArguments: watchManagerArgumentsPromise.get(), context: context, accountManager: sharedApplicationContext.sharedContext.accountManager, showCallsTab: callListSettings.showTab, reinitializedNotificationSettings: {

View file

@ -20,6 +20,7 @@ static_library(
"//submodules/AlertUI:AlertUI",
"//submodules/MergeLists:MergeLists",
"//submodules/ItemListUI:ItemListUI",
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
],
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",

View file

@ -280,16 +280,16 @@ private struct WalletInfoListEntry: Equatable, Comparable, Identifiable {
let item: WalletTransaction
var stableId: WalletTransactionId {
return self.item.previousTransactionId
return self.item.transactionId
}
static func <(lhs: WalletInfoListEntry, rhs: WalletInfoListEntry) -> Bool {
return lhs.index < rhs.index
}
func item(theme: PresentationTheme, action: @escaping (WalletTransaction) -> Void) -> ListViewItem {
func item(theme: PresentationTheme, strings: PresentationStrings, action: @escaping (WalletTransaction) -> Void) -> ListViewItem {
let item = self.item
return WalletInfoTransactionItem(theme: theme, walletTransaction: self.item, action: {
return WalletInfoTransactionItem(theme: theme, strings: strings, walletTransaction: self.item, action: {
action(item)
})
}
@ -299,8 +299,8 @@ private func preparedTransition(from fromEntries: [WalletInfoListEntry], to toEn
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(theme: presentationData.theme, action: action), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(theme: presentationData.theme, action: action), directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(theme: presentationData.theme, strings: presentationData.strings, action: action), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(theme: presentationData.theme, strings: presentationData.strings, action: action), directionHint: nil) }
return WalletInfoListTransaction(deletions: deletions, insertions: insertions, updates: updates)
}
@ -460,7 +460,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode {
listViewCurve = .Default(duration: duration)
}
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: UIEdgeInsets(top: topInset, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), scrollIndicatorInsets: UIEdgeInsets(top: topInset + 3.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), duration: duration, curve: listViewCurve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: UIEdgeInsets(top: topInset, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), headerInsets: UIEdgeInsets(top: navigationHeight, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), scrollIndicatorInsets: UIEdgeInsets(top: topInset + 3.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), duration: duration, curve: listViewCurve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
let emptyNodeHeight = self.emptyNode.updateLayout(width: layout.size.width, transition: transition)
let maxEmptyNodeHeight: CGFloat = max(100.0, layout.size.height - headerHeight)
@ -496,7 +496,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode {
return
}
self.loadingMoreTransactions = true
self.transactionListDisposable.set((getWalletTransactions(address: self.address, previousId: self.currentEntries?.last?.item.previousTransactionId, tonInstance: self.tonContext.instance)
self.transactionListDisposable.set((getWalletTransactions(address: self.address, previousId: self.currentEntries?.last?.item.transactionId, tonInstance: self.tonContext.instance)
|> deliverOnMainQueue).start(next: { [weak self] transactions in
guard let strongSelf = self else {
return
@ -522,10 +522,10 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode {
}
} else {
updatedEntries = self.currentEntries ?? []
var existingIds = Set(updatedEntries.map { $0.item.previousTransactionId })
var existingIds = Set(updatedEntries.map { $0.item.transactionId })
for transaction in transactions {
if !existingIds.contains(transaction.previousTransactionId) {
existingIds.insert(transaction.previousTransactionId)
if !existingIds.contains(transaction.transactionId) {
existingIds.insert(transaction.transactionId)
updatedEntries.append(WalletInfoListEntry(index: updatedEntries.count, item: transaction))
}
}
@ -575,7 +575,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode {
}
func formatBalanceText(_ value: Int64) -> String {
var balanceText = "\(value)"
var balanceText = "\(abs(value))"
while balanceText.count < 10 {
balanceText.insert("0", at: balanceText.startIndex)
}
@ -591,5 +591,8 @@ func formatBalanceText(_ value: Int64) -> String {
break
}
}
if value < 0 {
balanceText.insert("-", at: balanceText.startIndex)
}
return balanceText
}

View file

@ -6,6 +6,7 @@ import SwiftSignalKit
import TelegramPresentationData
import ItemListUI
import TelegramCore
import TelegramStringFormatting
private let transactionIcon = UIImage(bundleImageName: "Wallet/TransactionGem")?.precomposed()
@ -14,16 +15,32 @@ class WalletInfoTransactionItem: ListViewItem {
let walletTransaction: WalletTransaction
let action: () -> Void
init(theme: PresentationTheme, walletTransaction: WalletTransaction, action: @escaping () -> Void) {
fileprivate let header: WalletInfoTransactionDateHeader?
init(theme: PresentationTheme, strings: PresentationStrings, walletTransaction: WalletTransaction, action: @escaping () -> Void) {
self.theme = theme
self.walletTransaction = walletTransaction
self.action = action
self.header = WalletInfoTransactionDateHeader(timestamp: Int32(clamping: walletTransaction.timestamp), theme: theme, strings: strings)
}
func getDateAtBottom(top: ListViewItem?, bottom: ListViewItem?) -> Bool {
var dateAtBottom = false
if let top = top as? WalletInfoTransactionItem, top.header != nil {
if top.header?.id != self.header?.id {
dateAtBottom = true
}
} else {
dateAtBottom = true
}
return dateAtBottom
}
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
async {
let node = WalletInfoTransactionItemNode()
let (layout, apply) = node.asyncLayout()(self, params, previousItem != nil, nextItem != nil)
let (layout, apply) = node.asyncLayout()(self, params, previousItem != nil, nextItem != nil, self.getDateAtBottom(top: previousItem, bottom: nextItem))
node.contentSize = layout.contentSize
node.insets = layout.insets
@ -42,7 +59,7 @@ class WalletInfoTransactionItem: ListViewItem {
let makeLayout = nodeValue.asyncLayout()
async {
let (layout, apply) = makeLayout(self, params, previousItem != nil, nextItem != nil)
let (layout, apply) = makeLayout(self, params, previousItem != nil, nextItem != nil, self.getDateAtBottom(top: previousItem, bottom: nextItem))
Queue.mainQueue().async {
completion(layout, { _ in
apply()
@ -131,7 +148,7 @@ class WalletInfoTransactionItemNode: ListViewItemNode {
self.addSubnode(self.activateArea)
}
func asyncLayout() -> (_ item: WalletInfoTransactionItem, _ params: ListViewItemLayoutParams, _ hasPrevious: Bool, _ hasNext: Bool) -> (ListViewItemNodeLayout, () -> Void) {
func asyncLayout() -> (_ item: WalletInfoTransactionItem, _ params: ListViewItemLayoutParams, _ hasPrevious: Bool, _ hasNext: Bool, _ dateAtBottom: Bool) -> (ListViewItemNodeLayout, () -> Void) {
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeDirectionLayout = TextNode.asyncLayout(self.directionNode)
let makeTextLayout = TextNode.asyncLayout(self.textNode)
@ -139,7 +156,7 @@ class WalletInfoTransactionItemNode: ListViewItemNode {
let currentItem = self.item
return { item, params, hasPrevious, hasNext in
return { item, params, hasPrevious, hasNext, dateHeaderAtBottom in
var updatedTheme: PresentationTheme?
if currentItem?.theme !== item.theme {
@ -180,7 +197,8 @@ class WalletInfoTransactionItemNode: ListViewItemNode {
text = "<unknown>"
}
}
let dateText = " "
let dateText = stringForMessageTimestamp(timestamp: Int32(clamping: item.walletTransaction.timestamp), dateTimeFormat: PresentationDateTimeFormat(timeFormat: PresentationTimeFormat.military, dateFormat: .dayFirst, dateSeparator: ".", decimalSeparator: ".", groupingSeparator: ","))
let (dateLayout, dateApply) = makeDateLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: dateText, font: dateFont, textColor: item.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - leftInset - 20.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
@ -191,7 +209,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 contentSize: CGSize
let insets: UIEdgeInsets
var insets: UIEdgeInsets
let separatorHeight = UIScreenPixel
let itemBackgroundColor: UIColor
@ -206,6 +224,11 @@ class WalletInfoTransactionItemNode: ListViewItemNode {
contentSize = CGSize(width: params.width, height: topInset + titleLayout.size.height + titleSpacing + textLayout.size.height + bottomInset)
insets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
var topHighlightInset: CGFloat = 0.0
if dateHeaderAtBottom, let header = item.header {
insets.top += header.height - 4.0
topHighlightInset = 4.0
}
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
@ -252,7 +275,7 @@ class WalletInfoTransactionItemNode: ListViewItemNode {
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: titleFrame.maxY + titleSpacing), size: textLayout.size)
strongSelf.dateNode.frame = CGRect(origin: CGPoint(x: params.width - leftInset - dateLayout.size.width, y: topInset), size: dateLayout.size)
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: layout.contentSize.height + UIScreenPixel * 2.0))
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: topHighlightInset + -UIScreenPixel), size: CGSize(width: params.width, height: layout.contentSize.height + UIScreenPixel * 2.0 - topHighlightInset))
}
})
}
@ -303,4 +326,101 @@ class WalletInfoTransactionItemNode: ListViewItemNode {
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
}
override func header() -> ListViewItemHeader? {
return self.item?.header
}
}
private let timezoneOffset: Int32 = {
let nowTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
var now: time_t = time_t(nowTimestamp)
var timeinfoNow: tm = tm()
localtime_r(&now, &timeinfoNow)
return Int32(timeinfoNow.tm_gmtoff)
}()
private final class WalletInfoTransactionDateHeader: ListViewItemHeader {
private let timestamp: Int32
private let roundedTimestamp: Int32
private let month: Int32
private let year: Int32
let id: Int64
let theme: PresentationTheme
let strings: PresentationStrings
init(timestamp: Int32, theme: PresentationTheme, strings: PresentationStrings) {
self.timestamp = timestamp
self.theme = theme
self.strings = strings
var time: time_t = time_t(timestamp + timezoneOffset)
var timeinfo: tm = tm()
localtime_r(&time, &timeinfo)
self.roundedTimestamp = timeinfo.tm_year * 100 + timeinfo.tm_mon
self.month = timeinfo.tm_mon
self.year = timeinfo.tm_year
self.id = Int64(self.roundedTimestamp)
}
let stickDirection: ListViewItemHeaderStickDirection = .top
let height: CGFloat = 40.0
func node() -> ListViewItemHeaderNode {
return WalletInfoTransactionDateHeaderNode(theme: self.theme, strings: self.strings, roundedTimestamp: self.roundedTimestamp, month: self.month, year: self.year)
}
}
private let sectionTitleFont = Font.semibold(17.0)
final class WalletInfoTransactionDateHeaderNode: ListViewItemHeaderNode {
var theme: PresentationTheme
var strings: PresentationStrings
let titleNode: ASTextNode
let backgroundNode: ASDisplayNode
init(theme: PresentationTheme, strings: PresentationStrings, roundedTimestamp: Int32, month: Int32, year: Int32) {
self.theme = theme
self.strings = strings
self.backgroundNode = ASDisplayNode()
self.backgroundNode.isLayerBacked = true
self.backgroundNode.backgroundColor = theme.list.plainBackgroundColor.withAlphaComponent(0.9)
self.titleNode = ASTextNode()
self.titleNode.isUserInteractionEnabled = false
super.init()
let dateText = stringForMonth(strings: strings, month: month, ofYear: year)
self.addSubnode(self.backgroundNode)
self.addSubnode(self.titleNode)
self.titleNode.attributedText = NSAttributedString(string: dateText, font: sectionTitleFont, textColor: theme.list.itemPrimaryTextColor)
self.titleNode.maximumNumberOfLines = 1
self.titleNode.truncationMode = .byTruncatingTail
}
func updateThemeAndStrings(theme: PresentationTheme, strings: PresentationStrings) {
self.theme = theme
if let attributedString = self.titleNode.attributedText?.mutableCopy() as? NSMutableAttributedString {
attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: theme.list.itemPrimaryTextColor, range: NSMakeRange(0, attributedString.length))
self.titleNode.attributedText = attributedString
}
self.strings = strings
self.backgroundNode.backgroundColor = theme.list.plainBackgroundColor.withAlphaComponent(0.9)
self.setNeedsLayout()
}
override func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
let titleSize = self.titleNode.measure(CGSize(width: size.width - leftInset - rightInset - 24.0, height: CGFloat.greatestFiniteMagnitude))
self.titleNode.frame = CGRect(origin: CGPoint(x: leftInset + 16.0, y: floor((size.height - titleSize.height) / 2.0)), size: titleSize)
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size)
}
}

View file

@ -258,6 +258,7 @@ td::Result<Transaction::Info> Transaction::validate() {
}
Info res;
res.blkid = blkid;
res.now = trans.now;
res.prev_trans_lt = trans.prev_trans_lt;
res.prev_trans_hash = trans.prev_trans_hash;
res.transaction = root;
@ -281,6 +282,8 @@ td::Result<TransactionList::Info> TransactionList::validate() const {
Info res;
auto current_lt = lt;
auto current_hash = hash;
res.lt = lt;
res.hash = hash;
for (auto& root : list) {
const auto& blkid = blkids[c++];
Transaction transaction;

View file

@ -60,6 +60,7 @@ struct Transaction {
struct Info {
ton::BlockIdExt blkid;
td::uint32 now;
ton::LogicalTime prev_trans_lt;
ton::Bits256 prev_trans_hash;
td::Ref<vm::Cell> transaction;
@ -74,21 +75,12 @@ struct TransactionList {
td::BufferSlice transactions_boc;
struct Info {
ton::LogicalTime lt;
ton::Bits256 hash;
std::vector<Transaction::Info> transactions;
};
td::Result<Info> validate() const;
};
struct BlockChain {
ton::BlockIdExt from;
ton::BlockIdExt to;
td::int32 mode;
td::BufferSlice proof;
using Info = std::unique_ptr<block::BlockProofChain>;
td::Result<Info> validate() const;
};
} // namespace block

View file

@ -209,7 +209,8 @@ Bignum& Bignum::import_lsb(const unsigned char* buffer, std::size_t size) {
size--;
}
if (!size) {
bn_assert(BN_zero(val));
// Use BN_set_word, because from 1.1.0 BN_zero may return void
bn_assert(BN_set_word(val, 0));
return *this;
}
unsigned char tmp_buff[1024];

View file

@ -79,7 +79,7 @@ class Bignum {
}
Bignum(const bin_string& bs) {
val = BN_new();
set_dec_str(bs.str);
set_raw_bytes(bs.str);
}
Bignum(const dec_string& ds) {
val = BN_new();

View file

@ -3,5 +3,5 @@ cmake_minimum_required(VERSION 2.8)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_library(wingetopt src/getopt.c src/getopt.h)
target_include_directories(wingetopt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_include_directories(wingetopt PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)

View file

@ -334,6 +334,10 @@ object_ptr<Object> Object::fetch(td::TlParser &p) {
return engine_validator_dhtServersStatus::fetch(p);
case engine_validator_electionBid::ID:
return engine_validator_electionBid::fetch(p);
case engine_validator_fullNodeMaster::ID:
return engine_validator_fullNodeMaster::fetch(p);
case engine_validator_fullNodeSlave::ID:
return engine_validator_fullNodeSlave::fetch(p);
case validator_groupMember::ID:
return validator_groupMember::fetch(p);
case engine_validator_jsonConfig::ID:
@ -650,6 +654,10 @@ object_ptr<Function> Function::fetch(td::TlParser &p) {
return tonNode_preparePersistentState::fetch(p);
case tonNode_prepareZeroState::ID:
return tonNode_prepareZeroState::fetch(p);
case tonNode_query::ID:
return tonNode_query::fetch(p);
case tonNode_slave_sendExtMessage::ID:
return tonNode_slave_sendExtMessage::fetch(p);
case validatorSession_downloadCandidate::ID:
return validatorSession_downloadCandidate::fetch(p);
case validatorSession_ping::ID:
@ -7635,18 +7643,22 @@ engine_validator_config::engine_validator_config()
, dht_()
, validators_()
, fullnode_()
, fullnodeslave_()
, fullnodemasters_()
, liteservers_()
, control_()
, gc_()
{}
engine_validator_config::engine_validator_config(std::int32_t out_port_, std::vector<object_ptr<engine_Addr>> &&addrs_, std::vector<object_ptr<engine_adnl>> &&adnl_, std::vector<object_ptr<engine_dht>> &&dht_, std::vector<object_ptr<engine_validator>> &&validators_, td::Bits256 const &fullnode_, std::vector<object_ptr<engine_liteServer>> &&liteservers_, std::vector<object_ptr<engine_controlInterface>> &&control_, object_ptr<engine_gc> &&gc_)
engine_validator_config::engine_validator_config(std::int32_t out_port_, std::vector<object_ptr<engine_Addr>> &&addrs_, std::vector<object_ptr<engine_adnl>> &&adnl_, std::vector<object_ptr<engine_dht>> &&dht_, std::vector<object_ptr<engine_validator>> &&validators_, td::Bits256 const &fullnode_, object_ptr<engine_validator_fullNodeSlave> &&fullnodeslave_, std::vector<object_ptr<engine_validator_fullNodeMaster>> &&fullnodemasters_, std::vector<object_ptr<engine_liteServer>> &&liteservers_, std::vector<object_ptr<engine_controlInterface>> &&control_, object_ptr<engine_gc> &&gc_)
: out_port_(out_port_)
, addrs_(std::move(addrs_))
, adnl_(std::move(adnl_))
, dht_(std::move(dht_))
, validators_(std::move(validators_))
, fullnode_(fullnode_)
, fullnodeslave_(std::move(fullnodeslave_))
, fullnodemasters_(std::move(fullnodemasters_))
, liteservers_(std::move(liteservers_))
, control_(std::move(control_))
, gc_(std::move(gc_))
@ -7666,6 +7678,8 @@ engine_validator_config::engine_validator_config(td::TlParser &p)
, dht_(TlFetchVector<TlFetchObject<engine_dht>>::parse(p))
, validators_(TlFetchVector<TlFetchObject<engine_validator>>::parse(p))
, fullnode_(TlFetchInt256::parse(p))
, fullnodeslave_(TlFetchObject<engine_validator_fullNodeSlave>::parse(p))
, fullnodemasters_(TlFetchVector<TlFetchObject<engine_validator_fullNodeMaster>>::parse(p))
, liteservers_(TlFetchVector<TlFetchObject<engine_liteServer>>::parse(p))
, control_(TlFetchVector<TlFetchObject<engine_controlInterface>>::parse(p))
, gc_(TlFetchObject<engine_gc>::parse(p))
@ -7680,6 +7694,8 @@ void engine_validator_config::store(td::TlStorerCalcLength &s) const {
TlStoreVector<TlStoreObject>::store(dht_, s);
TlStoreVector<TlStoreObject>::store(validators_, s);
TlStoreBinary::store(fullnode_, s);
TlStoreObject::store(fullnodeslave_, s);
TlStoreVector<TlStoreObject>::store(fullnodemasters_, s);
TlStoreVector<TlStoreObject>::store(liteservers_, s);
TlStoreVector<TlStoreObject>::store(control_, s);
TlStoreObject::store(gc_, s);
@ -7693,6 +7709,8 @@ void engine_validator_config::store(td::TlStorerUnsafe &s) const {
TlStoreVector<TlStoreObject>::store(dht_, s);
TlStoreVector<TlStoreObject>::store(validators_, s);
TlStoreBinary::store(fullnode_, s);
TlStoreObject::store(fullnodeslave_, s);
TlStoreVector<TlStoreObject>::store(fullnodemasters_, s);
TlStoreVector<TlStoreObject>::store(liteservers_, s);
TlStoreVector<TlStoreObject>::store(control_, s);
TlStoreObject::store(gc_, s);
@ -7707,6 +7725,8 @@ void engine_validator_config::store(td::TlStorerToString &s, const char *field_n
{ const std::vector<object_ptr<engine_dht>> &v = dht_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("dht", 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(); }
{ const std::vector<object_ptr<engine_validator>> &v = validators_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("validators", 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_field("fullnode", fullnode_);
if (fullnodeslave_ == nullptr) { s.store_field("fullnodeslave", "null"); } else { fullnodeslave_->store(s, "fullnodeslave"); }
{ const std::vector<object_ptr<engine_validator_fullNodeMaster>> &v = fullnodemasters_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("fullnodemasters", 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(); }
{ const std::vector<object_ptr<engine_liteServer>> &v = liteservers_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("liteservers", 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(); }
{ const std::vector<object_ptr<engine_controlInterface>> &v = control_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("control", 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(); }
if (gc_ == nullptr) { s.store_field("gc", "null"); } else { gc_->store(s, "gc"); }
@ -7896,6 +7916,100 @@ void engine_validator_electionBid::store(td::TlStorerToString &s, const char *fi
}
}
engine_validator_fullNodeMaster::engine_validator_fullNodeMaster()
: port_()
, adnl_()
{}
engine_validator_fullNodeMaster::engine_validator_fullNodeMaster(std::int32_t port_, td::Bits256 const &adnl_)
: port_(port_)
, adnl_(adnl_)
{}
const std::int32_t engine_validator_fullNodeMaster::ID;
object_ptr<engine_validator_fullNodeMaster> engine_validator_fullNodeMaster::fetch(td::TlParser &p) {
return make_object<engine_validator_fullNodeMaster>(p);
}
engine_validator_fullNodeMaster::engine_validator_fullNodeMaster(td::TlParser &p)
#define FAIL(error) p.set_error(error)
: port_(TlFetchInt::parse(p))
, adnl_(TlFetchInt256::parse(p))
#undef FAIL
{}
void engine_validator_fullNodeMaster::store(td::TlStorerCalcLength &s) const {
(void)sizeof(s);
TlStoreBinary::store(port_, s);
TlStoreBinary::store(adnl_, s);
}
void engine_validator_fullNodeMaster::store(td::TlStorerUnsafe &s) const {
(void)sizeof(s);
TlStoreBinary::store(port_, s);
TlStoreBinary::store(adnl_, s);
}
void engine_validator_fullNodeMaster::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "engine_validator_fullNodeMaster");
s.store_field("port", port_);
s.store_field("adnl", adnl_);
s.store_class_end();
}
}
engine_validator_fullNodeSlave::engine_validator_fullNodeSlave()
: ip_()
, port_()
, adnl_()
{}
engine_validator_fullNodeSlave::engine_validator_fullNodeSlave(std::int32_t ip_, std::int32_t port_, object_ptr<PublicKey> &&adnl_)
: ip_(ip_)
, port_(port_)
, adnl_(std::move(adnl_))
{}
const std::int32_t engine_validator_fullNodeSlave::ID;
object_ptr<engine_validator_fullNodeSlave> engine_validator_fullNodeSlave::fetch(td::TlParser &p) {
return make_object<engine_validator_fullNodeSlave>(p);
}
engine_validator_fullNodeSlave::engine_validator_fullNodeSlave(td::TlParser &p)
#define FAIL(error) p.set_error(error)
: ip_(TlFetchInt::parse(p))
, port_(TlFetchInt::parse(p))
, adnl_(TlFetchObject<PublicKey>::parse(p))
#undef FAIL
{}
void engine_validator_fullNodeSlave::store(td::TlStorerCalcLength &s) const {
(void)sizeof(s);
TlStoreBinary::store(ip_, s);
TlStoreBinary::store(port_, s);
TlStoreBoxedUnknown<TlStoreObject>::store(adnl_, s);
}
void engine_validator_fullNodeSlave::store(td::TlStorerUnsafe &s) const {
(void)sizeof(s);
TlStoreBinary::store(ip_, s);
TlStoreBinary::store(port_, s);
TlStoreBoxedUnknown<TlStoreObject>::store(adnl_, s);
}
void engine_validator_fullNodeSlave::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "engine_validator_fullNodeSlave");
s.store_field("ip", ip_);
s.store_field("port", port_);
if (adnl_ == nullptr) { s.store_field("adnl", "null"); } else { adnl_->store(s, "adnl"); }
s.store_class_end();
}
}
validator_groupMember::validator_groupMember()
: public_key_hash_()
, adnl_()
@ -15371,6 +15485,91 @@ tonNode_prepareZeroState::ReturnType tonNode_prepareZeroState::fetch_result(td::
#undef FAIL
}
tonNode_query::tonNode_query() {
}
const std::int32_t tonNode_query::ID;
object_ptr<tonNode_query> tonNode_query::fetch(td::TlParser &p) {
return make_object<tonNode_query>(p);
}
tonNode_query::tonNode_query(td::TlParser &p)
#define FAIL(error) p.set_error(error)
#undef FAIL
{
(void)p;
}
void tonNode_query::store(td::TlStorerCalcLength &s) const {
(void)sizeof(s);
s.store_binary(1777542355);
}
void tonNode_query::store(td::TlStorerUnsafe &s) const {
(void)sizeof(s);
s.store_binary(1777542355);
}
void tonNode_query::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "tonNode_query");
s.store_class_end();
}
}
tonNode_query::ReturnType tonNode_query::fetch_result(td::TlParser &p) {
#define FAIL(error) p.set_error(error); return ReturnType()
return TlFetchBoxed<TlFetchObject<Object>, 695225504>::parse(p);
#undef FAIL
}
tonNode_slave_sendExtMessage::tonNode_slave_sendExtMessage()
: message_()
{}
tonNode_slave_sendExtMessage::tonNode_slave_sendExtMessage(object_ptr<tonNode_externalMessage> &&message_)
: message_(std::move(message_))
{}
const std::int32_t tonNode_slave_sendExtMessage::ID;
object_ptr<tonNode_slave_sendExtMessage> tonNode_slave_sendExtMessage::fetch(td::TlParser &p) {
return make_object<tonNode_slave_sendExtMessage>(p);
}
tonNode_slave_sendExtMessage::tonNode_slave_sendExtMessage(td::TlParser &p)
#define FAIL(error) p.set_error(error)
: message_(TlFetchObject<tonNode_externalMessage>::parse(p))
#undef FAIL
{}
void tonNode_slave_sendExtMessage::store(td::TlStorerCalcLength &s) const {
(void)sizeof(s);
s.store_binary(2067425040);
TlStoreObject::store(message_, s);
}
void tonNode_slave_sendExtMessage::store(td::TlStorerUnsafe &s) const {
(void)sizeof(s);
s.store_binary(2067425040);
TlStoreObject::store(message_, s);
}
void tonNode_slave_sendExtMessage::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "tonNode_slave_sendExtMessage");
if (message_ == nullptr) { s.store_field("message", "null"); } else { message_->store(s, "message"); }
s.store_class_end();
}
}
tonNode_slave_sendExtMessage::ReturnType tonNode_slave_sendExtMessage::fetch_result(td::TlParser &p) {
#define FAIL(error) p.set_error(error); return ReturnType()
return TlFetchBoxed<TlFetchTrue, 1072550713>::parse(p);
#undef FAIL
}
validatorSession_downloadCandidate::validatorSession_downloadCandidate()
: round_()
, id_()

View file

@ -234,6 +234,10 @@ class engine_validator_dhtServersStatus;
class engine_validator_electionBid;
class engine_validator_fullNodeMaster;
class engine_validator_fullNodeSlave;
class validator_groupMember;
class engine_validator_jsonConfig;
@ -4210,15 +4214,17 @@ class engine_validator_config final : public Object {
std::vector<object_ptr<engine_dht>> dht_;
std::vector<object_ptr<engine_validator>> validators_;
td::Bits256 fullnode_;
object_ptr<engine_validator_fullNodeSlave> fullnodeslave_;
std::vector<object_ptr<engine_validator_fullNodeMaster>> fullnodemasters_;
std::vector<object_ptr<engine_liteServer>> liteservers_;
std::vector<object_ptr<engine_controlInterface>> control_;
object_ptr<engine_gc> gc_;
engine_validator_config();
engine_validator_config(std::int32_t out_port_, std::vector<object_ptr<engine_Addr>> &&addrs_, std::vector<object_ptr<engine_adnl>> &&adnl_, std::vector<object_ptr<engine_dht>> &&dht_, std::vector<object_ptr<engine_validator>> &&validators_, td::Bits256 const &fullnode_, std::vector<object_ptr<engine_liteServer>> &&liteservers_, std::vector<object_ptr<engine_controlInterface>> &&control_, object_ptr<engine_gc> &&gc_);
engine_validator_config(std::int32_t out_port_, std::vector<object_ptr<engine_Addr>> &&addrs_, std::vector<object_ptr<engine_adnl>> &&adnl_, std::vector<object_ptr<engine_dht>> &&dht_, std::vector<object_ptr<engine_validator>> &&validators_, td::Bits256 const &fullnode_, object_ptr<engine_validator_fullNodeSlave> &&fullnodeslave_, std::vector<object_ptr<engine_validator_fullNodeMaster>> &&fullnodemasters_, std::vector<object_ptr<engine_liteServer>> &&liteservers_, std::vector<object_ptr<engine_controlInterface>> &&control_, object_ptr<engine_gc> &&gc_);
static const std::int32_t ID = -1061804008;
static const std::int32_t ID = 17126390;
std::int32_t get_id() const final {
return ID;
}
@ -4335,6 +4341,57 @@ class engine_validator_electionBid final : public Object {
void store(td::TlStorerToString &s, const char *field_name) const final;
};
class engine_validator_fullNodeMaster final : public Object {
public:
std::int32_t port_;
td::Bits256 adnl_;
engine_validator_fullNodeMaster();
engine_validator_fullNodeMaster(std::int32_t port_, td::Bits256 const &adnl_);
static const std::int32_t ID = -2071595416;
std::int32_t get_id() const final {
return ID;
}
static object_ptr<engine_validator_fullNodeMaster> fetch(td::TlParser &p);
explicit engine_validator_fullNodeMaster(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 engine_validator_fullNodeSlave final : public Object {
public:
std::int32_t ip_;
std::int32_t port_;
object_ptr<PublicKey> adnl_;
engine_validator_fullNodeSlave();
engine_validator_fullNodeSlave(std::int32_t ip_, std::int32_t port_, object_ptr<PublicKey> &&adnl_);
static const std::int32_t ID = -2010813575;
std::int32_t get_id() const final {
return ID;
}
static object_ptr<engine_validator_fullNodeSlave> fetch(td::TlParser &p);
explicit engine_validator_fullNodeSlave(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 validator_groupMember final : public Object {
public:
td::Bits256 public_key_hash_;
@ -8459,6 +8516,59 @@ class tonNode_prepareZeroState final : public Function {
static ReturnType fetch_result(td::TlParser &p);
};
class tonNode_query final : public Function {
public:
tonNode_query();
static const std::int32_t ID = 1777542355;
std::int32_t get_id() const final {
return ID;
}
using ReturnType = object_ptr<Object>;
static object_ptr<tonNode_query> fetch(td::TlParser &p);
explicit tonNode_query(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;
static ReturnType fetch_result(td::TlParser &p);
};
class tonNode_slave_sendExtMessage final : public Function {
public:
object_ptr<tonNode_externalMessage> message_;
tonNode_slave_sendExtMessage();
explicit tonNode_slave_sendExtMessage(object_ptr<tonNode_externalMessage> &&message_);
static const std::int32_t ID = 2067425040;
std::int32_t get_id() const final {
return ID;
}
using ReturnType = bool;
static object_ptr<tonNode_slave_sendExtMessage> fetch(td::TlParser &p);
explicit tonNode_slave_sendExtMessage(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;
static ReturnType fetch_result(td::TlParser &p);
};
class validatorSession_downloadCandidate final : public Function {
public:
std::int32_t round_;

View file

@ -479,6 +479,12 @@ bool downcast_call(Object &obj, const T &func) {
case engine_validator_electionBid::ID:
func(static_cast<engine_validator_electionBid &>(obj));
return true;
case engine_validator_fullNodeMaster::ID:
func(static_cast<engine_validator_fullNodeMaster &>(obj));
return true;
case engine_validator_fullNodeSlave::ID:
func(static_cast<engine_validator_fullNodeSlave &>(obj));
return true;
case validator_groupMember::ID:
func(static_cast<validator_groupMember &>(obj));
return true;
@ -952,6 +958,12 @@ bool downcast_call(Function &obj, const T &func) {
case tonNode_prepareZeroState::ID:
func(static_cast<tonNode_prepareZeroState &>(obj));
return true;
case tonNode_query::ID:
func(static_cast<tonNode_query &>(obj));
return true;
case tonNode_slave_sendExtMessage::ID:
func(static_cast<tonNode_slave_sendExtMessage &>(obj));
return true;
case validatorSession_downloadCandidate::ID:
func(static_cast<validatorSession_downloadCandidate &>(obj));
return true;

View file

@ -625,11 +625,13 @@ Result<int32> tl_constructor_from_string(ton_api::Object *object, const std::str
{"engine.adnlProxy.config", 1848000769},
{"engine.adnlProxy.port", -117344950},
{"engine.dht.config", -197295930},
{"engine.validator.config", -1061804008},
{"engine.validator.config", 17126390},
{"engine.validator.controlQueryError", 1999018527},
{"engine.validator.dhtServerStatus", -1323440290},
{"engine.validator.dhtServersStatus", 725155112},
{"engine.validator.electionBid", 598899261},
{"engine.validator.fullNodeMaster", -2071595416},
{"engine.validator.fullNodeSlave", -2010813575},
{"validator.groupMember", -1953208860},
{"engine.validator.jsonConfig", 321753611},
{"engine.validator.keyHash", -1027168946},
@ -792,6 +794,8 @@ Result<int32> tl_constructor_from_string(ton_api::Function *object, const std::s
{"tonNode.prepareBlockProof", -2024000760},
{"tonNode.preparePersistentState", -18209122},
{"tonNode.prepareZeroState", 1104021541},
{"tonNode.query", 1777542355},
{"tonNode.slave.sendExtMessage", 2067425040},
{"validatorSession.downloadCandidate", -520274443},
{"validatorSession.ping", 1745111469}
};
@ -3094,6 +3098,18 @@ Status from_json(ton_api::engine_validator_config &to, JsonObject &from) {
TRY_STATUS(from_json(to.fullnode_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "fullnodeslave", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.fullnodeslave_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "fullnodemasters", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.fullnodemasters_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "liteservers", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
@ -3180,6 +3196,42 @@ Status from_json(ton_api::engine_validator_electionBid &to, JsonObject &from) {
}
return Status::OK();
}
Status from_json(ton_api::engine_validator_fullNodeMaster &to, JsonObject &from) {
{
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", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.adnl_, value));
}
}
return Status::OK();
}
Status from_json(ton_api::engine_validator_fullNodeSlave &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));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "adnl", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.adnl_, value));
}
}
return Status::OK();
}
Status from_json(ton_api::validator_groupMember &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "public_key_hash", JsonValue::Type::Null, true));
@ -5505,6 +5557,18 @@ Status from_json(ton_api::tonNode_prepareZeroState &to, JsonObject &from) {
}
return Status::OK();
}
Status from_json(ton_api::tonNode_query &to, JsonObject &from) {
return Status::OK();
}
Status from_json(ton_api::tonNode_slave_sendExtMessage &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "message", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.message_, value));
}
}
return Status::OK();
}
Status from_json(ton_api::validatorSession_downloadCandidate &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "round", JsonValue::Type::Null, true));
@ -6647,6 +6711,10 @@ void to_json(JsonValueScope &jv, const ton_api::engine_validator_config &object)
jo << ctie("dht", ToJson(object.dht_));
jo << ctie("validators", ToJson(object.validators_));
jo << ctie("fullnode", ToJson(object.fullnode_));
if (object.fullnodeslave_) {
jo << ctie("fullnodeslave", ToJson(object.fullnodeslave_));
}
jo << ctie("fullnodemasters", ToJson(object.fullnodemasters_));
jo << ctie("liteservers", ToJson(object.liteservers_));
jo << ctie("control", ToJson(object.control_));
if (object.gc_) {
@ -6678,6 +6746,21 @@ void to_json(JsonValueScope &jv, const ton_api::engine_validator_electionBid &ob
jo << ctie("adnl_addr", ToJson(object.adnl_addr_));
jo << ctie("to_send_payload", ToJson(JsonBytes{object.to_send_payload_}));
}
void to_json(JsonValueScope &jv, const ton_api::engine_validator_fullNodeMaster &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "engine.validator.fullNodeMaster");
jo << ctie("port", ToJson(object.port_));
jo << ctie("adnl", ToJson(object.adnl_));
}
void to_json(JsonValueScope &jv, const ton_api::engine_validator_fullNodeSlave &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "engine.validator.fullNodeSlave");
jo << ctie("ip", ToJson(object.ip_));
jo << ctie("port", ToJson(object.port_));
if (object.adnl_) {
jo << ctie("adnl", ToJson(object.adnl_));
}
}
void to_json(JsonValueScope &jv, const ton_api::validator_groupMember &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "validator.groupMember");
@ -7745,6 +7828,17 @@ void to_json(JsonValueScope &jv, const ton_api::tonNode_prepareZeroState &object
jo << ctie("block", ToJson(object.block_));
}
}
void to_json(JsonValueScope &jv, const ton_api::tonNode_query &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "tonNode.query");
}
void to_json(JsonValueScope &jv, const ton_api::tonNode_slave_sendExtMessage &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "tonNode.slave.sendExtMessage");
if (object.message_) {
jo << ctie("message", ToJson(object.message_));
}
}
void to_json(JsonValueScope &jv, const ton_api::validatorSession_downloadCandidate &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "validatorSession.downloadCandidate");

View file

@ -204,6 +204,8 @@ Status from_json(ton_api::engine_validator_controlQueryError &to, JsonObject &fr
Status from_json(ton_api::engine_validator_dhtServerStatus &to, JsonObject &from);
Status from_json(ton_api::engine_validator_dhtServersStatus &to, JsonObject &from);
Status from_json(ton_api::engine_validator_electionBid &to, JsonObject &from);
Status from_json(ton_api::engine_validator_fullNodeMaster &to, JsonObject &from);
Status from_json(ton_api::engine_validator_fullNodeSlave &to, JsonObject &from);
Status from_json(ton_api::validator_groupMember &to, JsonObject &from);
Status from_json(ton_api::engine_validator_jsonConfig &to, JsonObject &from);
Status from_json(ton_api::engine_validator_keyHash &to, JsonObject &from);
@ -357,6 +359,8 @@ Status from_json(ton_api::tonNode_prepareBlock &to, JsonObject &from);
Status from_json(ton_api::tonNode_prepareBlockProof &to, JsonObject &from);
Status from_json(ton_api::tonNode_preparePersistentState &to, JsonObject &from);
Status from_json(ton_api::tonNode_prepareZeroState &to, JsonObject &from);
Status from_json(ton_api::tonNode_query &to, JsonObject &from);
Status from_json(ton_api::tonNode_slave_sendExtMessage &to, JsonObject &from);
Status from_json(ton_api::validatorSession_downloadCandidate &to, JsonObject &from);
Status from_json(ton_api::validatorSession_ping &to, JsonObject &from);
void to_json(JsonValueScope &jv, const ton_api::Hashable &object);
@ -534,6 +538,8 @@ void to_json(JsonValueScope &jv, const ton_api::engine_validator_controlQueryErr
void to_json(JsonValueScope &jv, const ton_api::engine_validator_dhtServerStatus &object);
void to_json(JsonValueScope &jv, const ton_api::engine_validator_dhtServersStatus &object);
void to_json(JsonValueScope &jv, const ton_api::engine_validator_electionBid &object);
void to_json(JsonValueScope &jv, const ton_api::engine_validator_fullNodeMaster &object);
void to_json(JsonValueScope &jv, const ton_api::engine_validator_fullNodeSlave &object);
void to_json(JsonValueScope &jv, const ton_api::validator_groupMember &object);
void to_json(JsonValueScope &jv, const ton_api::engine_validator_jsonConfig &object);
void to_json(JsonValueScope &jv, const ton_api::engine_validator_keyHash &object);
@ -703,6 +709,8 @@ void to_json(JsonValueScope &jv, const ton_api::tonNode_prepareBlock &object);
void to_json(JsonValueScope &jv, const ton_api::tonNode_prepareBlockProof &object);
void to_json(JsonValueScope &jv, const ton_api::tonNode_preparePersistentState &object);
void to_json(JsonValueScope &jv, const ton_api::tonNode_prepareZeroState &object);
void to_json(JsonValueScope &jv, const ton_api::tonNode_query &object);
void to_json(JsonValueScope &jv, const ton_api::tonNode_slave_sendExtMessage &object);
void to_json(JsonValueScope &jv, const ton_api::validatorSession_downloadCandidate &object);
void to_json(JsonValueScope &jv, const ton_api::validatorSession_ping &object);
inline void to_json(JsonValueScope &jv, const ton::ton_api::Object &object) {

View file

@ -187,11 +187,13 @@ void ok::store(td::TlStorerToString &s, const char *field_name) const {
options::options()
: config_()
, keystore_directory_()
, use_callbacks_for_network_()
{}
options::options(std::string const &config_, std::string const &keystore_directory_)
options::options(std::string const &config_, std::string const &keystore_directory_, bool use_callbacks_for_network_)
: config_(std::move(config_))
, keystore_directory_(std::move(keystore_directory_))
, use_callbacks_for_network_(use_callbacks_for_network_)
{}
const std::int32_t options::ID;
@ -201,6 +203,28 @@ void options::store(td::TlStorerToString &s, const char *field_name) const {
s.store_class_begin(field_name, "options");
s.store_field("config", config_);
s.store_field("keystore_directory", keystore_directory_);
s.store_field("use_callbacks_for_network", use_callbacks_for_network_);
s.store_class_end();
}
}
updateSendLiteServerQuery::updateSendLiteServerQuery()
: id_()
, data_()
{}
updateSendLiteServerQuery::updateSendLiteServerQuery(std::int64_t id_, std::string const &data_)
: id_(id_)
, data_(std::move(data_))
{}
const std::int32_t updateSendLiteServerQuery::ID;
void updateSendLiteServerQuery::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "updateSendLiteServerQuery");
s.store_field("id", id_);
s.store_bytes_field("data", data_);
s.store_class_end();
}
}
@ -339,13 +363,15 @@ raw_accountState::raw_accountState()
, code_()
, data_()
, last_transaction_id_()
, sync_utime_()
{}
raw_accountState::raw_accountState(std::int64_t balance_, std::string const &code_, std::string const &data_, object_ptr<internal_transactionId> &&last_transaction_id_)
raw_accountState::raw_accountState(std::int64_t balance_, std::string const &code_, std::string const &data_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_)
: balance_(balance_)
, code_(std::move(code_))
, data_(std::move(data_))
, last_transaction_id_(std::move(last_transaction_id_))
, sync_utime_(sync_utime_)
{}
const std::int32_t raw_accountState::ID;
@ -357,6 +383,7 @@ void raw_accountState::store(td::TlStorerToString &s, const char *field_name) co
s.store_bytes_field("code", code_);
s.store_bytes_field("data", data_);
if (last_transaction_id_ == nullptr) { s.store_field("last_transaction_id", "null"); } else { last_transaction_id_->store(s, "last_transaction_id"); }
s.store_field("sync_utime", sync_utime_);
s.store_class_end();
}
}
@ -407,16 +434,18 @@ void raw_message::store(td::TlStorerToString &s, const char *field_name) const {
}
raw_transaction::raw_transaction()
: data_()
, previous_transaction_id_()
: utime_()
, data_()
, transaction_id_()
, fee_()
, in_msg_()
, out_msgs_()
{}
raw_transaction::raw_transaction(std::string const &data_, object_ptr<internal_transactionId> &&previous_transaction_id_, std::int64_t fee_, object_ptr<raw_message> &&in_msg_, std::vector<object_ptr<raw_message>> &&out_msgs_)
: data_(std::move(data_))
, previous_transaction_id_(std::move(previous_transaction_id_))
raw_transaction::raw_transaction(std::int64_t utime_, std::string const &data_, object_ptr<internal_transactionId> &&transaction_id_, std::int64_t fee_, object_ptr<raw_message> &&in_msg_, std::vector<object_ptr<raw_message>> &&out_msgs_)
: utime_(utime_)
, data_(std::move(data_))
, transaction_id_(std::move(transaction_id_))
, fee_(fee_)
, in_msg_(std::move(in_msg_))
, out_msgs_(std::move(out_msgs_))
@ -427,8 +456,9 @@ const std::int32_t raw_transaction::ID;
void raw_transaction::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "raw_transaction");
s.store_field("utime", utime_);
s.store_bytes_field("data", data_);
if (previous_transaction_id_ == nullptr) { s.store_field("previous_transaction_id", "null"); } else { previous_transaction_id_->store(s, "previous_transaction_id"); }
if (transaction_id_ == nullptr) { s.store_field("transaction_id", "null"); } else { transaction_id_->store(s, "transaction_id"); }
s.store_field("fee", fee_);
if (in_msg_ == nullptr) { s.store_field("in_msg", "null"); } else { in_msg_->store(s, "in_msg"); }
{ const std::vector<object_ptr<raw_message>> &v = out_msgs_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("out_msgs", 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(); }
@ -438,10 +468,12 @@ void raw_transaction::store(td::TlStorerToString &s, const char *field_name) con
raw_transactions::raw_transactions()
: transactions_()
, previous_transaction_id_()
{}
raw_transactions::raw_transactions(std::vector<object_ptr<raw_transaction>> &&transactions_)
raw_transactions::raw_transactions(std::vector<object_ptr<raw_transaction>> &&transactions_, object_ptr<internal_transactionId> &&previous_transaction_id_)
: transactions_(std::move(transactions_))
, previous_transaction_id_(std::move(previous_transaction_id_))
{}
const std::int32_t raw_transactions::ID;
@ -450,6 +482,7 @@ void raw_transactions::store(td::TlStorerToString &s, const char *field_name) co
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "raw_transactions");
{ const std::vector<object_ptr<raw_transaction>> &v = transactions_; const std::uint32_t multiplicity = static_cast<std::uint32_t>(v.size()); const auto vector_name = "vector[" + td::to_string(multiplicity)+ "]"; s.store_class_begin("transactions", 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(); }
if (previous_transaction_id_ == nullptr) { s.store_field("previous_transaction_id", "null"); } else { previous_transaction_id_->store(s, "previous_transaction_id"); }
s.store_class_end();
}
}
@ -458,12 +491,14 @@ testGiver_accountState::testGiver_accountState()
: balance_()
, seqno_()
, last_transaction_id_()
, sync_utime_()
{}
testGiver_accountState::testGiver_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_)
testGiver_accountState::testGiver_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_)
: balance_(balance_)
, seqno_(seqno_)
, last_transaction_id_(std::move(last_transaction_id_))
, sync_utime_(sync_utime_)
{}
const std::int32_t testGiver_accountState::ID;
@ -474,6 +509,7 @@ void testGiver_accountState::store(td::TlStorerToString &s, const char *field_na
s.store_field("balance", balance_);
s.store_field("seqno", seqno_);
if (last_transaction_id_ == nullptr) { s.store_field("last_transaction_id", "null"); } else { last_transaction_id_->store(s, "last_transaction_id"); }
s.store_field("sync_utime", sync_utime_);
s.store_class_end();
}
}
@ -482,12 +518,14 @@ testWallet_accountState::testWallet_accountState()
: balance_()
, seqno_()
, last_transaction_id_()
, sync_utime_()
{}
testWallet_accountState::testWallet_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_)
testWallet_accountState::testWallet_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_)
: balance_(balance_)
, seqno_(seqno_)
, last_transaction_id_(std::move(last_transaction_id_))
, sync_utime_(sync_utime_)
{}
const std::int32_t testWallet_accountState::ID;
@ -498,6 +536,7 @@ void testWallet_accountState::store(td::TlStorerToString &s, const char *field_n
s.store_field("balance", balance_);
s.store_field("seqno", seqno_);
if (last_transaction_id_ == nullptr) { s.store_field("last_transaction_id", "null"); } else { last_transaction_id_->store(s, "last_transaction_id"); }
s.store_field("sync_utime", sync_utime_);
s.store_class_end();
}
}
@ -522,10 +561,14 @@ void testWallet_initialAccountState::store(td::TlStorerToString &s, const char *
uninited_accountState::uninited_accountState()
: balance_()
, last_transaction_id_()
, sync_utime_()
{}
uninited_accountState::uninited_accountState(std::int64_t balance_)
uninited_accountState::uninited_accountState(std::int64_t balance_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_)
: balance_(balance_)
, last_transaction_id_(std::move(last_transaction_id_))
, sync_utime_(sync_utime_)
{}
const std::int32_t uninited_accountState::ID;
@ -534,6 +577,8 @@ void uninited_accountState::store(td::TlStorerToString &s, const char *field_nam
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "uninited_accountState");
s.store_field("balance", balance_);
if (last_transaction_id_ == nullptr) { s.store_field("last_transaction_id", "null"); } else { last_transaction_id_->store(s, "last_transaction_id"); }
s.store_field("sync_utime", sync_utime_);
s.store_class_end();
}
}
@ -826,6 +871,48 @@ void init::store(td::TlStorerToString &s, const char *field_name) const {
}
}
onLiteServerQueryError::onLiteServerQueryError()
: id_()
, error_()
{}
onLiteServerQueryError::onLiteServerQueryError(std::int64_t id_, object_ptr<error> &&error_)
: id_(id_)
, error_(std::move(error_))
{}
const std::int32_t onLiteServerQueryError::ID;
void onLiteServerQueryError::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "onLiteServerQueryError");
s.store_field("id", id_);
if (error_ == nullptr) { s.store_field("error", "null"); } else { error_->store(s, "error"); }
s.store_class_end();
}
}
onLiteServerQueryResult::onLiteServerQueryResult()
: id_()
, bytes_()
{}
onLiteServerQueryResult::onLiteServerQueryResult(std::int64_t id_, std::string const &bytes_)
: id_(id_)
, bytes_(std::move(bytes_))
{}
const std::int32_t onLiteServerQueryResult::ID;
void onLiteServerQueryResult::store(td::TlStorerToString &s, const char *field_name) const {
if (!LOG_IS_STRIPPED(ERROR)) {
s.store_class_begin(field_name, "onLiteServerQueryResult");
s.store_field("id", id_);
s.store_bytes_field("bytes", bytes_);
s.store_class_end();
}
}
options_setConfig::options_setConfig()
: config_()
{}

View file

@ -64,6 +64,8 @@ class ok;
class options;
class updateSendLiteServerQuery;
class generic_AccountState;
class generic_InitialAccountState;
@ -246,12 +248,30 @@ class options final : public Object {
public:
std::string config_;
std::string keystore_directory_;
bool use_callbacks_for_network_;
options();
options(std::string const &config_, std::string const &keystore_directory_);
options(std::string const &config_, std::string const &keystore_directory_, bool use_callbacks_for_network_);
static const std::int32_t ID = -876766471;
static const std::int32_t ID = -952483001;
std::int32_t get_id() const final {
return ID;
}
void store(td::TlStorerToString &s, const char *field_name) const final;
};
class updateSendLiteServerQuery final : public Object {
public:
std::int64_t id_;
std::string data_;
updateSendLiteServerQuery();
updateSendLiteServerQuery(std::int64_t id_, std::string const &data_);
static const std::int32_t ID = -1555130916;
std::int32_t get_id() const final {
return ID;
}
@ -386,12 +406,13 @@ class raw_accountState final : public Object {
std::string code_;
std::string data_;
object_ptr<internal_transactionId> last_transaction_id_;
std::int64_t sync_utime_;
raw_accountState();
raw_accountState(std::int64_t balance_, std::string const &code_, std::string const &data_, object_ptr<internal_transactionId> &&last_transaction_id_);
raw_accountState(std::int64_t balance_, std::string const &code_, std::string const &data_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_);
static const std::int32_t ID = -550396199;
static const std::int32_t ID = 461615898;
std::int32_t get_id() const final {
return ID;
}
@ -436,17 +457,18 @@ class raw_message final : public Object {
class raw_transaction final : public Object {
public:
std::int64_t utime_;
std::string data_;
object_ptr<internal_transactionId> previous_transaction_id_;
object_ptr<internal_transactionId> transaction_id_;
std::int64_t fee_;
object_ptr<raw_message> in_msg_;
std::vector<object_ptr<raw_message>> out_msgs_;
raw_transaction();
raw_transaction(std::string const &data_, object_ptr<internal_transactionId> &&previous_transaction_id_, std::int64_t fee_, object_ptr<raw_message> &&in_msg_, std::vector<object_ptr<raw_message>> &&out_msgs_);
raw_transaction(std::int64_t utime_, std::string const &data_, object_ptr<internal_transactionId> &&transaction_id_, std::int64_t fee_, object_ptr<raw_message> &&in_msg_, std::vector<object_ptr<raw_message>> &&out_msgs_);
static const std::int32_t ID = -463758736;
static const std::int32_t ID = -1159530820;
std::int32_t get_id() const final {
return ID;
}
@ -457,12 +479,13 @@ class raw_transaction final : public Object {
class raw_transactions final : public Object {
public:
std::vector<object_ptr<raw_transaction>> transactions_;
object_ptr<internal_transactionId> previous_transaction_id_;
raw_transactions();
explicit raw_transactions(std::vector<object_ptr<raw_transaction>> &&transactions_);
raw_transactions(std::vector<object_ptr<raw_transaction>> &&transactions_, object_ptr<internal_transactionId> &&previous_transaction_id_);
static const std::int32_t ID = -442987753;
static const std::int32_t ID = 240548986;
std::int32_t get_id() const final {
return ID;
}
@ -475,12 +498,13 @@ class testGiver_accountState final : public Object {
std::int64_t balance_;
std::int32_t seqno_;
object_ptr<internal_transactionId> last_transaction_id_;
std::int64_t sync_utime_;
testGiver_accountState();
testGiver_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_);
testGiver_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_);
static const std::int32_t ID = 2037609684;
static const std::int32_t ID = 860930426;
std::int32_t get_id() const final {
return ID;
}
@ -493,12 +517,13 @@ class testWallet_accountState final : public Object {
std::int64_t balance_;
std::int32_t seqno_;
object_ptr<internal_transactionId> last_transaction_id_;
std::int64_t sync_utime_;
testWallet_accountState();
testWallet_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_);
testWallet_accountState(std::int64_t balance_, std::int32_t seqno_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_);
static const std::int32_t ID = 105752218;
static const std::int32_t ID = 305698744;
std::int32_t get_id() const final {
return ID;
}
@ -525,12 +550,14 @@ class testWallet_initialAccountState final : public Object {
class uninited_accountState final : public Object {
public:
std::int64_t balance_;
object_ptr<internal_transactionId> last_transaction_id_;
std::int64_t sync_utime_;
uninited_accountState();
explicit uninited_accountState(std::int64_t balance_);
uninited_accountState(std::int64_t balance_, object_ptr<internal_transactionId> &&last_transaction_id_, std::int64_t sync_utime_);
static const std::int32_t ID = -1992757598;
static const std::int32_t ID = 1768941188;
std::int32_t get_id() const final {
return ID;
}
@ -801,6 +828,44 @@ class init final : public Function {
void store(td::TlStorerToString &s, const char *field_name) const final;
};
class onLiteServerQueryError final : public Function {
public:
std::int64_t id_;
object_ptr<error> error_;
onLiteServerQueryError();
onLiteServerQueryError(std::int64_t id_, object_ptr<error> &&error_);
static const std::int32_t ID = -677427533;
std::int32_t get_id() const final {
return ID;
}
using ReturnType = object_ptr<ok>;
void store(td::TlStorerToString &s, const char *field_name) const final;
};
class onLiteServerQueryResult final : public Function {
public:
std::int64_t id_;
std::string bytes_;
onLiteServerQueryResult();
onLiteServerQueryResult(std::int64_t id_, std::string const &bytes_);
static const std::int32_t ID = 2056444510;
std::int32_t get_id() const final {
return ID;
}
using ReturnType = object_ptr<ok>;
void store(td::TlStorerToString &s, const char *field_name) const final;
};
class options_setConfig final : public Function {
public:
std::string config_;

View file

@ -44,6 +44,9 @@ bool downcast_call(Object &obj, const T &func) {
case options::ID:
func(static_cast<options &>(obj));
return true;
case updateSendLiteServerQuery::ID:
func(static_cast<updateSendLiteServerQuery &>(obj));
return true;
case generic_accountStateRaw::ID:
func(static_cast<generic_accountStateRaw &>(obj));
return true;
@ -148,6 +151,12 @@ bool downcast_call(Function &obj, const T &func) {
case init::ID:
func(static_cast<init &>(obj));
return true;
case onLiteServerQueryError::ID:
func(static_cast<onLiteServerQueryError &>(obj));
return true;
case onLiteServerQueryResult::ID:
func(static_cast<onLiteServerQueryResult &>(obj));
return true;
case options_setConfig::ID:
func(static_cast<options_setConfig &>(obj));
return true;

View file

@ -49,7 +49,8 @@ Result<int32> tl_constructor_from_string(tonlib_api::Object *object, const std::
{"inputKey", 869287093},
{"key", -1978362923},
{"ok", -722616727},
{"options", -876766471},
{"options", -952483001},
{"updateSendLiteServerQuery", -1555130916},
{"generic.accountStateRaw", -1387096685},
{"generic.accountStateTestWallet", -1041955397},
{"generic.accountStateTestGiver", 1134654598},
@ -57,15 +58,15 @@ Result<int32> tl_constructor_from_string(tonlib_api::Object *object, const std::
{"generic.initialAccountStateRaw", -1178429153},
{"generic.initialAccountStateTestWallet", 710924204},
{"internal.transactionId", -989527262},
{"raw.accountState", -550396199},
{"raw.accountState", 461615898},
{"raw.initialAccountState", 777456197},
{"raw.message", -1131081640},
{"raw.transaction", -463758736},
{"raw.transactions", -442987753},
{"testGiver.accountState", 2037609684},
{"testWallet.accountState", 105752218},
{"raw.transaction", -1159530820},
{"raw.transactions", 240548986},
{"testGiver.accountState", 860930426},
{"testWallet.accountState", 305698744},
{"testWallet.initialAccountState", -1231516227},
{"uninited.accountState", -1992757598}
{"uninited.accountState", 1768941188}
};
auto it = m.find(str);
if (it == m.end()) {
@ -89,6 +90,8 @@ Result<int32> tl_constructor_from_string(tonlib_api::Function *object, const std
{"importKey", -1607900903},
{"importPemKey", 76385617},
{"init", -2014661877},
{"onLiteServerQueryError", -677427533},
{"onLiteServerQueryResult", 2056444510},
{"options.setConfig", 21225546},
{"raw.getAccountAddress", -521283849},
{"raw.getAccountState", 663706721},
@ -215,6 +218,27 @@ Status from_json(tonlib_api::options &to, JsonObject &from) {
TRY_STATUS(from_json(to.keystore_directory_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "use_callbacks_for_network", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.use_callbacks_for_network_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::updateSendLiteServerQuery &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "id", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.id_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "data", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json_bytes(to.data_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::generic_accountStateRaw &to, JsonObject &from) {
@ -311,6 +335,12 @@ Status from_json(tonlib_api::raw_accountState &to, JsonObject &from) {
TRY_STATUS(from_json(to.last_transaction_id_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "sync_utime", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.sync_utime_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::raw_initialAccountState &to, JsonObject &from) {
@ -350,6 +380,12 @@ Status from_json(tonlib_api::raw_message &to, JsonObject &from) {
return Status::OK();
}
Status from_json(tonlib_api::raw_transaction &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "utime", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.utime_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "data", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
@ -357,9 +393,9 @@ Status from_json(tonlib_api::raw_transaction &to, JsonObject &from) {
}
}
{
TRY_RESULT(value, get_json_object_field(from, "previous_transaction_id", JsonValue::Type::Null, true));
TRY_RESULT(value, get_json_object_field(from, "transaction_id", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.previous_transaction_id_, value));
TRY_STATUS(from_json(to.transaction_id_, value));
}
}
{
@ -389,6 +425,12 @@ Status from_json(tonlib_api::raw_transactions &to, JsonObject &from) {
TRY_STATUS(from_json(to.transactions_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "previous_transaction_id", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.previous_transaction_id_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::testGiver_accountState &to, JsonObject &from) {
@ -410,6 +452,12 @@ Status from_json(tonlib_api::testGiver_accountState &to, JsonObject &from) {
TRY_STATUS(from_json(to.last_transaction_id_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "sync_utime", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.sync_utime_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::testWallet_accountState &to, JsonObject &from) {
@ -431,6 +479,12 @@ Status from_json(tonlib_api::testWallet_accountState &to, JsonObject &from) {
TRY_STATUS(from_json(to.last_transaction_id_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "sync_utime", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.sync_utime_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::testWallet_initialAccountState &to, JsonObject &from) {
@ -449,6 +503,18 @@ Status from_json(tonlib_api::uninited_accountState &to, JsonObject &from) {
TRY_STATUS(from_json(to.balance_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "last_transaction_id", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.last_transaction_id_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "sync_utime", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.sync_utime_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::changeLocalPassword &to, JsonObject &from) {
@ -655,6 +721,36 @@ Status from_json(tonlib_api::init &to, JsonObject &from) {
}
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));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.id_, value));
}
}
{
TRY_RESULT(value, get_json_object_field(from, "error", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json(to.error_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::onLiteServerQueryResult &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, "bytes", JsonValue::Type::Null, true));
if (value.type() != JsonValue::Type::Null) {
TRY_STATUS(from_json_bytes(to.bytes_, value));
}
}
return Status::OK();
}
Status from_json(tonlib_api::options_setConfig &to, JsonObject &from) {
{
TRY_RESULT(value, get_json_object_field(from, "config", JsonValue::Type::Null, true));
@ -862,6 +958,13 @@ void to_json(JsonValueScope &jv, const tonlib_api::options &object) {
jo << ctie("@type", "options");
jo << ctie("config", ToJson(object.config_));
jo << ctie("keystore_directory", ToJson(object.keystore_directory_));
jo << ctie("use_callbacks_for_network", ToJson(object.use_callbacks_for_network_));
}
void to_json(JsonValueScope &jv, const tonlib_api::updateSendLiteServerQuery &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "updateSendLiteServerQuery");
jo << ctie("id", ToJson(JsonInt64{object.id_}));
jo << ctie("data", ToJson(JsonBytes{object.data_}));
}
void to_json(JsonValueScope &jv, const tonlib_api::generic_AccountState &object) {
tonlib_api::downcast_call(const_cast<tonlib_api::generic_AccountState &>(object), [&jv](const auto &object) { to_json(jv, object); });
@ -926,6 +1029,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::raw_accountState &object) {
if (object.last_transaction_id_) {
jo << ctie("last_transaction_id", ToJson(object.last_transaction_id_));
}
jo << ctie("sync_utime", ToJson(object.sync_utime_));
}
void to_json(JsonValueScope &jv, const tonlib_api::raw_initialAccountState &object) {
auto jo = jv.enter_object();
@ -943,9 +1047,10 @@ void to_json(JsonValueScope &jv, const tonlib_api::raw_message &object) {
void to_json(JsonValueScope &jv, const tonlib_api::raw_transaction &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "raw.transaction");
jo << ctie("utime", ToJson(object.utime_));
jo << ctie("data", ToJson(JsonBytes{object.data_}));
if (object.previous_transaction_id_) {
jo << ctie("previous_transaction_id", ToJson(object.previous_transaction_id_));
if (object.transaction_id_) {
jo << ctie("transaction_id", ToJson(object.transaction_id_));
}
jo << ctie("fee", ToJson(JsonInt64{object.fee_}));
if (object.in_msg_) {
@ -957,6 +1062,9 @@ void to_json(JsonValueScope &jv, const tonlib_api::raw_transactions &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "raw.transactions");
jo << ctie("transactions", ToJson(object.transactions_));
if (object.previous_transaction_id_) {
jo << ctie("previous_transaction_id", ToJson(object.previous_transaction_id_));
}
}
void to_json(JsonValueScope &jv, const tonlib_api::testGiver_accountState &object) {
auto jo = jv.enter_object();
@ -966,6 +1074,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::testGiver_accountState &objec
if (object.last_transaction_id_) {
jo << ctie("last_transaction_id", ToJson(object.last_transaction_id_));
}
jo << ctie("sync_utime", ToJson(object.sync_utime_));
}
void to_json(JsonValueScope &jv, const tonlib_api::testWallet_accountState &object) {
auto jo = jv.enter_object();
@ -975,6 +1084,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::testWallet_accountState &obje
if (object.last_transaction_id_) {
jo << ctie("last_transaction_id", ToJson(object.last_transaction_id_));
}
jo << ctie("sync_utime", ToJson(object.sync_utime_));
}
void to_json(JsonValueScope &jv, const tonlib_api::testWallet_initialAccountState &object) {
auto jo = jv.enter_object();
@ -985,6 +1095,10 @@ void to_json(JsonValueScope &jv, const tonlib_api::uninited_accountState &object
auto jo = jv.enter_object();
jo << ctie("@type", "uninited.accountState");
jo << ctie("balance", ToJson(JsonInt64{object.balance_}));
if (object.last_transaction_id_) {
jo << ctie("last_transaction_id", ToJson(object.last_transaction_id_));
}
jo << ctie("sync_utime", ToJson(object.sync_utime_));
}
void to_json(JsonValueScope &jv, const tonlib_api::changeLocalPassword &object) {
auto jo = jv.enter_object();
@ -1093,6 +1207,20 @@ void to_json(JsonValueScope &jv, const tonlib_api::init &object) {
jo << ctie("options", ToJson(object.options_));
}
}
void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryError &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "onLiteServerQueryError");
jo << ctie("id", ToJson(JsonInt64{object.id_}));
if (object.error_) {
jo << ctie("error", ToJson(object.error_));
}
}
void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryResult &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "onLiteServerQueryResult");
jo << ctie("id", ToJson(JsonInt64{object.id_}));
jo << ctie("bytes", ToJson(JsonBytes{object.bytes_}));
}
void to_json(JsonValueScope &jv, const tonlib_api::options_setConfig &object) {
auto jo = jv.enter_object();
jo << ctie("@type", "options.setConfig");

View file

@ -25,6 +25,7 @@ Status from_json(tonlib_api::inputKey &to, JsonObject &from);
Status from_json(tonlib_api::key &to, JsonObject &from);
Status from_json(tonlib_api::ok &to, JsonObject &from);
Status from_json(tonlib_api::options &to, JsonObject &from);
Status from_json(tonlib_api::updateSendLiteServerQuery &to, JsonObject &from);
Status from_json(tonlib_api::generic_accountStateRaw &to, JsonObject &from);
Status from_json(tonlib_api::generic_accountStateTestWallet &to, JsonObject &from);
Status from_json(tonlib_api::generic_accountStateTestGiver &to, JsonObject &from);
@ -55,6 +56,8 @@ Status from_json(tonlib_api::importEncryptedKey &to, JsonObject &from);
Status from_json(tonlib_api::importKey &to, JsonObject &from);
Status from_json(tonlib_api::importPemKey &to, JsonObject &from);
Status from_json(tonlib_api::init &to, JsonObject &from);
Status from_json(tonlib_api::onLiteServerQueryError &to, JsonObject &from);
Status from_json(tonlib_api::onLiteServerQueryResult &to, JsonObject &from);
Status from_json(tonlib_api::options_setConfig &to, JsonObject &from);
Status from_json(tonlib_api::raw_getAccountAddress &to, JsonObject &from);
Status from_json(tonlib_api::raw_getAccountState &to, JsonObject &from);
@ -78,6 +81,7 @@ void to_json(JsonValueScope &jv, const tonlib_api::inputKey &object);
void to_json(JsonValueScope &jv, const tonlib_api::key &object);
void to_json(JsonValueScope &jv, const tonlib_api::ok &object);
void to_json(JsonValueScope &jv, const tonlib_api::options &object);
void to_json(JsonValueScope &jv, const tonlib_api::updateSendLiteServerQuery &object);
void to_json(JsonValueScope &jv, const tonlib_api::generic_AccountState &object);
void to_json(JsonValueScope &jv, const tonlib_api::generic_accountStateRaw &object);
void to_json(JsonValueScope &jv, const tonlib_api::generic_accountStateTestWallet &object);
@ -110,6 +114,8 @@ void to_json(JsonValueScope &jv, const tonlib_api::importEncryptedKey &object);
void to_json(JsonValueScope &jv, const tonlib_api::importKey &object);
void to_json(JsonValueScope &jv, const tonlib_api::importPemKey &object);
void to_json(JsonValueScope &jv, const tonlib_api::init &object);
void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryError &object);
void to_json(JsonValueScope &jv, const tonlib_api::onLiteServerQueryResult &object);
void to_json(JsonValueScope &jv, const tonlib_api::options_setConfig &object);
void to_json(JsonValueScope &jv, const tonlib_api::raw_getAccountAddress &object);
void to_json(JsonValueScope &jv, const tonlib_api::raw_getAccountState &object);

View file

@ -367,6 +367,10 @@ tonNode.downloadZeroState block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadBlockProof block:tonNode.blockIdExt = tonNode.Data;
tonNode.downloadBlockProofLink block:tonNode.blockIdExt = tonNode.Data;
tonNode.slave.sendExtMessage message:tonNode.externalMessage = True;
tonNode.query = Object;
---types---
// bit 0 - started
@ -482,9 +486,12 @@ engine.controlInterface id:int256 port:int allowed:(vector engine.controlProcess
engine.gc ids:(vector int256) = engine.Gc;
engine.dht.config dht:(vector engine.dht) gc:engine.gc = engine.dht.Config;
engine.validator.fullNodeMaster port:int adnl:int256 = engine.validator.FullNodeMaster;
engine.validator.fullNodeSlave ip:int port:int adnl:PublicKey = engine.validator.FullNodeSlave;
engine.validator.config out_port:int addrs:(vector engine.Addr) adnl:(vector engine.adnl)
dht:(vector engine.dht)
validators:(vector engine.validator) fullnode:int256
validators:(vector engine.validator) fullnode:int256 fullnodeslave:engine.validator.fullNodeSlave
fullnodemasters:(vector engine.validator.fullNodeMaster)
liteservers:(vector engine.liteServer) control:(vector engine.controlInterface)
gc:engine.gc = engine.validator.Config;

View file

@ -16,7 +16,7 @@ vector {t:Type} # [ t ] = Vector t;
error code:int32 message:string = Error;
ok = Ok;
options config:string keystore_directory:string = Options;
options config:string keystore_directory:string use_callbacks_for_network:Bool = Options;
key public_key:string secret:secureBytes = Key;
inputKey key:key local_password:secureBytes = InputKey;
@ -31,17 +31,17 @@ accountAddress account_address:string = AccountAddress;
internal.transactionId lt:int64 hash:bytes = internal.TransactionId;
raw.initialAccountState code:bytes data:bytes = raw.InitialAccountState;
raw.accountState balance:int64 code:bytes data:bytes last_transaction_id:internal.transactionId = raw.AccountState;
raw.accountState balance:int64 code:bytes data:bytes last_transaction_id:internal.transactionId sync_utime:int53 = raw.AccountState;
raw.message source:string destination:string value:int64 = raw.Message;
raw.transaction data:bytes previous_transaction_id:internal.transactionId fee:int64 in_msg:raw.message out_msgs:vector<raw.message> = raw.Transaction;
raw.transactions transactions:vector<raw.Transaction> = raw.Transactions;
raw.transaction utime:int53 data:bytes transaction_id:internal.transactionId fee:int64 in_msg:raw.message out_msgs:vector<raw.message> = raw.Transaction;
raw.transactions transactions:vector<raw.Transaction> previous_transaction_id:internal.transactionId = raw.Transactions;
testWallet.initialAccountState public_key:string = testWallet.InitialAccountState;
testWallet.accountState balance:int64 seqno:int32 last_transaction_id:internal.transactionId = testWallet.AccountState;
testWallet.accountState balance:int64 seqno:int32 last_transaction_id:internal.transactionId sync_utime:int53 = testWallet.AccountState;
testGiver.accountState balance:int64 seqno:int32 last_transaction_id:internal.transactionId = testGiver.AccountState;
testGiver.accountState balance:int64 seqno:int32 last_transaction_id:internal.transactionId sync_utime:int53= testGiver.AccountState;
uninited.accountState balance:int64 = uninited.AccountState;
uninited.accountState balance:int64 last_transaction_id:internal.transactionId sync_utime:int53 = uninited.AccountState;
generic.initialAccountStateRaw initital_account_state:raw.initialAccountState = generic.InitialAccountState;
generic.initialAccountStateTestWallet initital_account_state:testWallet.initialAccountState = generic.InitialAccountState;
@ -51,6 +51,8 @@ generic.accountStateTestWallet account_state:testWallet.accountState = generic.A
generic.accountStateTestGiver account_state:testGiver.accountState = generic.AccountState;
generic.accountStateUninited account_state:uninited.accountState = generic.AccountState;
updateSendLiteServerQuery id:int64 data:bytes = Update;
---functions---
init options:options = Ok;
@ -89,5 +91,7 @@ testGiver.sendGrams destination:accountAddress seqno:int32 amount:int64 = Ok;
generic.getAccountState account_address:accountAddress = generic.AccountState;
generic.sendGrams private_key:inputKey source:accountAddress destination:accountAddress amount:int64 = Ok;
runTests dir:string = Ok;
onLiteServerQueryResult id:int64 bytes:bytes = Ok;
onLiteServerQueryError id:int64 error:error = Ok;
runTests dir:string = Ok;

View file

@ -9,6 +9,7 @@ set(TONLIB_SOURCE
tonlib/Config.cpp
tonlib/ExtClient.cpp
tonlib/ExtClientLazy.cpp
tonlib/ExtClientOutbound.cpp
tonlib/GenericAccount.cpp
tonlib/KeyStorage.cpp
tonlib/LastBlock.cpp
@ -21,6 +22,7 @@ set(TONLIB_SOURCE
tonlib/Config.h
tonlib/ExtClient.h
tonlib/ExtClientLazy.h
tonlib/ExtClientOutbound.h
tonlib/GenericAccount.h
tonlib/KeyStorage.h
tonlib/LastBlock.h

Binary file not shown.

View file

@ -172,16 +172,17 @@ TEST(Tonlib, InitClose) {
{
Client client;
sync_send(client, make_object<tonlib_api::close>()).ensure();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "."))).ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", ".", false))).ensure_error();
}
{
Client client;
sync_send(client, make_object<tonlib_api::init>(nullptr)).ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("fdajkfldsjkafld", ".")))
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("fdajkfldsjkafld", ".", false)))
.ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "fdhskfds"))).ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "."))).ensure();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "."))).ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "fdhskfds", false)))
.ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", ".", false))).ensure();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", ".", false))).ensure_error();
td::Slice bad_config = R"abc(
{
@ -194,7 +195,7 @@ TEST(Tonlib, InitClose) {
sync_send(client, make_object<tonlib_api::testGiver_getAccountState>()).ensure_error();
sync_send(client, make_object<tonlib_api::close>()).ensure();
sync_send(client, make_object<tonlib_api::close>()).ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "."))).ensure_error();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", ".", false))).ensure_error();
}
}
@ -289,7 +290,7 @@ TEST(Tonlib, KeysApi) {
Client client;
// init
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", "."))).ensure();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>("", ".", false))).ensure();
auto local_password = td::SecureString("local password");
auto mnemonic_password = td::SecureString("mnemonic password");
{

View file

@ -170,12 +170,12 @@ void dump_transaction_history(Client& client, std::string address) {
make_object<tonlib_api::accountAddress>(address), std::move(tid)))
.move_as_ok();
CHECK(got_transactions->transactions_.size() > 0);
CHECK(got_transactions->transactions_[0]->previous_transaction_id_->lt_ < lt);
CHECK(got_transactions->previous_transaction_id_->lt_ < lt);
for (auto& txn : got_transactions->transactions_) {
LOG(ERROR) << to_string(txn);
cnt++;
}
tid = std::move(got_transactions->transactions_.back()->previous_transaction_id_);
tid = std::move(got_transactions->previous_transaction_id_);
}
LOG(ERROR) << cnt;
}
@ -196,7 +196,8 @@ int main(int argc, char* argv[]) {
Client client;
{
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>(global_config_str, "."))).ensure();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>(global_config_str, ".", false)))
.ensure();
}
//dump_transaction_history(client, get_test_giver_address(client));
auto wallet_a = create_wallet(client);
@ -208,7 +209,8 @@ int main(int argc, char* argv[]) {
return 0;
{
// init
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>(global_config_str, "."))).ensure();
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>(global_config_str, ".", false)))
.ensure();
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(
td::SecureString("local"), td::SecureString("mnemonic"), td::SecureString()))

View file

@ -0,0 +1,11 @@
#pragma once
#include "tonlib/LastBlock.h"
namespace tonlib {
class BlockchainInfoStorage {
td::Status set_directory(std::string directory);
td::Result<LastBlock::State> get_state(ZeroStateIdExt);
void save_state(LastBlock::State state);
};
} // namespace tonlib

View file

@ -21,10 +21,10 @@
#include "tonlib/LastBlock.h"
namespace tonlib {
void ExtClient::with_last_block(td::Promise<ton::BlockIdExt> promise) {
void ExtClient::with_last_block(td::Promise<LastBlockInfo> promise) {
auto query_id = last_block_queries_.create(std::move(promise));
td::Promise<ton::BlockIdExt> P = [query_id, self = this,
actor_id = td::actor::actor_id()](td::Result<ton::BlockIdExt> result) {
td::Promise<LastBlockInfo> P = [query_id, self = this,
actor_id = td::actor::actor_id()](td::Result<LastBlockInfo> result) {
send_lambda(actor_id, [self, query_id, result = std::move(result)]() mutable {
self->last_block_queries_.extract(query_id).set_result(std::move(result));
});

View file

@ -29,6 +29,7 @@
namespace tonlib {
class LastBlock;
struct LastBlockInfo;
struct ExtClientRef {
td::actor::ActorId<ton::adnl::AdnlExtClient> andl_ext_client_;
td::actor::ActorId<LastBlock> last_block_actor_;
@ -49,7 +50,7 @@ class ExtClient {
return client_;
}
void with_last_block(td::Promise<ton::BlockIdExt> promise);
void with_last_block(td::Promise<LastBlockInfo> promise);
template <class QueryT>
void send_query(QueryT query, td::Promise<typename QueryT::ReturnType> promise) {
@ -74,7 +75,7 @@ class ExtClient {
private:
ExtClientRef client_;
td::Container<td::Promise<td::BufferSlice>> queries_;
td::Container<td::Promise<ton::BlockIdExt>> last_block_queries_;
td::Container<td::Promise<LastBlockInfo>> last_block_queries_;
void send_raw_query(td::BufferSlice query, td::Promise<td::BufferSlice> promise);
};

View file

@ -0,0 +1,66 @@
/*
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 <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#include "ExtClientOutbound.h"
#include <map>
namespace tonlib {
class ExtClientOutboundImp : public ExtClientOutbound {
public:
ExtClientOutboundImp(td::unique_ptr<ExtClientOutbound::Callback> callback) : callback_(std::move(callback)) {
}
void check_ready(td::Promise<td::Unit> promise) override {
promise.set_error(td::Status::Error("Not supported"));
}
void send_query(std::string name, td::BufferSlice data, td::Timestamp timeout,
td::Promise<td::BufferSlice> promise) override {
auto query_id = next_query_id_++;
queries_[query_id] = std::move(promise);
callback_->request(query_id, data.as_slice().str());
}
void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) override {
auto it = queries_.find(id);
if (it == queries_.end()) {
promise.set_error(td::Status::Error(400, "Unknown query id"));
}
it->second.set_result(std::move(r_data));
queries_.erase(it);
promise.set_value(td::Unit());
}
private:
td::unique_ptr<ExtClientOutbound::Callback> callback_;
td::int64 next_query_id_{1};
std::map<td::int64, td::Promise<td::BufferSlice>> queries_;
void tear_down() override {
for (auto &it : queries_) {
it.second.set_error(td::Status::Error(400, "Query cancelled"));
}
queries_.clear();
}
};
td::actor::ActorOwn<ExtClientOutbound> ExtClientOutbound::create(td::unique_ptr<Callback> callback) {
return td::actor::create_actor<ExtClientOutboundImp>("ExtClientOutbound", std::move(callback));
}
} // namespace tonlib

View file

@ -0,0 +1,37 @@
/*
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 <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#pragma once
#include "td/actor/actor.h"
#include "adnl/adnl-ext-client.h"
namespace tonlib {
class ExtClientOutbound : public ton::adnl::AdnlExtClient {
public:
class Callback {
public:
virtual ~Callback() {
}
virtual void request(td::int64 id, std::string data) = 0;
};
virtual void on_query_result(td::int64 id, td::Result<td::BufferSlice> r_data, td::Promise<td::Unit> promise) = 0;
static td::actor::ActorOwn<ExtClientOutbound> create(td::unique_ptr<Callback> callback);
};
} // namespace tonlib

View file

@ -23,15 +23,12 @@
#include "lite-client/lite-client-common.h"
namespace tonlib {
LastBlock::LastBlock(ExtClientRef client, ton::ZeroStateIdExt zero_state_id, ton::BlockIdExt last_block_id,
td::actor::ActorShared<> parent) {
zero_state_id_ = std::move(zero_state_id);
mc_last_block_id_ = std::move(last_block_id);
LastBlock::LastBlock(ExtClientRef client, State state, td::unique_ptr<Callback> callback)
: state_(std::move(state)), callback_(std::move(callback)) {
client_.set_client(client);
parent_ = std::move(parent);
}
void LastBlock::get_last_block(td::Promise<ton::BlockIdExt> promise) {
void LastBlock::get_last_block(td::Promise<LastBlockInfo> promise) {
if (promises_.empty()) {
do_get_last_block();
}
@ -39,13 +36,16 @@ void LastBlock::get_last_block(td::Promise<ton::BlockIdExt> promise) {
}
void LastBlock::do_get_last_block() {
client_.send_query(ton::lite_api::liteServer_getMasterchainInfo(),
[this](auto r_info) { this->on_masterchain_info(std::move(r_info)); });
return;
//client_.send_query(ton::lite_api::liteServer_getMasterchainInfo(),
//[this](auto r_info) { this->on_masterchain_info(std::move(r_info)); });
//return;
//liteServer.getBlockProof mode:# known_block:tonNode.blockIdExt target_block:mode.0?tonNode.blockIdExt = liteServer.PartialBlockProof;
client_.send_query(
ton::lite_api::liteServer_getBlockProof(0, create_tl_lite_block_id(mc_last_block_id_), nullptr),
[this, from = mc_last_block_id_](auto r_block_proof) { this->on_block_proof(from, std::move(r_block_proof)); });
ton::lite_api::liteServer_getBlockProof(0, create_tl_lite_block_id(state_.last_key_block_id), nullptr),
[this, from = state_.last_key_block_id](auto r_block_proof) {
this->on_block_proof(from, std::move(r_block_proof));
});
}
td::Result<bool> LastBlock::process_block_proof(
@ -60,6 +60,12 @@ td::Result<bool> LastBlock::process_block_proof(
}
TRY_STATUS(chain->validate());
update_mc_last_block(chain->to);
if (chain->has_key_block) {
update_mc_last_key_block(chain->key_blkid);
}
if (chain->has_utime) {
update_utime(chain->last_utime);
}
return chain->complete;
}
@ -68,14 +74,16 @@ void LastBlock::on_block_proof(
td::Result<ton::ton_api::object_ptr<ton::lite_api::liteServer_partialBlockProof>> r_block_proof) {
auto r_is_ready = process_block_proof(from, std::move(r_block_proof));
if (r_is_ready.is_error()) {
LOG(WARNING) << "Failed liteServer_getBlockProof " << r_block_proof.error();
LOG(WARNING) << "Failed liteServer_getBlockProof " << r_is_ready.error();
return;
}
auto is_ready = r_is_ready.move_as_ok();
if (is_ready) {
for (auto& promise : promises_) {
auto copy = mc_last_block_id_;
promise.set_value(std::move(copy));
LastBlockInfo res;
res.id = state_.last_block_id;
res.utime = state_.utime;
promise.set_value(std::move(res));
}
promises_.clear();
} else {
@ -93,8 +101,10 @@ void LastBlock::on_masterchain_info(
LOG(WARNING) << "Failed liteServer_getMasterchainInfo " << r_info.error();
}
for (auto& promise : promises_) {
auto copy = mc_last_block_id_;
promise.set_value(std::move(copy));
LastBlockInfo res;
res.id = state_.last_block_id;
res.utime = state_.utime;
promise.set_value(std::move(res));
}
promises_.clear();
}
@ -105,17 +115,17 @@ void LastBlock::update_zero_state(ton::ZeroStateIdExt zero_state_id) {
return;
}
if (!zero_state_id_.is_valid()) {
if (!state_.zero_state_id.is_valid()) {
LOG(INFO) << "Init zerostate: " << zero_state_id.to_str();
zero_state_id_ = std::move(zero_state_id);
state_.zero_state_id = std::move(zero_state_id);
return;
}
if (zero_state_id_ == zero_state_id_) {
if (state_.zero_state_id == state_.zero_state_id) {
return;
}
LOG(FATAL) << "Masterchain zerostate mismatch: expected: " << zero_state_id_.to_str() << ", found "
LOG(FATAL) << "Masterchain zerostate mismatch: expected: " << state_.zero_state_id.to_str() << ", found "
<< zero_state_id.to_str();
// TODO: all other updates will be inconsitent.
// One will have to restart ton client
@ -126,9 +136,25 @@ void LastBlock::update_mc_last_block(ton::BlockIdExt mc_block_id) {
LOG(ERROR) << "Ignore invalid masterchain block";
return;
}
if (!mc_last_block_id_.is_valid() || mc_last_block_id_.id.seqno < mc_block_id.id.seqno) {
mc_last_block_id_ = mc_block_id;
LOG(INFO) << "Update masterchain block id: " << mc_last_block_id_.to_str();
if (!state_.last_block_id.is_valid() || state_.last_block_id.id.seqno < mc_block_id.id.seqno) {
state_.last_block_id = mc_block_id;
LOG(INFO) << "Update masterchain block id: " << state_.last_block_id.to_str();
}
}
void LastBlock::update_mc_last_key_block(ton::BlockIdExt mc_key_block_id) {
if (!mc_key_block_id.is_valid()) {
LOG(ERROR) << "Ignore invalid masterchain block";
return;
}
if (!state_.last_key_block_id.is_valid() || state_.last_key_block_id.id.seqno < mc_key_block_id.id.seqno) {
state_.last_key_block_id = mc_key_block_id;
LOG(INFO) << "Update masterchain key block id: " << state_.last_key_block_id.to_str();
}
}
void LastBlock::update_utime(td::int64 utime) {
if (state_.utime < utime) {
state_.utime = utime;
}
}
} // namespace tonlib

View file

@ -22,21 +22,35 @@
#include "tonlib/ExtClient.h"
namespace tonlib {
struct LastBlockInfo {
ton::BlockIdExt id;
td::int64 utime{0};
};
class LastBlock : public td::actor::Actor {
public:
explicit LastBlock(ExtClientRef client, ton::ZeroStateIdExt zero_state_id, ton::BlockIdExt last_block_id,
td::actor::ActorShared<> parent);
struct State {
ton::ZeroStateIdExt zero_state_id;
ton::BlockIdExt last_key_block_id;
ton::BlockIdExt last_block_id;
td::int64 utime{0};
};
void get_last_block(td::Promise<ton::BlockIdExt> promise);
class Callback {
public:
virtual ~Callback() {
}
virtual void on_state_changes(State state) = 0;
};
explicit LastBlock(ExtClientRef client, State state, td::unique_ptr<Callback> callback);
void get_last_block(td::Promise<LastBlockInfo> promise);
private:
ExtClient client_;
ton::ZeroStateIdExt zero_state_id_;
ton::BlockIdExt mc_last_block_id_;
State state_;
td::unique_ptr<Callback> callback_;
std::vector<td::Promise<ton::BlockIdExt>> promises_;
td::actor::ActorShared<> parent_;
std::vector<td::Promise<LastBlockInfo>> promises_;
void do_get_last_block();
void on_masterchain_info(td::Result<ton::ton_api::object_ptr<ton::lite_api::liteServer_masterchainInfo>> r_info);
@ -49,5 +63,7 @@ class LastBlock : public td::actor::Actor {
void update_zero_state(ton::ZeroStateIdExt zero_state_id);
void update_mc_last_block(ton::BlockIdExt mc_block_id);
void update_mc_last_key_block(ton::BlockIdExt mc_key_block_id);
void update_utime(td::int64 utime);
};
} // namespace tonlib

View file

@ -19,6 +19,7 @@
#include "TonlibClient.h"
#include "tonlib/ExtClientLazy.h"
#include "tonlib/ExtClientOutbound.h"
#include "tonlib/GenericAccount.h"
#include "tonlib/LastBlock.h"
#include "tonlib/TestWallet.h"
@ -73,6 +74,7 @@ struct RawAccountState {
td::Ref<vm::CellSlice> code;
td::Ref<vm::CellSlice> data;
block::AccountState::Info info;
td::int64 sync_utime = 0;
};
td::Result<td::int64> to_balance_or_throw(td::Ref<vm::CellSlice> balance_ref) {
@ -169,7 +171,7 @@ class GetRawAccountState : public td::actor::Actor {
block::StdAddress address_;
td::Promise<RawAccountState> promise_;
ExtClient client_;
ton::BlockIdExt last_block_;
LastBlockInfo last_block_;
void with_account_state(td::Result<ton::tl_object_ptr<ton::lite_api::liteServer_accountState>> r_account_state) {
promise_.set_result(TRY_VM(do_with_account_state(std::move(r_account_state))));
@ -180,10 +182,11 @@ class GetRawAccountState : public td::actor::Actor {
td::Result<ton::tl_object_ptr<ton::lite_api::liteServer_accountState>> r_account_state) {
TRY_RESULT(raw_account_state, std::move(r_account_state));
auto account_state = create_account_state(std::move(raw_account_state));
TRY_RESULT(info, account_state.validate(last_block_, address_));
TRY_RESULT(info, account_state.validate(last_block_.id, address_));
auto serialized_state = account_state.state.clone();
RawAccountState res;
res.info = std::move(info);
res.sync_utime = last_block_.utime;
auto cell = res.info.root;
if (cell.is_null()) {
return res;
@ -222,14 +225,14 @@ class GetRawAccountState : public td::actor::Actor {
}
void start_up() override {
client_.with_last_block([self = this](td::Result<ton::BlockIdExt> r_last_block) {
client_.with_last_block([self = this](td::Result<LastBlockInfo> r_last_block) {
if (r_last_block.is_error()) {
return self->check(r_last_block.move_as_error());
}
self->last_block_ = r_last_block.move_as_ok();
self->client_.send_query(
ton::lite_api::liteServer_getAccountState(ton::create_tl_lite_block_id(self->last_block_),
ton::lite_api::liteServer_getAccountState(ton::create_tl_lite_block_id(self->last_block_.id),
ton::create_tl_object<ton::lite_api::liteServer_accountId>(
self->address_.workchain, self->address_.addr)),
[self](auto r_state) { self->with_account_state(std::move(r_state)); });
@ -263,28 +266,68 @@ ExtClientRef TonlibClient::get_client_ref() {
return ref;
}
void TonlibClient::proxy_request(td::int64 query_id, std::string data) {
callback_->on_result(0, tonlib_api::make_object<tonlib_api::updateSendLiteServerQuery>(query_id, data));
}
void TonlibClient::init_ext_client() {
auto lite_clients_size = config_.lite_clients.size();
CHECK(lite_clients_size != 0);
auto lite_client_id = td::Random::fast(0, td::narrow_cast<int>(lite_clients_size) - 1);
auto& lite_client = config_.lite_clients[lite_client_id];
class Callback : public ExtClientLazy::Callback {
if (use_callbacks_for_network_) {
class Callback : public ExtClientOutbound::Callback {
public:
explicit Callback(td::actor::ActorShared<TonlibClient> parent) : parent_(std::move(parent)) {
}
void request(td::int64 id, std::string data) override {
send_closure(parent_, &TonlibClient::proxy_request, id, std::move(data));
}
private:
td::actor::ActorShared<TonlibClient> parent_;
};
ref_cnt_++;
auto client = ExtClientOutbound::create(td::make_unique<Callback>(td::actor::actor_shared(this)));
ext_client_outbound_ = client.get();
raw_client_ = std::move(client);
} else {
auto lite_clients_size = config_.lite_clients.size();
CHECK(lite_clients_size != 0);
auto lite_client_id = td::Random::fast(0, td::narrow_cast<int>(lite_clients_size) - 1);
auto& lite_client = config_.lite_clients[lite_client_id];
class Callback : public ExtClientLazy::Callback {
public:
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
}
private:
td::actor::ActorShared<> parent_;
};
ref_cnt_++;
raw_client_ = ExtClientLazy::create(lite_client.adnl_id, lite_client.address,
td::make_unique<Callback>(td::actor::actor_shared()));
}
}
void TonlibClient::init_last_block() {
ref_cnt_++;
class Callback : public LastBlock::Callback {
public:
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
Callback(td::actor::ActorShared<TonlibClient> client) : client_(std::move(client)) {
}
void on_state_changes(LastBlock::State state) override {
//TODO
}
private:
td::actor::ActorShared<> parent_;
td::actor::ActorShared<TonlibClient> client_;
};
ref_cnt_++;
raw_client_ = ExtClientLazy::create(lite_client.adnl_id, lite_client.address,
td::make_unique<Callback>(td::actor::actor_shared()));
ref_cnt_++;
raw_last_block_ = td::actor::create_actor<LastBlock>(
"LastBlock", get_client_ref(),
ton::ZeroStateIdExt(config_.zero_state_id.id.workchain, config_.zero_state_id.root_hash,
config_.zero_state_id.file_hash),
config_.zero_state_id, td::actor::actor_shared());
LastBlock::State state;
//state.zero_state_id = ton::ZeroStateIdExt(config_.zero_state_id.id.workchain, config_.zero_state_id.root_hash,
//config_.zero_state_id.file_hash),
state.last_block_id = config_.zero_state_id;
state.last_key_block_id = config_.zero_state_id;
raw_last_block_ = td::actor::create_actor<LastBlock>("LastBlock", get_client_ref(), std::move(state),
td::make_unique<Callback>(td::actor::actor_shared(this)));
client_.set_client(get_client_ref());
}
@ -426,6 +469,7 @@ td::Status TonlibClient::do_request(const tonlib_api::init& request,
return td::Status::Error(400, "Field options must not be empty");
}
TRY_STATUS(key_storage_.set_directory(request.options_->keystore_directory_));
use_callbacks_for_network_ = request.options_->use_callbacks_for_network_;
if (!request.options_->config_.empty()) {
TRY_STATUS(set_config(std::move(request.options_->config_)));
}
@ -444,6 +488,7 @@ td::Status TonlibClient::set_config(std::string config) {
}
config_ = std::move(new_config);
init_ext_client();
init_last_block();
return td::Status::OK();
}
@ -454,6 +499,7 @@ td::Status TonlibClient::do_request(const tonlib_api::close& request,
promise.set_value(tonlib_api::make_object<tonlib_api::ok>());
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::options_setConfig& request,
td::Promise<object_ptr<tonlib_api::ok>>&& promise) {
TRY_STATUS(set_config(request.config_));
@ -461,6 +507,10 @@ td::Status TonlibClient::do_request(const tonlib_api::options_setConfig& request
return td::Status::OK();
}
tonlib_api::object_ptr<tonlib_api::internal_transactionId> empty_transaction_id() {
return tonlib_api::make_object<tonlib_api::internal_transactionId>(0, std::string(32, 0));
}
tonlib_api::object_ptr<tonlib_api::internal_transactionId> to_transaction_id(const block::AccountState::Info& info) {
return tonlib_api::make_object<tonlib_api::internal_transactionId>(info.last_trans_lt,
info.last_trans_hash.as_slice().str());
@ -482,7 +532,7 @@ td::Result<tonlib_api::object_ptr<tonlib_api::raw_accountState>> to_raw_accountS
.str();
}
return tonlib_api::make_object<tonlib_api::raw_accountState>(raw_state.balance, std::move(code), std::move(data),
to_transaction_id(raw_state.info));
to_transaction_id(raw_state.info), raw_state.sync_utime);
}
td::Result<std::string> to_std_address_or_throw(td::Ref<vm::CellSlice> cs) {
@ -591,7 +641,7 @@ td::Result<tonlib_api::object_ptr<tonlib_api::raw_transaction>> to_raw_transacti
}
}
return tonlib_api::make_object<tonlib_api::raw_transaction>(
data,
info.now, data,
tonlib_api::make_object<tonlib_api::internal_transactionId>(info.prev_trans_lt,
info.prev_trans_hash.as_slice().str()),
fees, std::move(in_msg), std::move(out_msgs));
@ -608,7 +658,14 @@ td::Result<tonlib_api::object_ptr<tonlib_api::raw_transactions>> to_raw_transact
TRY_RESULT(raw_transaction, to_raw_transaction(std::move(transaction)));
transactions.push_back(std::move(raw_transaction));
}
return tonlib_api::make_object<tonlib_api::raw_transactions>(std::move(transactions));
auto transaction_id =
tonlib_api::make_object<tonlib_api::internal_transactionId>(info.lt, info.hash.as_slice().str());
for (auto& transaction : transactions) {
std::swap(transaction->transaction_id_, transaction_id);
}
return tonlib_api::make_object<tonlib_api::raw_transactions>(std::move(transactions), std::move(transaction_id));
}
td::Result<tonlib_api::object_ptr<tonlib_api::testWallet_accountState>> to_testWallet_accountState(
@ -622,8 +679,8 @@ td::Result<tonlib_api::object_ptr<tonlib_api::testWallet_accountState>> to_testW
if (seqno == cs.fetch_ulong_eof) {
return td::Status::Error("Failed to parse seq_no");
}
return tonlib_api::make_object<tonlib_api::testWallet_accountState>(raw_state.balance, static_cast<td::uint32>(seqno),
to_transaction_id(raw_state.info));
return tonlib_api::make_object<tonlib_api::testWallet_accountState>(
raw_state.balance, static_cast<td::uint32>(seqno), to_transaction_id(raw_state.info), raw_state.sync_utime);
}
td::Result<tonlib_api::object_ptr<tonlib_api::testGiver_accountState>> to_testGiver_accountState(
@ -637,15 +694,16 @@ td::Result<tonlib_api::object_ptr<tonlib_api::testGiver_accountState>> to_testGi
if (seqno == cs.fetch_ulong_eof) {
return td::Status::Error("Failed to parse seq_no");
}
return tonlib_api::make_object<tonlib_api::testGiver_accountState>(raw_state.balance, static_cast<td::uint32>(seqno),
to_transaction_id(raw_state.info));
return tonlib_api::make_object<tonlib_api::testGiver_accountState>(
raw_state.balance, static_cast<td::uint32>(seqno), to_transaction_id(raw_state.info), raw_state.sync_utime);
}
td::Result<tonlib_api::object_ptr<tonlib_api::generic_AccountState>> to_generic_accountState(
RawAccountState&& raw_state) {
if (raw_state.code.is_null()) {
return tonlib_api::make_object<tonlib_api::generic_accountStateUninited>(
tonlib_api::make_object<tonlib_api::uninited_accountState>(raw_state.balance));
tonlib_api::make_object<tonlib_api::uninited_accountState>(raw_state.balance, empty_transaction_id(),
raw_state.sync_utime));
}
auto code_hash = raw_state.code->prefetch_ref()->get_hash();
@ -1019,4 +1077,30 @@ td::Status TonlibClient::do_request(const tonlib_api::changeLocalPassword& reque
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::onLiteServerQueryResult& request,
td::Promise<object_ptr<tonlib_api::ok>>&& promise) {
send_closure(ext_client_outbound_, &ExtClientOutbound::on_query_result, request.id_, td::BufferSlice(request.bytes_),
[promise = std::move(promise)](td::Result<td::Unit> res) mutable {
if (res.is_ok()) {
promise.set_value(tonlib_api::make_object<tonlib_api::ok>());
} else {
promise.set_error(res.move_as_error());
}
});
return td::Status::OK();
}
td::Status TonlibClient::do_request(const tonlib_api::onLiteServerQueryError& request,
td::Promise<object_ptr<tonlib_api::ok>>&& promise) {
send_closure(ext_client_outbound_, &ExtClientOutbound::on_query_result, request.id_,
td::Status::Error(request.error_->code_, request.error_->message_),
[promise = std::move(promise)](td::Result<td::Unit> res) mutable {
if (res.is_ok()) {
promise.set_value(tonlib_api::make_object<tonlib_api::ok>());
} else {
promise.set_error(res.move_as_error());
}
});
return td::Status::OK();
}
} // namespace tonlib

View file

@ -22,6 +22,7 @@
#include "tonlib/Config.h"
#include "tonlib/ExtClient.h"
#include "tonlib/ExtClientOutbound.h"
#include "tonlib/KeyStorage.h"
#include "td/actor/actor.h"
@ -44,6 +45,9 @@ class TonlibClient : public td::actor::Actor {
td::unique_ptr<TonlibCallback> callback_;
Config config_;
bool use_callbacks_for_network_{false};
td::actor::ActorId<ExtClientOutbound> ext_client_outbound_;
// KeyStorage
KeyStorage key_storage_;
@ -54,6 +58,7 @@ class TonlibClient : public td::actor::Actor {
ExtClientRef get_client_ref();
void init_ext_client();
void init_last_block();
bool is_closing_{false};
td::uint32 ref_cnt_{1};
@ -130,5 +135,12 @@ class TonlibClient : public td::actor::Actor {
td::Status do_request(const tonlib_api::changeLocalPassword& request,
td::Promise<object_ptr<tonlib_api::key>>&& promise);
td::Status do_request(const tonlib_api::onLiteServerQueryResult& request,
td::Promise<object_ptr<tonlib_api::ok>>&& promise);
td::Status do_request(const tonlib_api::onLiteServerQueryError& request,
td::Promise<object_ptr<tonlib_api::ok>>&& promise);
void proxy_request(td::int64 query_id, std::string data);
};
} // namespace tonlib

View file

@ -5,12 +5,17 @@
#include "td/utils/Parser.h"
#include "td/utils/port/signals.h"
#include "td/utils/port/path.h"
#include "td/utils/Random.h"
#include "terminal/terminal.h"
#include "tonlib/TonlibClient.h"
#include "tonlib/TonlibCallback.h"
#include "tonlib/ExtClientLazy.h"
#include "auto/tl/tonlib_api.hpp"
#include <iostream>
#include <map>
@ -20,6 +25,7 @@ class TonlibCli : public td::actor::Actor {
bool enable_readline{true};
std::string config;
std::string key_dir{"."};
bool use_callbacks_for_network{false};
};
TonlibCli(Options options) : options_(std::move(options)) {
}
@ -39,6 +45,8 @@ class TonlibCli : public td::actor::Actor {
std::map<std::uint64_t, td::Promise<tonlib_api::object_ptr<tonlib_api::Object>>> query_handlers_;
td::actor::ActorOwn<ton::adnl::AdnlExtClient> raw_client_;
bool is_closing_{false};
td::uint32 ref_cnt_{1};
@ -79,8 +87,28 @@ class TonlibCli : public td::actor::Actor {
load_keys();
if (options_.use_callbacks_for_network) {
auto config = tonlib::Config::parse(options_.config).move_as_ok();
auto lite_clients_size = config.lite_clients.size();
CHECK(lite_clients_size != 0);
auto lite_client_id = td::Random::fast(0, td::narrow_cast<int>(lite_clients_size) - 1);
auto& lite_client = config.lite_clients[lite_client_id];
class Callback : public tonlib::ExtClientLazy::Callback {
public:
explicit Callback(td::actor::ActorShared<> parent) : parent_(std::move(parent)) {
}
private:
td::actor::ActorShared<> parent_;
};
ref_cnt_++;
raw_client_ = tonlib::ExtClientLazy::create(lite_client.adnl_id, lite_client.address,
td::make_unique<Callback>(td::actor::actor_shared()));
}
using tonlib_api::make_object;
send_query(make_object<tonlib_api::init>(make_object<tonlib_api::options>(options_.config, options_.key_dir)),
send_query(make_object<tonlib_api::init>(make_object<tonlib_api::options>(options_.config, options_.key_dir,
options_.use_callbacks_for_network)),
[](auto r_ok) {
LOG_IF(ERROR, r_ok.is_error()) << r_ok.error();
td::TerminalIO::out() << "Tonlib is inited\n";
@ -121,6 +149,8 @@ class TonlibCli : public td::actor::Actor {
td::TerminalIO::out() << "exportkey [key_id] - export key\n";
td::TerminalIO::out() << "setconfig <path> - set lite server config\n";
td::TerminalIO::out() << "getstate <key_id> - get state of simple wallet with requested key\n";
td::TerminalIO::out()
<< "gethistory <key_id> - get history fo simple wallet with requested key (last 10 transactions)\n";
td::TerminalIO::out() << "init <key_id> - init simple wallet with requested key\n";
td::TerminalIO::out() << "transfer <from_key_id> <to_key_id> <amount> - transfer <amount> of grams from "
"<from_key_id> to <to_key_id>.\n"
@ -145,6 +175,8 @@ class TonlibCli : public td::actor::Actor {
set_config(parser.read_word());
} else if (cmd == "getstate") {
get_state(parser.read_word());
} else if (cmd == "gethistory") {
get_history(parser.read_word());
} else if (cmd == "init") {
init_simple_wallet(parser.read_word());
} else if (cmd == "transfer") {
@ -157,7 +189,31 @@ class TonlibCli : public td::actor::Actor {
}
}
void on_adnl_result(td::uint64 id, td::Result<td::BufferSlice> res) {
using tonlib_api::make_object;
if (res.is_ok()) {
send_query(make_object<tonlib_api::onLiteServerQueryResult>(id, res.move_as_ok().as_slice().str()),
[](auto r_ok) { LOG_IF(ERROR, r_ok.is_error()) << r_ok.error(); });
LOG(ERROR) << "!!!";
} else {
send_query(make_object<tonlib_api::onLiteServerQueryError>(
id, make_object<tonlib_api::error>(res.error().code(), res.error().message().str())),
[](auto r_ok) { LOG_IF(ERROR, r_ok.is_error()) << r_ok.error(); });
}
}
void on_tonlib_result(std::uint64_t id, tonlib_api::object_ptr<tonlib_api::Object> result) {
if (id == 0) {
if (result->get_id() == tonlib_api::updateSendLiteServerQuery::ID) {
auto update = tonlib_api::move_object_as<tonlib_api::updateSendLiteServerQuery>(std::move(result));
CHECK(!raw_client_.empty());
send_closure(raw_client_, &ton::adnl::AdnlExtClient::send_query, "query", td::BufferSlice(update->data_),
td::Timestamp::in(5),
[actor_id = actor_id(this), id = update->id_](td::Result<td::BufferSlice> res) {
send_closure(actor_id, &TonlibCli::on_adnl_result, id, std::move(res));
});
}
}
auto it = query_handlers_.find(id);
if (it == query_handlers_.end()) {
return;
@ -468,6 +524,53 @@ class TonlibCli : public td::actor::Actor {
td::TerminalIO::out() << to_string(r_res.ok());
});
}
void get_history(td::Slice key) {
if (key.empty()) {
dump_keys();
td::TerminalIO::out() << "Choose public key (hex prefix or #N)";
cont_ = [this](td::Slice key) { this->get_state(key); };
return;
}
auto r_address = to_account_address(key, false);
if (r_address.is_error()) {
td::TerminalIO::out() << "Unknown key id: [" << key << "]\n";
return;
}
auto address = r_address.move_as_ok();
using tonlib_api::make_object;
send_query(make_object<tonlib_api::generic_getAccountState>(
ton::move_tl_object_as<tonlib_api::accountAddress>(std::move(address.address))),
[this, key = key.str()](auto r_res) {
if (r_res.is_error()) {
td::TerminalIO::out() << "Can't get state: " << r_res.error() << "\n";
return;
}
this->get_history(key, *r_res.move_as_ok());
});
}
void get_history(td::Slice key, tonlib_api::generic_AccountState& state) {
auto r_address = to_account_address(key, false);
if (r_address.is_error()) {
td::TerminalIO::out() << "Unknown key id: [" << key << "]\n";
return;
}
auto address = r_address.move_as_ok();
tonlib_api::object_ptr<tonlib_api::internal_transactionId> transaction_id;
downcast_call(state, [&](auto& state) { transaction_id = std::move(state.account_state_->last_transaction_id_); });
send_query(
tonlib_api::make_object<tonlib_api::raw_getTransactions>(
ton::move_tl_object_as<tonlib_api::accountAddress>(std::move(address.address)), std::move(transaction_id)),
[](auto r_res) {
if (r_res.is_error()) {
td::TerminalIO::out() << "Can't get transactions: " << r_res.error() << "\n";
return;
}
td::TerminalIO::out() << to_string(r_res.move_as_ok()) << "\n";
});
}
void transfer(td::Slice from, td::Slice to, td::Slice grams) {
auto r_from_address = to_account_address(from, true);
@ -591,6 +694,10 @@ int main(int argc, char* argv[]) {
options.config = std::move(data);
return td::Status::OK();
});
p.add_option('c', "use_callbacks_for_network (for debug)", "do not use this", [&]() {
options.use_callbacks_for_network = true;
return td::Status::OK();
});
auto S = p.run(argc, argv);
if (S.is_error()) {