diff --git a/pkg/api/emulation.go b/pkg/api/emulation.go index 071e08b7..99696169 100644 --- a/pkg/api/emulation.go +++ b/pkg/api/emulation.go @@ -206,7 +206,7 @@ func emulatedTreeToTrace( transaction, err := core.ConvertTransaction(int32(a.AddrStd.WorkchainId), tongo.Transaction{ Transaction: tree.TX, BlockID: tongo.BlockIDExt{BlockID: tongo.BlockID{Workchain: int32(a.AddrStd.WorkchainId)}}, - }) + }, nil) filteredMsgs := make([]core.Message, 0, len(transaction.OutMsgs)) for _, msg := range transaction.OutMsgs { if msg.Destination == nil { diff --git a/pkg/api/event_handlers.go b/pkg/api/event_handlers.go index 2ccaa9f3..908c930d 100644 --- a/pkg/api/event_handlers.go +++ b/pkg/api/event_handlers.go @@ -182,10 +182,11 @@ func (h *Handler) GetEvent(ctx context.Context, params oas.GetEventParams) (*oas if err != nil { return nil, toError(http.StatusInternalServerError, err) } - result, err := bath.FindActions(ctx, trace, bath.WithInformationSource(h.storage)) + actions, err := bath.FindActions(ctx, trace, bath.WithInformationSource(h.storage)) if err != nil { return nil, toError(http.StatusInternalServerError, err) } + result := bath.EnrichWithIntentions(trace, actions) event, err := h.toEvent(ctx, trace, result, params.AcceptLanguage) if err != nil { return nil, toError(http.StatusInternalServerError, err) @@ -234,12 +235,13 @@ func (h *Handler) GetAccountEvents(ctx context.Context, params oas.GetAccountEve skippedInProgress = append(skippedInProgress, traceID.Hash) continue } - result, err := bath.FindActions(ctx, trace, bath.ForAccount(account.ID), bath.WithInformationSource(h.storage)) + actions, err := bath.FindActions(ctx, trace, bath.ForAccount(account.ID), bath.WithInformationSource(h.storage)) if err != nil { events = append(events, h.toUnknownAccountEvent(account.ID, traceID)) continue //return nil, toError(http.StatusInternalServerError, err) } + result := bath.EnrichWithIntentions(trace, actions) e, err := h.toAccountEvent(ctx, account.ID, trace, result, params.AcceptLanguage, params.SubjectOnly.Value) if err != nil { events = append(events, h.toUnknownAccountEvent(account.ID, traceID)) @@ -262,10 +264,11 @@ func (h *Handler) GetAccountEvents(ctx context.Context, params oas.GetAccountEve continue } i++ - result, err := bath.FindActions(ctx, trace, bath.ForAccount(account.ID), bath.WithInformationSource(h.storage)) + actions, err := bath.FindActions(ctx, trace, bath.ForAccount(account.ID), bath.WithInformationSource(h.storage)) if err != nil { return nil, toError(http.StatusInternalServerError, err) } + result := bath.EnrichWithIntentions(trace, actions) event, err := h.toAccountEvent(ctx, account.ID, trace, result, params.AcceptLanguage, params.SubjectOnly.Value) if err != nil { return nil, toError(http.StatusInternalServerError, err) diff --git a/pkg/bath/actions.go b/pkg/bath/actions.go index bcc149e2..707117f3 100644 --- a/pkg/bath/actions.go +++ b/pkg/bath/actions.go @@ -90,6 +90,7 @@ type ( InscriptionTransfer *InscriptionTransferAction `json:",omitempty"` Success bool Type ActionType + Error *string BaseTransactions []ton.Bits256 } TonTransferAction struct { diff --git a/pkg/bath/bath_test.go b/pkg/bath/bath_test.go index 3da4d8c2..6254e1cc 100644 --- a/pkg/bath/bath_test.go +++ b/pkg/bath/bath_test.go @@ -164,6 +164,8 @@ func TestFindActions(t *testing.T) { tongo.MustParseBlockID("(0,8000000000000000,34021598)"), // nft transfer tongo.MustParseBlockID("(0,8000000000000000,33600829)"), + // failed dedust swap + tongo.MustParseBlockID("(0,7000000000000000,45592983)"), }), ) @@ -394,6 +396,21 @@ func TestFindActions(t *testing.T) { hash: "e27cdf1d6987a3e74dc8d9c4a52a5b22112fe3946d0dceadf8160b74f80b9d46", filenamePrefix: "governance_jetton_mint", }, + { + name: "failed simple transfer", + hash: "63d358331c0154ade48ab92b4634c3fff004f42ce7201a37973938862d232c0f", + filenamePrefix: "failed-simple-transfer", + }, + { + name: "simple transfers, one of two failed", + hash: "ac0b8bf04949cb72759832ec6c123b3677b8ca140899ac859aa66a558e4f4c11", + filenamePrefix: "simple-transfers-one-failed", + }, + { + name: "failed dedust swap", + hash: "887c7763f41ca4a4b9de28900ab514caabc0c27ed5b41d9918d60f5e7f4a9d96", + filenamePrefix: "failed-dedust-swap", + }, } { t.Run(c.name, func(t *testing.T) { trace, err := storage.GetTrace(context.Background(), tongo.MustParseHash(c.hash)) @@ -411,6 +428,7 @@ func TestFindActions(t *testing.T) { WithStraws(straws), WithInformationSource(source)) require.Nil(t, err) + actionsList = EnrichWithIntentions(trace, actionsList) results := result{ Actions: actionsList.Actions, } diff --git a/pkg/bath/intentions.go b/pkg/bath/intentions.go new file mode 100644 index 00000000..2227c445 --- /dev/null +++ b/pkg/bath/intentions.go @@ -0,0 +1,227 @@ +package bath + +import ( + "github.com/tonkeeper/opentonapi/internal/g" + "github.com/tonkeeper/opentonapi/pkg/core" + "github.com/tonkeeper/tongo/abi" + "github.com/tonkeeper/tongo/boc" + "golang.org/x/exp/slices" + "reflect" +) + +type OutMessage struct { + body any + mode uint8 + messageRelaxed abi.MessageRelaxed + tx *core.Transaction +} + +func EnrichWithIntentions(trace *core.Trace, actions *ActionsList) *ActionsList { + outMessages, inMsgCount := extractIntentions(trace) + if len(outMessages) <= inMsgCount { + return actions + } + outMessages = removeMatchedIntentions(trace, &outMessages) + for _, outMsg := range outMessages { + newAction := createActionFromMessage(outMsg) + added := false + for i, action := range actions.Actions { + if slices.Contains(action.BaseTransactions, outMsg.tx.Hash) { + actions.Actions = slices.Insert(actions.Actions, i+1, newAction) + added = true + break + } + } + if !added { + actions.Actions = append(actions.Actions, newAction) + } + } + return actions +} + +func extractIntentions(trace *core.Trace) ([]OutMessage, int) { + var outMessages []OutMessage + var inMsgCount int + + var getIntentions func(*core.Trace) + getIntentions = func(trace *core.Trace) { + outMessages = append(outMessages, getOutMessages(&trace.Transaction)...) + for _, child := range trace.Children { + if child.InMsg != nil { + inMsgCount += 1 + } + getIntentions(child) + } + } + getIntentions(trace) + + return outMessages, inMsgCount +} + +func removeMatchedIntentions(trace *core.Trace, intentions *[]OutMessage) []OutMessage { + var matchAndRemove func(*core.Trace) + matchAndRemove = func(trace *core.Trace) { + for _, child := range trace.Children { + for i, outMsg := range *intentions { + if isMatch(outMsg, child.Transaction.InMsg) { + // remove this outgoing message + *intentions = append((*intentions)[:i], (*intentions)[i+1:]...) + } + } + matchAndRemove(child) + } + } + matchAndRemove(trace) + return *intentions +} + +func isMatch(msgOut OutMessage, msgIn *core.Message) bool { + if msgIn == nil { + return false + } + + if !compareMessageFields(msgOut, msgIn) { + return false + } + + _, ok := msgOut.body.(*boc.Cell) + if (msgOut.body == nil || ok) && msgIn.DecodedBody == nil { + return true + } + + if msgOut.body == nil || msgIn.DecodedBody == nil { + return false + } + + if reflect.TypeOf(msgOut.body) != reflect.TypeOf(msgIn.DecodedBody.Value) { + return false + } + + // compare message body + switch bodyOut := msgOut.body.(type) { + case abi.TextCommentMsgBody: + bodyIn := msgIn.DecodedBody.Value.(abi.TextCommentMsgBody) + return bodyOut.Text == bodyIn.Text + case abi.JettonTransferMsgBody: + bodyIn := msgIn.DecodedBody.Value.(abi.JettonTransferMsgBody) + return bodyIn.QueryId == bodyOut.QueryId + case abi.NftTransferMsgBody: + bodyIn := msgIn.DecodedBody.Value.(abi.NftTransferMsgBody) + return bodyIn.QueryId == bodyOut.QueryId + case abi.DedustSwapMsgBody: + bodyIn := msgIn.DecodedBody.Value.(abi.DedustSwapMsgBody) + return bodyIn.QueryId == bodyOut.QueryId + default: + return true // not supported yet, so removed + } +} + +func compareMessageFields(msgOut OutMessage, msgIn *core.Message) bool { + msg := msgOut.messageRelaxed.MessageInternal + + if msg.Dest != msgIn.Destination.ToMsgAddress() { + return false + } + + if msgOut.mode < 128 && int64(msg.Value.Grams) != msgIn.Value { + return false + } + + return true +} + +func getOutMessages(transaction *core.Transaction) []OutMessage { + if transaction.InMsg.DecodedBody == nil { + return []OutMessage{} + } + + var messages []OutMessage + switch v := transaction.InMsg.DecodedBody.Value.(type) { + case abi.WalletSignedV3ExtInMsgBody: + for _, msg := range v.Payload { + messages = append(messages, OutMessage{ + body: msg.Message.MessageInternal.Body.Value.Value, + mode: msg.Mode, + tx: transaction, + messageRelaxed: msg.Message}) + } + case abi.WalletSignedV4ExtInMsgBody: + for _, msg := range v.Payload { + messages = append(messages, OutMessage{ + body: msg.Message.MessageInternal.Body.Value.Value, + mode: msg.Mode, + tx: transaction, + messageRelaxed: msg.Message}) + } + case abi.WalletSignedExternalV5R1ExtInMsgBody: + if v.Actions != nil { + for _, msg := range *v.Actions { + messages = append(messages, OutMessage{ + body: msg.Msg.MessageInternal.Body.Value.Value, + mode: msg.Mode, + tx: transaction, + messageRelaxed: msg.Msg}) + } + } + case abi.WalletSignedInternalV5R1MsgBody: + if v.Actions != nil { + for _, msg := range *v.Actions { + messages = append(messages, OutMessage{ + body: msg.Msg.MessageInternal.Body.Value.Value, + mode: msg.Mode, + tx: transaction, + messageRelaxed: msg.Msg}) + } + } + case abi.HighloadWalletSignedV3ExtInMsgBody: + messages = []OutMessage{{ + body: v.Msg.MessageToSend.MessageInternal.Body.Value.Value, + mode: v.Msg.SendMode, + tx: transaction, + messageRelaxed: v.Msg.MessageToSend}} + } + return messages +} + +func createActionFromMessage(msgOut OutMessage) Action { + var action Action + switch body := msgOut.body.(type) { + case abi.TextCommentMsgBody: + action = Action{Type: TonTransfer, TonTransfer: &TonTransferAction{ + Recipient: parseAccount(msgOut.messageRelaxed.MessageInternal.Dest).Address, + Sender: msgOut.tx.Account, + Comment: g.Pointer(string(body.Text))}} + if msgOut.mode < 128 { + action.TonTransfer.Amount = int64(msgOut.messageRelaxed.MessageInternal.Value.Grams) + if msgOut.tx.EndBalance < action.TonTransfer.Amount { + action.Error = g.Pointer("Not enough balance") + } + } + case abi.NftTransferMsgBody: + action = Action{Type: NftItemTransfer, NftItemTransfer: &NftTransferAction{ + Recipient: &parseAccount(body.NewOwner).Address, + Sender: &msgOut.tx.Account, + Nft: parseAccount(msgOut.messageRelaxed.MessageInternal.Dest).Address, + }} + case abi.JettonTransferMsgBody: + action = Action{Type: JettonTransfer, JettonTransfer: &JettonTransferAction{ + Recipient: &parseAccount(body.Destination).Address, + Sender: &msgOut.tx.Account, + Amount: body.Amount, + SendersWallet: parseAccount(msgOut.messageRelaxed.MessageInternal.Dest).Address, + }} + default: + action = Action{Type: TonTransfer, TonTransfer: &TonTransferAction{ + Recipient: parseAccount(msgOut.messageRelaxed.MessageInternal.Dest).Address, + Sender: msgOut.tx.Account}} + if msgOut.mode < 128 { + action.TonTransfer.Amount = int64(msgOut.messageRelaxed.MessageInternal.Value.Grams) + if msgOut.tx.EndBalance < action.TonTransfer.Amount { + action.Error = g.Pointer("Not enough balance") + } + } + } + + action.Success = false + return action +} diff --git a/pkg/bath/testdata/buy-nft-on-fragment.json b/pkg/bath/testdata/buy-nft-on-fragment.json index e9200359..978e1b12 100644 --- a/pkg/bath/testdata/buy-nft-on-fragment.json +++ b/pkg/bath/testdata/buy-nft-on-fragment.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "NftPurchase", + "Error": null, "BaseTransactions": [ "268f46a593b64400a93eb17a0945629647fdd662fb00ff69b58327d10336022b", "29c039520eeef18295d428e919b7b33bd472f50ab3e9713b767a4f5e5c55181e" @@ -26,6 +27,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "9fc8546b6f866685908c18b91e14d0fbafb39d6389403831b3ba63c3e60399e5" ] @@ -41,6 +43,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "fa4c9108bebce63aff79570fceccf99126996b1e8793fcbdcd56a0b8752a2ee1" ] diff --git a/pkg/bath/testdata/cut-jetton-transfer.json b/pkg/bath/testdata/cut-jetton-transfer.json index 3bb48346..2989b2a6 100644 --- a/pkg/bath/testdata/cut-jetton-transfer.json +++ b/pkg/bath/testdata/cut-jetton-transfer.json @@ -14,6 +14,7 @@ }, "Success": true, "Type": "JettonTransfer", + "Error": null, "BaseTransactions": [ "ae17905025e6920b8ca4f036c79bf3cdddeea052556f9d2b21c574670caf1d12", "9187161025b3f6249b5d57b8a347bb6e7f82c364fb7f0efb3261f54604574e50", diff --git a/pkg/bath/testdata/dedust-swap-from-ton.json b/pkg/bath/testdata/dedust-swap-from-ton.json index f001ef42..9ea25099 100644 --- a/pkg/bath/testdata/dedust-swap-from-ton.json +++ b/pkg/bath/testdata/dedust-swap-from-ton.json @@ -20,6 +20,7 @@ }, "Success": true, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "c85ebd3043603612af808ab874ac1d19d1a68725afc3c4a78589ed5e88372b21", "bdef4c941f1f311c7de9badebc71464752c6599ae7cdcf514cd449726d750dd6", diff --git a/pkg/bath/testdata/dedust-swap-jettons.json b/pkg/bath/testdata/dedust-swap-jettons.json index 55603495..826b6c37 100644 --- a/pkg/bath/testdata/dedust-swap-jettons.json +++ b/pkg/bath/testdata/dedust-swap-jettons.json @@ -20,6 +20,7 @@ }, "Success": true, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "c18eaf143061a879bdd81f4db08cf4e37ebaeeea03b350fcf33dce1fa486bb62", "2e2cdf4736ba039f1e86faf195c6ac68835c030e150cbabcf96ce20514fbf7e4", @@ -38,6 +39,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "2e2cdf4736ba039f1e86faf195c6ac68835c030e150cbabcf96ce20514fbf7e4" ] diff --git a/pkg/bath/testdata/dedust-swap-to-ton.json b/pkg/bath/testdata/dedust-swap-to-ton.json index 062a3d89..dc19c4d8 100644 --- a/pkg/bath/testdata/dedust-swap-to-ton.json +++ b/pkg/bath/testdata/dedust-swap-to-ton.json @@ -20,6 +20,7 @@ }, "Success": true, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "bba7985c6b547c2bce3a2979b41bf5b0c5bf5a399bcbee69a80572039147ce4d", "93a65eccc2922a64274a090e52973ff9ddd26b86d6458ab2bed36ed3c051ec59", diff --git a/pkg/bath/testdata/deploy-contract.json b/pkg/bath/testdata/deploy-contract.json index 083e405c..86a47598 100644 --- a/pkg/bath/testdata/deploy-contract.json +++ b/pkg/bath/testdata/deploy-contract.json @@ -11,6 +11,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "4ac45cea7c469c2c98b73b064d1588313f8cde5b356267418302801d5e94b17b" ] @@ -22,6 +23,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "657623f3db93397a3bb956e0e621d7a37e4ff27b80013a68f2dd91c8094b50e3" ] diff --git a/pkg/bath/testdata/deposit-liquid-staking.json b/pkg/bath/testdata/deposit-liquid-staking.json index 7f515f3d..6f0e507a 100644 --- a/pkg/bath/testdata/deposit-liquid-staking.json +++ b/pkg/bath/testdata/deposit-liquid-staking.json @@ -9,6 +9,7 @@ }, "Success": true, "Type": "DepositStake", + "Error": null, "BaseTransactions": [ "20bee52141d1af08d3631baba8e598518a5a98e7b7d82e6960c79cb4001ec910" ] @@ -22,6 +23,7 @@ }, "Success": true, "Type": "JettonMint", + "Error": null, "BaseTransactions": [ "2d77c21a86e5189a6b44bfed0c8c588505f770ff8bdcdfe1a3528512f330d9b1", "242f3560ec3274abf5046ed7a867dfb7b37a97d86abb244f06211e809a27e6de", @@ -36,6 +38,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "2d77c21a86e5189a6b44bfed0c8c588505f770ff8bdcdfe1a3528512f330d9b1" ] diff --git a/pkg/bath/testdata/disintar-nft-purchase.json b/pkg/bath/testdata/disintar-nft-purchase.json index dcffee56..100837d3 100644 --- a/pkg/bath/testdata/disintar-nft-purchase.json +++ b/pkg/bath/testdata/disintar-nft-purchase.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "NftPurchase", + "Error": null, "BaseTransactions": [ "bccf47a1994af80196b94000b1d3a7bd92a046ca0a8a26db690802457da1d5cf", "3a30ad237eedde236d8aad4e1506e249d70fb6eb245c4d776ecb24df38d628d9", @@ -27,6 +28,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "5191af8acbf473017d2df1b164fd686f0d107278104597d89040104a7c63b9e7" ] @@ -42,6 +44,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "6f7fa225314b344d390ef9c1a451ea4c01b32528bf3341f215ad7787b6bc9694" ] @@ -57,6 +60,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "ec4e20e6047390f1202af08d2c4df336d8e843ea015d488832404898c54ffda2" ] diff --git a/pkg/bath/testdata/domain-renew.json b/pkg/bath/testdata/domain-renew.json index 434334b4..7913577a 100644 --- a/pkg/bath/testdata/domain-renew.json +++ b/pkg/bath/testdata/domain-renew.json @@ -7,6 +7,7 @@ }, "Success": true, "Type": "DomainRenew", + "Error": null, "BaseTransactions": [ "bf33c4ee09a872f0831935adec38a0e411c6be83b87e47bb7bf7a843d5e06047" ] @@ -21,6 +22,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "5123850dca7109412f695435a9a75618c001b70fad98d34d950b860116f37785" ] diff --git a/pkg/bath/testdata/encrypted-comment.json b/pkg/bath/testdata/encrypted-comment.json index 80917162..88c4e238 100644 --- a/pkg/bath/testdata/encrypted-comment.json +++ b/pkg/bath/testdata/encrypted-comment.json @@ -14,6 +14,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "c1d98ee34e88a912d7eefd7d1401d612d33c74835343814ca99a318fb7138ea8" ] @@ -25,6 +26,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "6f3e1f2c05df05345198a9d26456dcb51d4c78ce64ced56fb9976e92941211d3" ] diff --git a/pkg/bath/testdata/failed-dedust-swap.json b/pkg/bath/testdata/failed-dedust-swap.json new file mode 100644 index 00000000..f5227b02 --- /dev/null +++ b/pkg/bath/testdata/failed-dedust-swap.json @@ -0,0 +1,26 @@ +{ + "Actions": [ + { + "TonTransfer": { + "Amount": 189417707456, + "Comment": null, + "EncryptedComment": null, + "Recipient": "0:dae153a74d894bbc32748198cd626e4f5df4a69ad2fa56ce80fc2644b5708d20", + "Sender": "0:7be3026a154d127ea897871c06d4356474162f96caa3122d1adc81981ebcfccf", + "Refund": null + }, + "Success": false, + "Type": "TonTransfer", + "Error": "Not enough balance", + "BaseTransactions": null + } + ], + "Accounts": [ + { + "Account": "0:7be3026a154d127ea897871c06d4356474162f96caa3122d1adc81981ebcfccf", + "Ton": -2914445, + "Fee": 2914445, + "Jettons": null + } + ] + } \ No newline at end of file diff --git a/pkg/bath/testdata/failed-simple-transfer.json b/pkg/bath/testdata/failed-simple-transfer.json new file mode 100644 index 00000000..30fe652b --- /dev/null +++ b/pkg/bath/testdata/failed-simple-transfer.json @@ -0,0 +1,26 @@ +{ + "Actions": [ + { + "TonTransfer": { + "Amount": 1000000000000, + "Comment": null, + "EncryptedComment": null, + "Recipient": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Sender": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Refund": null + }, + "Success": false, + "Type": "TonTransfer", + "Error": "Not enough balance", + "BaseTransactions": null + } + ], + "Accounts": [ + { + "Account": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Ton": -2451454, + "Fee": 2451454, + "Jettons": null + } + ] + } \ No newline at end of file diff --git a/pkg/bath/testdata/getgems-nft-purchase.json b/pkg/bath/testdata/getgems-nft-purchase.json index 27514521..51e18c90 100644 --- a/pkg/bath/testdata/getgems-nft-purchase.json +++ b/pkg/bath/testdata/getgems-nft-purchase.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "NftPurchase", + "Error": null, "BaseTransactions": [ "5bf0cbc13d3079056cf300c80ab1cebf2e7e3ba20d0cef31678f0575fecb8beb", "dec6e1b8984a00114f6c0763ae1a5b2db5f9b82d57932554727a4f2c33498a9b", @@ -28,6 +29,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "4a38cfbe295cdb38b98d010975372aeb96ebd700682132f641bcadc4de230a60" ] @@ -43,6 +45,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "95e7869735d43d858c82356f2475a52e7682b7ed9718e55d07296f9ed0a3396c" ] @@ -58,6 +61,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "0dd50bfaeb46c13bc7919612cde6034e8a9a4d79ee23fc64a7570d739da601f9" ] @@ -69,6 +73,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "8feb00edd889f8a36fb8af5b4d5370190fcbe872088cd1247c445e3c3b39a795" ] diff --git a/pkg/bath/testdata/getgetms-cancel-sale.json b/pkg/bath/testdata/getgetms-cancel-sale.json index b348a68a..fafba1a5 100644 --- a/pkg/bath/testdata/getgetms-cancel-sale.json +++ b/pkg/bath/testdata/getgetms-cancel-sale.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "dd73b0fbd2f8ddb788802e999afb4e27a931492036f9038a9f0b773caf96e923" ] @@ -25,6 +26,7 @@ }, "Success": true, "Type": "NftItemTransfer", + "Error": null, "BaseTransactions": [ "e4717dd6a13f472299757879cf46480e07ea64fae7a5bccbc4a0766ba71b6f4e", "af9603b51ea224f718d884d977b85ac9f46ead2c9fe2b424412dade6a8305e1a" diff --git a/pkg/bath/testdata/governance_jetton_mint.json b/pkg/bath/testdata/governance_jetton_mint.json index 7a867714..ec07dd94 100644 --- a/pkg/bath/testdata/governance_jetton_mint.json +++ b/pkg/bath/testdata/governance_jetton_mint.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "6ea51bde0e6471ef5a7d06209f7b4cef6e2e175ad36d3cd00e8b5fa23c174dfd" ] @@ -24,6 +25,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "da099f32c4504fdcec2e5ee93f5dbc958b79e5c82a3fff25545738ec8b91cb34" ] @@ -38,6 +40,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "86697608f8a1a352d1b83fbb295890236f306ec2e56ac80e55510573b34251f0" ] @@ -51,6 +54,7 @@ }, "Success": true, "Type": "JettonMint", + "Error": null, "BaseTransactions": [ "aa939cbcd55cd707175d71d55136e101d8ad1e4b4339bd56e23d0492c5e15ac1", "50877f2d76ad0c3b5e079b9fa0c75ebb04fd8ef4905e439f52e608259357ce62", @@ -64,6 +68,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "50877f2d76ad0c3b5e079b9fa0c75ebb04fd8ef4905e439f52e608259357ce62" ] @@ -75,6 +80,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "da099f32c4504fdcec2e5ee93f5dbc958b79e5c82a3fff25545738ec8b91cb34" ] diff --git a/pkg/bath/testdata/ihr-fee.json b/pkg/bath/testdata/ihr-fee.json index e93e073b..02f90c27 100644 --- a/pkg/bath/testdata/ihr-fee.json +++ b/pkg/bath/testdata/ihr-fee.json @@ -11,6 +11,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "0916cd818bacdf7b23a1c75dd3940f0dfe7a815162a58bddd32124c229efd56a" ] diff --git a/pkg/bath/testdata/jetton-transfer-to-another-person.json b/pkg/bath/testdata/jetton-transfer-to-another-person.json index 41d0d681..aca9e325 100644 --- a/pkg/bath/testdata/jetton-transfer-to-another-person.json +++ b/pkg/bath/testdata/jetton-transfer-to-another-person.json @@ -14,6 +14,7 @@ }, "Success": true, "Type": "JettonTransfer", + "Error": null, "BaseTransactions": [ "d7c56c9c08a0b83d0486a993f248aa61b62504bb7cb8223c5705cb8ee4882d17", "61f2a240452c334febc1f20df9c468c4bb13f396fd08929537409dd47c1f5261", @@ -28,6 +29,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "61f2a240452c334febc1f20df9c468c4bb13f396fd08929537409dd47c1f5261" ] diff --git a/pkg/bath/testdata/jetton-transfer-to-myself.json b/pkg/bath/testdata/jetton-transfer-to-myself.json index 4245e181..40e05f3a 100644 --- a/pkg/bath/testdata/jetton-transfer-to-myself.json +++ b/pkg/bath/testdata/jetton-transfer-to-myself.json @@ -14,6 +14,7 @@ }, "Success": true, "Type": "JettonTransfer", + "Error": null, "BaseTransactions": [ "e7befadce3fc7a1f15f7119beb23a8e056c3e8db5fc807c72c488a740a08614b", "d1e9668698b01c839bfa12be742d6c88ffe703a0790099bfbbb844c4d7edbdf0", diff --git a/pkg/bath/testdata/liquid-withdraw-pending-request.json b/pkg/bath/testdata/liquid-withdraw-pending-request.json index 53edfc64..b419d715 100644 --- a/pkg/bath/testdata/liquid-withdraw-pending-request.json +++ b/pkg/bath/testdata/liquid-withdraw-pending-request.json @@ -9,6 +9,7 @@ }, "Success": true, "Type": "WithdrawStakeRequest", + "Error": null, "BaseTransactions": [ "32a649c3f4c5cd15cda3678bba67f2a1ccd6cd554249a726e760cfe389226008", "1cb338e71299a927fb4f3ed26d87b141df6d5996b31c01bde8494c0ee2b4ec8d", @@ -25,6 +26,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "075bfecbaae2f45c6e0d5c3125e41a0d1f123ef9ba0638c7701e3b4e36472d0d" ] diff --git a/pkg/bath/testdata/megatonfi-swap.json b/pkg/bath/testdata/megatonfi-swap.json index fce8e65e..921d8db0 100644 --- a/pkg/bath/testdata/megatonfi-swap.json +++ b/pkg/bath/testdata/megatonfi-swap.json @@ -20,6 +20,7 @@ }, "Success": true, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "e5d8031bb6e6001342fae861e94761658a96d4e6bd8ed26814ff2746ed3c38a6", "b7be28c8fcba9e2a4e07d7f6a11c30ad3a3e4e07181717cf2372be88069d4815", @@ -45,6 +46,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "f40d673de37e9a7ea81a346ee4b6b1371fa0c456ddcf15b48e6e6d67e3b02071" ] diff --git a/pkg/bath/testdata/multiple-call-contracts.json b/pkg/bath/testdata/multiple-call-contracts.json index a93fe183..bb950bf8 100644 --- a/pkg/bath/testdata/multiple-call-contracts.json +++ b/pkg/bath/testdata/multiple-call-contracts.json @@ -14,6 +14,7 @@ }, "Success": true, "Type": "JettonTransfer", + "Error": null, "BaseTransactions": [ "a47be2c95381c33a3efd100aaff86f9bb415bc21d3f2b7a751872ea7631012f1", "7309e9a76410ed7d8d4147790dea40c3cbbbe325946b6af36bcf30ae86048d67", @@ -30,6 +31,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "52d18ed6ff9de1724d30a7bc7347680b37a6205736c74f09495e5a482e3196e6" ] @@ -44,6 +46,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "e9b362ae466b18a53a8bb658e14511787699d14428c753b94ffcfe34262ff92d" ] @@ -62,6 +65,7 @@ }, "Success": true, "Type": "JettonTransfer", + "Error": null, "BaseTransactions": [ "1c0e8d968434981c8d380453bc55c31984ae50c7068ebc9262610c798dbcbfb4", "3cf5c2370fa0677f13b4629758942c0a309be33d878b796a4c8ad1ad7297fd48", @@ -78,6 +82,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "2ba854a4642c1523aa1e6a91f61f3e9d7f8c2963787b6c9c8f5695f0720d3383" ] @@ -96,6 +101,7 @@ }, "Success": true, "Type": "JettonTransfer", + "Error": null, "BaseTransactions": [ "be8c3f1bba22515a8efbe43cbbf195476f43ad7c75fc772dc636ffddf51f2304", "34fa15497ceebed556dcdde456d5a232d4194b57f1ba403aebce0a838b77f8dc", @@ -109,6 +115,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "34fa15497ceebed556dcdde456d5a232d4194b57f1ba403aebce0a838b77f8dc" ] diff --git a/pkg/bath/testdata/nft-transfer.json b/pkg/bath/testdata/nft-transfer.json index be7de5fa..6ec84e8b 100644 --- a/pkg/bath/testdata/nft-transfer.json +++ b/pkg/bath/testdata/nft-transfer.json @@ -11,6 +11,7 @@ }, "Success": true, "Type": "NftItemTransfer", + "Error": null, "BaseTransactions": [ "18122fb128076d62f3ad1b45619ac929eb308d757690a6ab9832d977e8214859", "648b9fb6f0781778b5128efcffd306545695e019795ca35e4a7ff981c544f0ea", diff --git a/pkg/bath/testdata/simple-transfer.json b/pkg/bath/testdata/simple-transfer.json index c08645e5..ca5d0b1c 100644 --- a/pkg/bath/testdata/simple-transfer.json +++ b/pkg/bath/testdata/simple-transfer.json @@ -11,6 +11,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "e969bcf584062ba9d329890a28c36fa818a050ab9cf9c80c62847fead1ef3732" ] diff --git a/pkg/bath/testdata/simple-transfers-one-failed.json b/pkg/bath/testdata/simple-transfers-one-failed.json new file mode 100644 index 00000000..b7391d14 --- /dev/null +++ b/pkg/bath/testdata/simple-transfers-one-failed.json @@ -0,0 +1,42 @@ +{ + "Actions": [ + { + "TonTransfer": { + "Amount": 1000000, + "Comment": null, + "EncryptedComment": null, + "Recipient": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Sender": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Refund": null + }, + "Success": true, + "Type": "TonTransfer", + "Error": null, + "BaseTransactions": [ + "5595b0f88d7482de31ba6499d9e95e19c75b527c67447aa54404f226373a8ea4" + ] + }, + { + "TonTransfer": { + "Amount": 1000000000000, + "Comment": null, + "EncryptedComment": null, + "Recipient": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Sender": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Refund": null + }, + "Success": false, + "Type": "TonTransfer", + "Error": "Not enough balance", + "BaseTransactions": null + } + ], + "Accounts": [ + { + "Account": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb", + "Ton": -3395653, + "Fee": 3395653, + "Jettons": null + } + ] + } \ No newline at end of file diff --git a/pkg/bath/testdata/stonfi-failed-swap.json b/pkg/bath/testdata/stonfi-failed-swap.json index 7807f9f4..96c55fac 100644 --- a/pkg/bath/testdata/stonfi-failed-swap.json +++ b/pkg/bath/testdata/stonfi-failed-swap.json @@ -20,6 +20,7 @@ }, "Success": false, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "ea39b268e9771623b9c4991ae6fd607b1faa0518c1ca8fa7adbdfbb5ee26314e", "ff27078f163f27a2b9d579da2e15b4d2d59de7e9806d64e8d511bd98d449e7a0", diff --git a/pkg/bath/testdata/stonfi-purchase-jUSDT.json b/pkg/bath/testdata/stonfi-purchase-jUSDT.json index 1a1635ba..971cc6be 100644 --- a/pkg/bath/testdata/stonfi-purchase-jUSDT.json +++ b/pkg/bath/testdata/stonfi-purchase-jUSDT.json @@ -20,6 +20,7 @@ }, "Success": true, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "0758bff5c2318d2063d798d2040ffdcd550991bfe27d7a78d0479aa0d27c5f7a", "5b14584359682422af53bd5e957bdec0905225d8b14a798bb61a29cc01f971d3", diff --git a/pkg/bath/testdata/stonfi-swap-jUSDT-STON.json b/pkg/bath/testdata/stonfi-swap-jUSDT-STON.json index e3940b57..8af86990 100644 --- a/pkg/bath/testdata/stonfi-swap-jUSDT-STON.json +++ b/pkg/bath/testdata/stonfi-swap-jUSDT-STON.json @@ -20,6 +20,7 @@ }, "Success": true, "Type": "JettonSwap", + "Error": null, "BaseTransactions": [ "e8933ed0b2086b312f89a3ae5f597666493ca747b69cea9ef9a79c1e641e763f", "cdc129c36ad3c345459ed5d0c1ffad145134e6ce96b8a4ed8201909def33de2a", @@ -38,6 +39,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "9809a999b20e8bae123c21f229abb4de7b00b03c754eb692b23a8662f5445c19" ] diff --git a/pkg/bath/testdata/subscription-init.json b/pkg/bath/testdata/subscription-init.json index aeb5e91a..c8280c43 100644 --- a/pkg/bath/testdata/subscription-init.json +++ b/pkg/bath/testdata/subscription-init.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "Subscribe", + "Error": null, "BaseTransactions": [ "a9d02569af93f8ec85ea9c322690e5ba561783dcb02f000698af9b2f334ae9c4", "ccf8675254a925f516ee7facaaf7a71d166e6ac99fc71ce9f6f4129ea9ee3130" @@ -22,6 +23,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "a9d02569af93f8ec85ea9c322690e5ba561783dcb02f000698af9b2f334ae9c4" ] diff --git a/pkg/bath/testdata/subscription-prolongation.json b/pkg/bath/testdata/subscription-prolongation.json index b5d8bc95..c1ff8982 100644 --- a/pkg/bath/testdata/subscription-prolongation.json +++ b/pkg/bath/testdata/subscription-prolongation.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "Subscribe", + "Error": null, "BaseTransactions": [ "d5cf39c85392e40a7f5b0e706c4df56ad89cb214e4c5b5206fbe82c6d71a09cf", "0869aca7038f732a29e89fc9ce1990afecc99106d8ab07d967a2e0950faf6580", diff --git a/pkg/bath/testdata/telemint-deploy.json b/pkg/bath/testdata/telemint-deploy.json index f70758fb..58b49688 100644 --- a/pkg/bath/testdata/telemint-deploy.json +++ b/pkg/bath/testdata/telemint-deploy.json @@ -11,6 +11,7 @@ }, "Success": true, "Type": "AuctionBid", + "Error": null, "BaseTransactions": [ "17d25b9f2dae646c63f005abcdc6e2778f7fb9511015f2eafbd3f46c33276198", "9e979adabf0853c34a675d635a8ff7dae24f6c980780a7e5c4e21f4b6e29f575" @@ -23,6 +24,7 @@ }, "Success": true, "Type": "ContractDeploy", + "Error": null, "BaseTransactions": [ "17d25b9f2dae646c63f005abcdc6e2778f7fb9511015f2eafbd3f46c33276198" ] diff --git a/pkg/bath/testdata/tf-nominator-deposit.json b/pkg/bath/testdata/tf-nominator-deposit.json index ad0dafb8..4b359c04 100644 --- a/pkg/bath/testdata/tf-nominator-deposit.json +++ b/pkg/bath/testdata/tf-nominator-deposit.json @@ -9,6 +9,7 @@ }, "Success": true, "Type": "DepositStake", + "Error": null, "BaseTransactions": [ "1e941df6eff142f1b6e11d984e695ff90a1b975e73640f4b3a9781f5fd6a5d71" ] diff --git a/pkg/bath/testdata/tf-nominator-process-withdraw-requests.json b/pkg/bath/testdata/tf-nominator-process-withdraw-requests.json index 2fe6a277..2079a14e 100644 --- a/pkg/bath/testdata/tf-nominator-process-withdraw-requests.json +++ b/pkg/bath/testdata/tf-nominator-process-withdraw-requests.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "d6760dc8f3cbc37003f76b3e78b55613a8d81b5354cedf7ce6b2149e0e4cad85" ] @@ -25,6 +26,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "42233d9a77a59c9909fad1ccf76655efa46f60412de37cfa36dd5dd98cdb7eba" ] @@ -40,6 +42,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "1984eefa9f92e1137c442153295c61160ac5990606065285590bac249aa54775" ] diff --git a/pkg/bath/testdata/tf-nominator-request-a-withdraw.json b/pkg/bath/testdata/tf-nominator-request-a-withdraw.json index ccc84e70..798b712a 100644 --- a/pkg/bath/testdata/tf-nominator-request-a-withdraw.json +++ b/pkg/bath/testdata/tf-nominator-request-a-withdraw.json @@ -9,6 +9,7 @@ }, "Success": true, "Type": "WithdrawStakeRequest", + "Error": null, "BaseTransactions": [ "64e3d3c5020beebbf423654c305996909e89df21339a41b2f37fd40183a67205", "6eee762f4db52fcd5e797f86436cbf940c0d9b4759603be95a5fd24f145cbe22" diff --git a/pkg/bath/testdata/tf-update-validator-set.json b/pkg/bath/testdata/tf-update-validator-set.json index ab41ecc3..4cc55f61 100644 --- a/pkg/bath/testdata/tf-update-validator-set.json +++ b/pkg/bath/testdata/tf-update-validator-set.json @@ -10,6 +10,7 @@ }, "Success": true, "Type": "SmartContractExec", + "Error": null, "BaseTransactions": [ "0143cff500c883ccfd40a1a873a45a6f6168f4b0b2a9f2c9a81d6d5e8be1c41d" ] @@ -25,6 +26,7 @@ }, "Success": true, "Type": "TonTransfer", + "Error": null, "BaseTransactions": [ "890ccbb2740d15ada498270a12508afe448d64f08385b7b2d14eaca566802814" ] diff --git a/pkg/bath/testdata/tonstake-withdraw.json b/pkg/bath/testdata/tonstake-withdraw.json index a31b2d28..0c86754f 100644 --- a/pkg/bath/testdata/tonstake-withdraw.json +++ b/pkg/bath/testdata/tonstake-withdraw.json @@ -9,6 +9,7 @@ }, "Success": true, "Type": "WithdrawStake", + "Error": null, "BaseTransactions": [ "708fc31d9355864979a2c4237adb6541fd87b4fa58f553c1ae8f286dc14e1672", "fd93c25d37d1ba7033a337a12663a2a24907e6f7442463b4b97f4fda7d3422df", diff --git a/pkg/bath/testdata/wton-mint.json b/pkg/bath/testdata/wton-mint.json index ca09356b..33b20e4c 100644 --- a/pkg/bath/testdata/wton-mint.json +++ b/pkg/bath/testdata/wton-mint.json @@ -9,6 +9,7 @@ }, "Success": true, "Type": "JettonMint", + "Error": null, "BaseTransactions": [ "85f69a391a9f79a7b30f4d50371ab96f6aae9e2d30ad25eabb97e0350c1ae54a", "e8999c9ce8e675bef70edb66b69755223436e3c6c86424a20b62ca61411c87fe", diff --git a/pkg/core/converters.go b/pkg/core/converters.go index 1d5f19ea..08e8a03e 100644 --- a/pkg/core/converters.go +++ b/pkg/core/converters.go @@ -163,10 +163,10 @@ func maybeRefInvoke[Result any, T any](fn func(t T) *Result, maybe tlb.Maybe[tlb return fn(maybe.Value.Value) } -func ConvertTransaction(workchain int32, tx tongo.Transaction) (*Transaction, error) { +func ConvertTransaction(workchain int32, tx tongo.Transaction, cd *abi.ContractDescription) (*Transaction, error) { var inMsg *Message if tx.Msgs.InMsg.Exists { - msg, err := ConvertMessage(tx.Msgs.InMsg.Value.Value, tx.Lt) + msg, err := ConvertMessage(tx.Msgs.InMsg.Value.Value, tx.Lt, cd) if err != nil { return nil, err } @@ -174,7 +174,7 @@ func ConvertTransaction(workchain int32, tx tongo.Transaction) (*Transaction, er } var outMessage []Message for _, msg := range tx.Msgs.OutMsgs.Values() { - m, err := ConvertMessage(msg.Value, tx.Lt) + m, err := ConvertMessage(msg.Value, tx.Lt, cd) if err != nil { return nil, err } @@ -272,7 +272,7 @@ func ConvertTransaction(workchain int32, tx tongo.Transaction) (*Transaction, er }, nil } -func ConvertMessage(message tlb.Message, txLT uint64) (Message, error) { +func ConvertMessage(message tlb.Message, txLT uint64, cd *abi.ContractDescription) (Message, error) { init := make([]byte, 0) if message.Init.Exists { initCell := boc.NewCell() @@ -289,11 +289,15 @@ func ConvertMessage(message tlb.Message, txLT uint64) (Message, error) { if err != nil { return Message{}, err } + var ci []abi.ContractInterface + if cd != nil { + ci = cd.ContractInterfaces + } cell := boc.Cell(message.Body.Value) switch message.Info.SumType { case "IntMsgInfo": var decodedBody *DecodedMessageBody - tag, op, value, err := abi.InternalMessageDecoder(&cell, nil) + tag, op, value, err := abi.InternalMessageDecoder(&cell, ci) if err == nil && op != nil { decodedBody = &DecodedMessageBody{ Operation: *op, @@ -332,7 +336,7 @@ func ConvertMessage(message tlb.Message, txLT uint64) (Message, error) { case "ExtInMsgInfo": var decodedBody *DecodedMessageBody info := message.Info.ExtInMsgInfo - tag, op, value, err := abi.ExtInMessageDecoder(&cell, nil) + tag, op, value, err := abi.ExtInMessageDecoder(&cell, ci) if err == nil && op != nil { decodedBody = &DecodedMessageBody{ Operation: *op, @@ -361,7 +365,7 @@ func ConvertMessage(message tlb.Message, txLT uint64) (Message, error) { case "ExtOutMsgInfo": var decodedBody *DecodedMessageBody info := message.Info.ExtOutMsgInfo - tag, op, value, err := abi.ExtOutMessageDecoder(&cell, nil, info.Dest) + tag, op, value, err := abi.ExtOutMessageDecoder(&cell, ci, info.Dest) if err == nil && op != nil { decodedBody = &DecodedMessageBody{ Operation: *op, @@ -481,7 +485,7 @@ func ExtractTransactions(id tongo.BlockIDExt, block *tlb.Block) ([]*Transaction, rawTransactions := block.AllTransactions() transactions := make([]*Transaction, 0, len(rawTransactions)) for _, rawTx := range rawTransactions { - tx, err := ConvertTransaction(id.Workchain, tongo.Transaction{Transaction: *rawTx, BlockID: id}) + tx, err := ConvertTransaction(id.Workchain, tongo.Transaction{Transaction: *rawTx, BlockID: id}, nil) if err != nil { return nil, err } diff --git a/pkg/core/converters_test.go b/pkg/core/converters_test.go index 19128f20..02b1f391 100644 --- a/pkg/core/converters_test.go +++ b/pkg/core/converters_test.go @@ -105,7 +105,7 @@ func TestConvertTransaction(t *testing.T) { require.Nil(t, err) txs, err := cli.GetTransactions(context.Background(), 1, tt.accountID, tt.txLt, tt.txHash) require.Nil(t, err) - tx, err := ConvertTransaction(0, txs[0]) + tx, err := ConvertTransaction(0, txs[0], nil) require.Nil(t, err) bs, err := json.MarshalIndent(tx, " ", " ") require.Nil(t, err) diff --git a/pkg/litestorage/litestorage.go b/pkg/litestorage/litestorage.go index 2b0f37e2..b914d60a 100644 --- a/pkg/litestorage/litestorage.go +++ b/pkg/litestorage/litestorage.go @@ -198,7 +198,7 @@ func (s *LiteStorage) run(ch <-chan indexer.IDandBlock) { accountID := *ton.NewAccountID(block.ID.Workchain, tx.AccountAddr) if _, ok := s.trackingAccounts[accountID]; ok { hash := tongo.Bits256(tx.Hash()) - transaction, err := core.ConvertTransaction(accountID.Workchain, tongo.Transaction{Transaction: *tx, BlockID: block.ID}) + transaction, err := core.ConvertTransaction(accountID.Workchain, tongo.Transaction{Transaction: *tx, BlockID: block.ID}, nil) if err != nil { s.logger.Error("failed to process tx", zap.String("tx-hash", hash.Hex()), @@ -287,7 +287,13 @@ func (s *LiteStorage) preloadAccount(a tongo.AccountID) error { return err } for _, tx := range accountTxs { - t, err := core.ConvertTransaction(a.Workchain, tx) + inspector := abi.NewContractInspector(abi.InspectWithLibraryResolver(s)) + account, err := s.GetRawAccount(ctx, a) + if err != nil { + return err + } + cd, err := inspector.InspectContract(ctx, account.Code, s.executor, a) + t, err := core.ConvertTransaction(a.Workchain, tx, cd) if err != nil { return err } @@ -316,7 +322,13 @@ func (s *LiteStorage) preloadBlock(id tongo.BlockID) error { Workchain: extID.Workchain, Address: tx.AccountAddr, } - t, err := core.ConvertTransaction(extID.Workchain, tongo.Transaction{Transaction: *tx, BlockID: extID}) + inspector := abi.NewContractInspector(abi.InspectWithLibraryResolver(s)) + account, err := s.GetRawAccount(ctx, accountID) + if err != nil { + return err + } + cd, err := inspector.InspectContract(ctx, account.Code, s.executor, accountID) + t, err := core.ConvertTransaction(extID.Workchain, tongo.Transaction{Transaction: *tx, BlockID: extID}, cd) if err != nil { return err } @@ -479,7 +491,7 @@ func (s *LiteStorage) GetAccountTransactions(ctx context.Context, id tongo.Accou } result := make([]*core.Transaction, len(txs)) for i := range txs { - tx, err := core.ConvertTransaction(id.Workchain, txs[i]) + tx, err := core.ConvertTransaction(id.Workchain, txs[i], nil) if err != nil { return nil, err } diff --git a/pkg/litestorage/trace.go b/pkg/litestorage/trace.go index ba6ec051..4e06ae18 100644 --- a/pkg/litestorage/trace.go +++ b/pkg/litestorage/trace.go @@ -131,12 +131,12 @@ func (s *LiteStorage) searchTransactionInBlock(ctx context.Context, a tongo.Acco } inMsg := tx.Msgs.InMsg if !back && inMsg.Exists && inMsg.Value.Value.Info.IntMsgInfo != nil && inMsg.Value.Value.Info.IntMsgInfo.CreatedLt == lt { - return core.ConvertTransaction(a.Workchain, tongo.Transaction{BlockID: blockIDExt, Transaction: *tx}) + return core.ConvertTransaction(a.Workchain, tongo.Transaction{BlockID: blockIDExt, Transaction: *tx}, nil) } if back { for _, m := range tx.Msgs.OutMsgs.Values() { if m.Value.Info.IntMsgInfo != nil && m.Value.Info.IntMsgInfo.CreatedLt == lt { - return core.ConvertTransaction(a.Workchain, tongo.Transaction{BlockID: blockIDExt, Transaction: *tx}) + return core.ConvertTransaction(a.Workchain, tongo.Transaction{BlockID: blockIDExt, Transaction: *tx}, nil) } } }