@@ -158,6 +158,64 @@ TEST(TonDbScanner, JettonWalletDetector_parse_burn_without_custom_payload) {
158158 scheduler.stop ();
159159}
160160
161+ TEST (TonDbScanner, JettonWalletDetector_parse_burn_without_response_destination) {
162+ /* *
163+ * The same situation as in the previous test - burn message doesn't have some required fields.
164+ * stTON (bemo) burn message doesn't require response_destination field at all and
165+ * in the documentation (https://docs.bemo.fi/developers/unstake) one can find a TL-B schema of the burn message:
166+ * burn#595f07bc query_id:uint64 jetton_amount:Coins = InternalMsgBody;
167+ *
168+ * Since stTON is quite popular, it is worth to add it as an exception to the rule.
169+ */
170+ td::actor::Scheduler scheduler ({1 });
171+ auto watcher = td::create_shared_destructor ([] { td::actor::SchedulerContext::get ()->stop (); });
172+
173+ // message payload for tx bea8befb0d6a928fa00e4ec4e6035b760ec12d4b339dd6cb2d53077fbf99c87f
174+ auto message_payload = vm::load_cell_slice_ref (vm::std_boc_deserialize (td::base64_decode (
175+ td::Slice (" te6ccgEBAQEAFAAAI1lfB7wAAAAAAAAAAFU2CBF7qA==" )).move_as_ok ()).move_as_ok ());
176+
177+ auto transaction = schema::Transaction ();
178+ transaction.account = block::StdAddress (std::string (" EQCbVZsB2jOe0DGc0DSUA-gxqzfuAjBI7mCvIxuYmWkzBNl-" )); // jetton wallet
179+ transaction.in_msg = std::make_optional (schema::Message ());
180+ transaction.in_msg ->source = " 0:E27383455DD29192D213773AD731540C1D83CE03BB9C9D59A13A9800335EAC22" ; // owner
181+
182+ td::actor::ActorId<InsertManagerInterface> insert_manager;
183+ td::actor::ActorOwn<JettonWalletDetector> jetton_wallet_detector;
184+ td::actor::ActorOwn<InterfaceManager> interface_manager;
185+ td::actor::ActorOwn<JettonMasterDetector> jetton_master_detector;
186+
187+ // prepare jetton metadata
188+ std::unordered_map<std::string, JettonWalletData> cache;
189+ JettonWalletData jetton_master;
190+ jetton_master.jetton = " 0:CD872FA7C5816052ACDF5332260443FAEC9AACC8C21CCA4D92E7F47034D11892" ;
191+ cache.emplace (std::string (" 0:9B559B01DA339ED0319CD0349403E831AB37EE023048EE60AF231B9899693304" ), jetton_master);
192+
193+ scheduler.run_in_context ([&] {
194+ interface_manager = td::actor::create_actor<InterfaceManager>(" interface_manager" , insert_manager);
195+ jetton_master_detector = td::actor::create_actor<JettonMasterDetector>(" jetton_master_detector" , interface_manager.get (), insert_manager);
196+
197+ jetton_wallet_detector = td::actor::create_actor<JettonWalletDetector>(" jetton_wallet_detector" ,
198+ jetton_master_detector.get (), interface_manager.get (), insert_manager, cache);
199+
200+ auto P = td::PromiseCreator::lambda ([&transaction, &jetton_master](td::Result<JettonBurn> R) {
201+ CHECK (R.is_ok ());
202+ auto burn = R.move_as_ok ();
203+ ASSERT_EQ (transaction.in_msg ->source .value (), burn.owner );
204+ ASSERT_EQ (convert::to_raw_address (transaction.account ), burn.jetton_wallet );
205+ ASSERT_EQ (jetton_master.jetton , burn.jetton_master );
206+ ASSERT_EQ (0 , burn.query_id );
207+ ASSERT_TRUE (burn.custom_payload .is_null ());
208+ ASSERT_EQ (std::string (" addr_none" ), burn.response_destination );
209+ CHECK (td::BigIntG<257 >(358101358522 ) == **burn.amount .get ());
210+ });
211+ td::actor::send_closure (jetton_wallet_detector, &JettonWalletDetector::parse_burn, transaction, message_payload, std::move (P));
212+ watcher.reset ();
213+ });
214+
215+ scheduler.run (10 );
216+ scheduler.stop ();
217+ }
218+
161219
162220TEST (TonDbScanner, JettonWalletDetector) {
163221 td::actor::Scheduler scheduler ({1 });
0 commit comments