From 26fba201585097192425b1ccadb989b73b8f7e87 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Wed, 27 Dec 2023 13:50:41 +0300 Subject: [PATCH] Extract more information from tx and msgs --- api/openapi.json | 117 ++- api/openapi.yml | 89 +++ pkg/api/account_handlers_test.go | 34 +- pkg/api/blockchain_converters.go | 47 +- pkg/api/suite_test.go | 39 + pkg/api/testdata/block-txs-1.json | 201 +++++ pkg/api/testdata/block-txs-2.json | 1095 +++++++++++++++++++++++++++ pkg/bath/bubble.go | 4 +- pkg/core/converters.go | 91 ++- pkg/core/currency.go | 28 + pkg/core/testdata/convert-tx-1.json | 31 +- pkg/core/transactions.go | 55 +- pkg/oas/oas_json_gen.go | 577 +++++++++++++- pkg/oas/oas_schemas_gen.go | 362 ++++++++- pkg/oas/oas_validators_gen.go | 74 ++ 15 files changed, 2734 insertions(+), 110 deletions(-) create mode 100644 pkg/api/suite_test.go create mode 100644 pkg/api/testdata/block-txs-1.json create mode 100644 pkg/api/testdata/block-txs-2.json create mode 100644 pkg/core/currency.go diff --git a/api/openapi.json b/api/openapi.json index 3d2e1be5..d322ca33 100644 --- a/api/openapi.json +++ b/api/openapi.json @@ -1006,11 +1006,38 @@ "format": "int64", "type": "integer" }, + "msgs_created": { + "example": 1000, + "format": "int16", + "type": "integer" + }, + "no_funds": { + "example": true, + "type": "boolean" + }, + "result_arg": { + "example": 5, + "format": "int32", + "type": "integer" + }, + "result_code": { + "example": 5, + "format": "int32", + "type": "integer" + }, "skipped_actions": { "example": 5, "format": "int32", "type": "integer" }, + "spec_actions": { + "example": 5, + "format": "int32", + "type": "integer" + }, + "status_change": { + "$ref": "#/components/schemas/AccStatusChange" + }, "success": { "example": true, "type": "boolean" @@ -1024,14 +1051,37 @@ "example": 1000, "format": "int64", "type": "integer" + }, + "total_msg_size_bits": { + "example": 1000, + "format": "int64", + "type": "integer" + }, + "total_msg_size_cells": { + "example": 3, + "format": "int64", + "type": "integer" + }, + "valid": { + "example": true, + "type": "boolean" } }, "required": [ "success", + "valid", + "no_funds", + "status_change", + "result_code", + "result_arg", "total_actions", + "spec_actions", "skipped_actions", "fwd_fees", - "total_fees" + "total_fees", + "msgs_created", + "total_msg_size_cells", + "total_msg_size_bits" ], "type": "object" }, @@ -2326,6 +2376,37 @@ ], "type": "object" }, + "BouncePhase": { + "properties": { + "bounce_type": { + "$ref": "#/components/schemas/BouncePhaseType" + }, + "fwd_fees": { + "format": "int64", + "type": "integer" + }, + "msg_fees": { + "format": "int64", + "type": "integer" + }, + "msg_size_bits": { + "format": "int64", + "type": "integer" + }, + "msg_size_cells": { + "format": "int64", + "type": "integer" + }, + "req_fwd_fees": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "bounce_type" + ], + "type": "object" + }, "BouncePhaseType": { "enum": [ "TrPhaseBounceNegfunds", @@ -2337,21 +2418,49 @@ }, "ComputePhase": { "properties": { + "account_activated": { + "example": true, + "type": "boolean" + }, + "exit_arg": { + "example": 0, + "format": "int32", + "type": "integer" + }, "exit_code": { "example": 0, "format": "int32", "type": "integer" }, + "gas_credit": { + "example": 10000, + "format": "int64", + "type": "integer" + }, "gas_fees": { "example": 1000, "format": "int64", "type": "integer" }, + "gas_limit": { + "example": 10000, + "format": "int64", + "type": "integer" + }, "gas_used": { "example": 10000, "format": "int64", "type": "integer" }, + "mode": { + "example": 0, + "format": "int8", + "type": "integer" + }, + "msg_state_used": { + "example": true, + "type": "boolean" + }, "skip_reason": { "$ref": "#/components/schemas/ComputeSkipReason" }, @@ -4747,8 +4856,12 @@ "example": "(-1,4234234,8000000000000000)", "type": "string" }, + "bounce": { + "$ref": "#/components/schemas/BouncePhase" + }, "bounce_phase": { - "$ref": "#/components/schemas/BouncePhaseType" + "$ref": "#/components/schemas/BouncePhaseType", + "deprecated": true }, "compute_phase": { "$ref": "#/components/schemas/ComputePhase" diff --git a/api/openapi.yml b/api/openapi.yml index 58cd0745..c992e925 100644 --- a/api/openapi.yml +++ b/api/openapi.yml @@ -3157,6 +3157,29 @@ components: - TrPhaseBounceNegfunds - TrPhaseBounceNofunds - TrPhaseBounceOk + BouncePhase: + type: object + required: + - bounce_type + properties: + bounce_type: + $ref: '#/components/schemas/BouncePhaseType' + msg_size_cells: + type: integer + format: int64 + msg_size_bits: + type: integer + format: int64 + req_fwd_fees: + type: integer + format: int64 + msg_fees: + type: integer + format: int64 + fwd_fees: + type: integer + format: int64 + ComputePhase: type: object required: @@ -3170,6 +3193,12 @@ components: success: type: boolean example: true + msg_state_used: + type: boolean + example: true + account_activated: + type: boolean + example: true gas_fees: type: integer format: int64 @@ -3178,6 +3207,14 @@ components: type: integer format: int64 example: 10000 + gas_credit: + type: integer + format: int64 + example: 10000 + gas_limit: + type: integer + format: int64 + example: 10000 vm_steps: type: integer format: uint32 @@ -3186,6 +3223,14 @@ components: type: integer format: int32 example: 0 + exit_arg: + type: integer + format: int32 + example: 0 + mode: + type: integer + format: int8 + example: 0 StoragePhase: type: object required: @@ -3220,18 +3265,47 @@ components: type: object required: - success + - valid + - no_funds + - status_change + - result_code + - result_arg - total_actions + - spec_actions - skipped_actions - fwd_fees - total_fees + - msgs_created + - total_msg_size_cells + - total_msg_size_bits properties: success: type: boolean example: true + valid: + type: boolean + example: true + no_funds: + type: boolean + example: true + status_change: + $ref: '#/components/schemas/AccStatusChange' + result_code: + type: integer + format: int32 + example: 5 + result_arg: + type: integer + format: int32 + example: 5 total_actions: type: integer format: int32 example: 5 + spec_actions: + type: integer + format: int32 + example: 5 skipped_actions: type: integer format: int32 @@ -3244,6 +3318,18 @@ components: type: integer format: int64 example: 1000 + msgs_created: + type: integer + format: int16 + example: 1000 + total_msg_size_cells: + type: integer + format: int64 + example: 3 + total_msg_size_bits: + type: integer + format: int64 + example: 1000 Transaction: type: object required: @@ -3320,7 +3406,10 @@ components: action_phase: $ref: '#/components/schemas/ActionPhase' bounce_phase: + deprecated: true $ref: '#/components/schemas/BouncePhaseType' + bounce: + $ref: '#/components/schemas/BouncePhase' aborted: type: boolean example: true diff --git a/pkg/api/account_handlers_test.go b/pkg/api/account_handlers_test.go index 84e080b5..3044cee0 100644 --- a/pkg/api/account_handlers_test.go +++ b/pkg/api/account_handlers_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/tonkeeper/opentonapi/pkg/chainstate" + pkgTesting "github.com/tonkeeper/opentonapi/pkg/testing" "github.com/tonkeeper/tongo/liteapi" "github.com/stretchr/testify/require" @@ -162,21 +163,20 @@ func TestHandler_GetAccounts(t *testing.T) { } func TestHandler_GetTransactions(t *testing.T) { - t.Skip() tests := []struct { - name string - params oas.GetBlockchainBlockTransactionsParams - wantTxCount int - wantTxHashes map[string]struct{} + name string + params oas.GetBlockchainBlockTransactionsParams + filenamePrefix string }{ { - params: oas.GetBlockchainBlockTransactionsParams{BlockID: "(-1,8000000000000000,28741341)"}, - wantTxCount: 3, - wantTxHashes: map[string]struct{}{ - "fec4f77e8b72eec62d14944d9cf99171a32c03783c8e6e30590aabbe35236f9b": {}, - "ed07582702c23aeaa6f1b7ce28def3a810399467a8e062ed1c67eed8c1abd2ad": {}, - "6f268d1fcd0bd36021237bb2b1810a7a78cd1d3b5e96d826ffddbcc96b848523": {}, - }, + name: "masterchain block", + params: oas.GetBlockchainBlockTransactionsParams{BlockID: "(-1,8000000000000000,28741341)"}, + filenamePrefix: "block-txs-1", + }, + { + name: "basechain block", + params: oas.GetBlockchainBlockTransactionsParams{BlockID: "(0,8000000000000000,40834551)"}, + filenamePrefix: "block-txs-2", }, } for _, tt := range tests { @@ -186,18 +186,12 @@ func TestHandler_GetTransactions(t *testing.T) { require.Nil(t, err) liteStorage, err := litestorage.NewLiteStorage(logger, cli) require.Nil(t, err) - h, err := NewHandler(logger, WithStorage(liteStorage), WithExecutor(liteStorage)) + h, err := NewHandler(logger, WithStorage(liteStorage), WithExecutor(liteStorage), WithAddressBook(&mockAddressBook{})) require.Nil(t, err) res, err := h.GetBlockchainBlockTransactions(context.Background(), tt.params) require.Nil(t, err) fmt.Printf("%v\n", res) - - require.Equal(t, tt.wantTxCount, len(res.Transactions)) - txHashes := map[string]struct{}{} - for _, tx := range res.Transactions { - txHashes[tx.Hash] = struct{}{} - } - require.Equal(t, tt.wantTxHashes, txHashes) + pkgTesting.CompareResults(t, res, tt.filenamePrefix) }) } } diff --git a/pkg/api/blockchain_converters.go b/pkg/api/blockchain_converters.go index d8722448..d2dbea3f 100644 --- a/pkg/api/blockchain_converters.go +++ b/pkg/api/blockchain_converters.go @@ -140,11 +140,20 @@ func convertTransaction(t core.Transaction, book addressBook) oas.Transaction { } if t.ActionPhase != nil { phase := oas.ActionPhase{ - Success: t.ActionPhase.Success, - TotalActions: int32(t.ActionPhase.TotalActions), - SkippedActions: int32(t.ActionPhase.SkippedActions), - FwdFees: int64(t.ActionPhase.FwdFees), - TotalFees: int64(t.ActionPhase.TotalFees), + Success: t.ActionPhase.Success, + Valid: t.ActionPhase.Valid, + NoFunds: t.ActionPhase.NoFunds, + StatusChange: oas.AccStatusChange(t.ActionPhase.StatusChange), + ResultCode: t.ActionPhase.ResultCode, + ResultArg: t.ActionPhase.ResultArg, + TotalActions: int32(t.ActionPhase.TotalActions), + SpecActions: int32(t.ActionPhase.SpecActions), + SkippedActions: int32(t.ActionPhase.SkippedActions), + FwdFees: int64(t.ActionPhase.TotalFwdFees), + TotalFees: int64(t.ActionPhase.TotalActionFees), + MsgsCreated: int16(t.ActionPhase.MsgsCreated), + TotalMsgSizeCells: t.ActionPhase.TotMsgSize.Cells, + TotalMsgSizeBits: t.ActionPhase.TotMsgSize.Bits, } tx.ActionPhase = oas.NewOptActionPhase(phase) } @@ -165,11 +174,17 @@ func convertTransaction(t core.Transaction, book addressBook) oas.Transaction { if t.ComputePhase.Skipped { phase.SkipReason = oas.NewOptComputeSkipReason(oas.ComputeSkipReason(t.ComputePhase.SkipReason)) } else { + phase.MsgStateUsed = oas.NewOptBool(t.ComputePhase.MsgStateUsed) + phase.AccountActivated = oas.NewOptBool(t.ComputePhase.AccountActivated) phase.Success = oas.NewOptBool(t.ComputePhase.Success) phase.GasFees = oas.NewOptInt64(int64(t.ComputePhase.GasFees)) - phase.GasUsed = oas.NewOptInt64(t.ComputePhase.GasUsed.Int64()) + phase.GasUsed = oas.NewOptInt64(int64(t.ComputePhase.GasUsed)) + phase.GasLimit = oas.NewOptInt64(int64(t.ComputePhase.GasLimit)) + phase.GasCredit = oas.NewOptInt64(int64(t.ComputePhase.GasCredit)) phase.VMSteps = oas.NewOptUint32(t.ComputePhase.VmSteps) phase.ExitCode = oas.NewOptInt32(t.ComputePhase.ExitCode) + phase.ExitArg = oas.NewOptInt32(t.ComputePhase.ExitArg) + phase.Mode = oas.NewOptInt8(t.ComputePhase.Mode) } tx.ComputePhase = oas.NewOptComputePhase(phase) } @@ -180,8 +195,24 @@ func convertTransaction(t core.Transaction, book addressBook) oas.Transaction { } tx.CreditPhase = oas.NewOptCreditPhase(phase) } - if t.BouncePhase != nil { - tx.BouncePhase = oas.NewOptBouncePhaseType(oas.BouncePhaseType(t.BouncePhase.Type)) + if ph := t.BouncePhase; ph != nil { + tx.BouncePhase = oas.NewOptBouncePhaseType(oas.BouncePhaseType(ph.Type)) + phase := oas.BouncePhase{ + BounceType: oas.BouncePhaseType(ph.Type), + } + if ph.MsgSize != nil { + phase.MsgSizeCells = oas.NewOptInt64(ph.MsgSize.Cells) + phase.MsgSizeBits = oas.NewOptInt64(ph.MsgSize.Bits) + } + if ph.ReqFwdFees != nil { + phase.ReqFwdFees = oas.NewOptInt64(int64(*ph.ReqFwdFees)) + } + if ph.FwdFees != nil { + phase.FwdFees = oas.NewOptInt64(int64(*ph.FwdFees)) + } + if ph.MsgFees != nil { + phase.MsgFees = oas.NewOptInt64(int64(*ph.MsgFees)) + } } return tx } diff --git a/pkg/api/suite_test.go b/pkg/api/suite_test.go new file mode 100644 index 00000000..e773a407 --- /dev/null +++ b/pkg/api/suite_test.go @@ -0,0 +1,39 @@ +package api + +import ( + "github.com/tonkeeper/opentonapi/pkg/addressbook" + "github.com/tonkeeper/tongo" +) + +type mockAddressBook struct { +} + +func (m mockAddressBook) GetAddressInfoByAddress(a tongo.AccountID) (addressbook.KnownAddress, bool) { + return addressbook.KnownAddress{}, false +} + +func (m mockAddressBook) GetCollectionInfoByAddress(a tongo.AccountID) (addressbook.KnownCollection, bool) { + return addressbook.KnownCollection{}, false +} + +func (m mockAddressBook) GetJettonInfoByAddress(a tongo.AccountID) (addressbook.KnownJetton, bool) { + return addressbook.KnownJetton{}, false +} + +func (m mockAddressBook) GetTFPoolInfo(a tongo.AccountID) (addressbook.TFPoolInfo, bool) { + return addressbook.TFPoolInfo{}, false +} + +func (m mockAddressBook) GetKnownJettons() map[tongo.AccountID]addressbook.KnownJetton { + return map[tongo.AccountID]addressbook.KnownJetton{} +} + +func (m mockAddressBook) GetKnownCollections() map[tongo.AccountID]addressbook.KnownCollection { + return map[tongo.AccountID]addressbook.KnownCollection{} +} + +func (m mockAddressBook) SearchAttachedAccountsByPrefix(prefix string) []addressbook.AttachedAccount { + return []addressbook.AttachedAccount{} +} + +var _ addressBook = &mockAddressBook{} diff --git a/pkg/api/testdata/block-txs-1.json b/pkg/api/testdata/block-txs-1.json new file mode 100644 index 00000000..e9a44940 --- /dev/null +++ b/pkg/api/testdata/block-txs-1.json @@ -0,0 +1,201 @@ +{ + "transactions": [ + { + "hash": "fec4f77e8b72eec62d14944d9cf99171a32c03783c8e6e30590aabbe35236f9b", + "lt": 36807592000001, + "account": { + "address": "-1:3333333333333333333333333333333333333333333333333333333333333333", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1681393854, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransTickTock", + "state_update_old": "728283e3b716f098ed0779fffa2b380ecf007db9b9658b9eef3ed30dbb54a4c6", + "state_update_new": "895c7f301fd8726e006e2ececb743903a6ca030dd882935bb2569f911c32a3a7", + "out_msgs": [], + "block": "(-1,8000000000000000,28741341)", + "prev_trans_hash": "af89622d86ca19507338ee6e75d115e66159f81f0fe87a84de85066ffc121bad", + "prev_trans_lt": 36807591000002, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 0, + "gas_used": 6464, + "gas_credit": 0, + "gas_limit": 35000000, + "vm_steps": 150, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 0, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 0, + "total_fees": 0, + "msgs_created": 0, + "total_msg_size_cells": 0, + "total_msg_size_bits": 0 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "ed07582702c23aeaa6f1b7ce28def3a810399467a8e062ed1c67eed8c1abd2ad", + "lt": 36807592000002, + "account": { + "address": "-1:3333333333333333333333333333333333333333333333333333333333333333", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1681393854, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransOrd", + "state_update_old": "895c7f301fd8726e006e2ececb743903a6ca030dd882935bb2569f911c32a3a7", + "state_update_new": "04b2f9070b4bf54debc1f1524ff2b14e7ff8736235fbc2f8ebc886db37d325aa", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 36807592000000, + "ihr_disabled": true, + "bounce": true, + "bounced": false, + "value": 2722504297, + "fwd_fee": 0, + "ihr_fee": 0, + "destination": { + "address": "-1:3333333333333333333333333333333333333333333333333333333333333333", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "-1:0000000000000000000000000000000000000000000000000000000000000000", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1681393854 + }, + "out_msgs": [], + "block": "(-1,8000000000000000,28741341)", + "prev_trans_hash": "fec4f77e8b72eec62d14944d9cf99171a32c03783c8e6e30590aabbe35236f9b", + "prev_trans_lt": 36807592000001, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 0, + "gas_used": 4874, + "gas_credit": 0, + "gas_limit": 272250, + "vm_steps": 100, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 2722504297 + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 0, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 0, + "total_fees": 0, + "msgs_created": 0, + "total_msg_size_cells": 0, + "total_msg_size_bits": 0 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "6f268d1fcd0bd36021237bb2b1810a7a78cd1d3b5e96d826ffddbcc96b848523", + "lt": 36807592000003, + "account": { + "address": "-1:5555555555555555555555555555555555555555555555555555555555555555", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1681393854, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransTickTock", + "state_update_old": "70e0a74209500c5c3bdf816b6c09aa510ab8cdfd8878e4c2c47c64654f5d0aa3", + "state_update_new": "0cccc8fd653c124fb45be1def0d7e38c961021173b66cf4e7a460e72bdc63e78", + "out_msgs": [], + "block": "(-1,8000000000000000,28741341)", + "prev_trans_hash": "c77a0443dec7ab27d8c5a29b81f15953d8d49001bb2575271de301b086ce09e6", + "prev_trans_lt": 36807591000003, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 0, + "gas_used": 2479, + "gas_credit": 0, + "gas_limit": 35000000, + "vm_steps": 46, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 0, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 0, + "total_fees": 0, + "msgs_created": 0, + "total_msg_size_cells": 0, + "total_msg_size_bits": 0 + }, + "aborted": false, + "destroyed": false + } + ] + } \ No newline at end of file diff --git a/pkg/api/testdata/block-txs-2.json b/pkg/api/testdata/block-txs-2.json new file mode 100644 index 00000000..12c0baaf --- /dev/null +++ b/pkg/api/testdata/block-txs-2.json @@ -0,0 +1,1095 @@ +{ + "transactions": [ + { + "hash": "e58cd7ffbbe68332d6ea082c5e91da3e88568c3891bccf552d3f8b4659d5c8ea", + "lt": 43458908000001, + "account": { + "address": "0:5c6a0dadaf3bb47d408349d06152c3d14cb3a18810e0c29a1287857a677ade70", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 15433995, + "transaction_type": "TransOrd", + "state_update_old": "fb4e010c29319feb7d9b134b0f3c8f15f4165dd92b152af62fec19af62bd4f99", + "state_update_new": "fc8edeeed5c1d972bbb6ba546b404d398b25088583cd3e4e21b78ced4b5e0b61", + "in_msg": { + "msg_type": "ext_in_msg", + "created_lt": 43458908000001, + "ihr_disabled": false, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 0, + "ihr_fee": 0, + "destination": { + "address": "0:5c6a0dadaf3bb47d408349d06152c3d14cb3a18810e0c29a1287857a677ade70", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 0, + "op_code": "0xcb6bf173", + "raw_body": "b5ee9c7201020501000104000199cb6bf17355d3b158585d6fe6522affeaad290fb180dedc4e45b2e3d4ac5ae0b4e29697c8f6e8e177927b99f33d1c7df04171b3ed012a5a9be4a4dd6d0469eb0b00000001658964dc3c7f8fb7c0010104d00302019762002e92c70cf4a6954cf9bf60080eaa5e7e76971130d96f8132c851a2dcdc5828dda00a7d8c0000000000000000000000000000000000010000385fcdfa80000000385fcdfa800034c4b40803018580118416eee1c3da556c381a0e0813efec064cc35556eed470f24d45fceaf375be300171a836b6bceed1f5020d2741854b0f4532ce862043830a684a1e15e99deb79c204003036313938343132383739343632342f6d6574612e6a736f6e" + }, + "out_msgs": [ + { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": true, + "bounce": true, + "bounced": false, + "value": 22000000, + "fwd_fee": 1284010, + "ihr_fee": 0, + "destination": { + "address": "0:5d258e19e94d2a99f37ec0101d54bcfced2e2261b2df026590a345b9b8b051bb", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:5c6a0dadaf3bb47d408349d06152c3d14cb3a18810e0c29a1287857a677ade70", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000001", + "raw_body": "b5ee9c7201010301007b00012f000000010000385fcdfa80000000385fcdfa800034c4b40801018580118416eee1c3da556c381a0e0813efec064cc35556eed470f24d45fceaf375be300171a836b6bceed1f5020d2741854b0f4532ce862043830a684a1e15e99deb79c202003036313938343132383739343632342f6d6574612e6a736f6e" + } + ], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "83c4f983c9e2aa010d4905288e6e9f03ee5447f42c45641e825a8732df42841b", + "prev_trans_lt": 43458904000001, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 12046000, + "gas_used": 12046, + "gas_credit": 10000, + "gas_limit": 0, + "vm_steps": 138, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 5, + "status_change": "acst_unchanged" + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 1, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 1926000, + "total_fees": 641990, + "msgs_created": 1, + "total_msg_size_cells": 3, + "total_msg_size_bits": 1619 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "2da9737c4da572382f7a5abfdb923f223455280089f4b627c6cb028b2b8350d2", + "lt": 43458908000001, + "account": { + "address": "0:6ccd325a858c379693fae2bcaab1c2906831a4e10a6c3bb44ee8b615bca1d220", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 5873530, + "transaction_type": "TransOrd", + "state_update_old": "69f854c6e3d695caa467e94773931cc6a5e777fb3b4cb035929348e216d5bcfd", + "state_update_new": "1ce0f4a3b70ca63490bb94c2cfc608b33e4649613927a24353753b0b9473e20f", + "in_msg": { + "msg_type": "ext_in_msg", + "created_lt": 43458908000001, + "ihr_disabled": false, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 0, + "ihr_fee": 0, + "destination": { + "address": "0:6ccd325a858c379693fae2bcaab1c2906831a4e10a6c3bb44ee8b615bca1d220", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 0, + "op_code": "0x27c987da", + "raw_body": "b5ee9c7201010201008600019c27c987da7031d58a7ad2932749b51483c4cd07b16c78722bd12519ee1b0b213df2fbd4b0aac13d34f8668e836b29ded163f153cb4e889170057bf0b73d9ddf0729a9a3176589657e00000116000301006602001679dadc6448f28be4d6eded0e01c3504e6565d871fd7b185a8e7e40a9192d5d80cb71b000000000000000000000000000" + }, + "out_msgs": [ + { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": false, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 666672, + "ihr_fee": 3000000, + "destination": { + "address": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325abb", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:6ccd325a858c379693fae2bcaab1c2906831a4e10a6c3bb44ee8b615bca1d220", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059 + } + ], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "3746abcb4a39c0ff1b9922d1133936f8f28d6d43509fcbc7b78f35bb2b9180b7", + "prev_trans_lt": 43458698000001, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 3308000, + "gas_used": 3308, + "gas_credit": 10000, + "gas_limit": 0, + "vm_steps": 68, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 202, + "status_change": "acst_unchanged" + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 1, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 4000000, + "total_fees": 333328, + "msgs_created": 1, + "total_msg_size_cells": 1, + "total_msg_size_bits": 697 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "241c3741bccafe2027ade117ce290a5b5274b72cbb3372fcc1c5fcd682c396ec", + "lt": 43458908000001, + "account": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 9908633, + "transaction_type": "TransOrd", + "state_update_old": "20ee1816b96d2b0265ae29e6951ed38211152e69ad8cb193c7a4925a326a628f", + "state_update_new": "6d50a0d77efd01cfe6c7e270da992bb2b26465072082a780e6d4d869d51bd85e", + "in_msg": { + "msg_type": "ext_in_msg", + "created_lt": 43458908000001, + "ihr_disabled": false, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 0, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 0, + "op_code": "0x3c7c74f7", + "raw_body": "b5ee9c720101030100e30004a23c7c74f73de44f553c1076bb92cc4b74139f9a43ba91368da25d1dbb679133298f244fca284858fedfbf8aded3f919080a0adc2bf3f5378dc62cbf93981e900529a9a3176589650a000006b0000101010101010101016042004f1ec29e07b11ca929e9d9221b95a3cca985a5f296746da36718f9478fa8277380000000000000000000000000010200ae00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d" + }, + "out_msgs": [ + { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + { + "msg_type": "int_msg", + "created_lt": 43458908000003, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + { + "msg_type": "int_msg", + "created_lt": 43458908000004, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + { + "msg_type": "int_msg", + "created_lt": 43458908000005, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + } + ], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "de0e0dae8975608b1d49a41faafb15bc5630e3e9116c00232a7c9f418980eaf2", + "prev_trans_lt": 43458903000009, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 5234000, + "gas_used": 5234, + "gas_credit": 10000, + "gas_limit": 0, + "vm_steps": 92, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 5, + "status_change": "acst_unchanged" + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 4, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 7184000, + "total_fees": 2394628, + "msgs_created": 4, + "total_msg_size_cells": 8, + "total_msg_size_bits": 5476 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "e535803d524af1c7335cb5afb3c4a7cafbb3b59f875d9af3870c8a92f0a482a2", + "lt": 43458908000001, + "account": { + "address": "0:ef59caea6ebbee8542839162aa654b76f416e712ce22752da647d7e22cf1097f", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 5844004, + "transaction_type": "TransOrd", + "state_update_old": "1dfabc37b6c750b787128457f28c91b00a8635e5cd860d24f0886365eca48b6d", + "state_update_new": "ed8de1c20ef85845443f10b43b0b13c03bec82a5b730cf7c95a29d884e6da78a", + "in_msg": { + "msg_type": "ext_in_msg", + "created_lt": 43458908000001, + "ihr_disabled": false, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 0, + "ihr_fee": 0, + "destination": { + "address": "0:ef59caea6ebbee8542839162aa654b76f416e712ce22752da647d7e22cf1097f", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 0, + "op_code": "0xc0b8e554", + "raw_body": "b5ee9c720101030100bb00019cc0b8e5545fcb0a3bdbb0558902df45d34ed5f72ad9625d809ff83555ea9baea5cc4092f703e8ddff1dedd50a97211fed34391b663b896b72abec8d63d6449a0629a9a3176589650b00000c8900030101b842002046d1d945b6032d2c9f081c8934dd554e2fc6575e0634ecf8555dd5954c92b5a80a21fe8000000000000000000000000000000000000054656c656772616d205072656d69756d20666f722033206d6f6e746873200a0a526566020012236852326179717150" + }, + "out_msgs": [ + { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 5440000000, + "fwd_fee": 1056009, + "ihr_fee": 0, + "destination": { + "address": "0:408da3b28b6c065a593e10391269baaa9c5f8caebc0c69d9f0aabbab2a99256b", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:ef59caea6ebbee8542839162aa654b76f416e712ce22752da647d7e22cf1097f", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "b5ee9c7201010201003500014e0000000054656c656772616d205072656d69756d20666f722033206d6f6e746873200a0a526566010012236852326179717150", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "Telegram Premium for 3 months \n\nRef#hR2ayqqP" + } + } + ], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "69618710c097ea4e8f3270b85a2eaf5a67703f706f96bd4149362723ced920af", + "prev_trans_lt": 43458896000001, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 3308000, + "gas_used": 3308, + "gas_credit": 10000, + "gas_limit": 0, + "vm_steps": 68, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 13, + "status_change": "acst_unchanged" + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 1, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 1584000, + "total_fees": 527991, + "msgs_created": 1, + "total_msg_size_cells": 3, + "total_msg_size_bits": 1097 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "0916cd818bacdf7b23a1c75dd3940f0dfe7a815162a58bddd32124c229efd56a", + "lt": 43458908000003, + "account": { + "address": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325abb", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "uninit", + "end_status": "uninit", + "total_fees": 8, + "transaction_type": "TransOrd", + "state_update_old": "270708db7a57598af7d4cf4a2d31a2880da5bc759b4616b25ee8a02cf4b04d51", + "state_update_new": "6ad4ecea2541a238b59266ca9a6f638cdbb36f7898aeed59224ebd5230312953", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": false, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 666672, + "ihr_fee": 3000000, + "destination": { + "address": "0:2cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325abb", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:6ccd325a858c379693fae2bcaab1c2906831a4e10a6c3bb44ee8b615bca1d220", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059 + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "7d38056b88eb4777cd9254e1d373d0e3ca60d1ea3ae1d4ab63d9cd5104809d41", + "prev_trans_lt": 43458698000003, + "compute_phase": { + "skipped": true, + "skip_reason": "cskip_no_state" + }, + "storage_phase": { + "fees_collected": 8, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 3000000 + }, + "aborted": true, + "destroyed": false + }, + { + "hash": "1bb443f1ca90d6f4d9ab7bc62fea6b133d49bbffba040964ba858beb632656a8", + "lt": 43458908000003, + "account": { + "address": "0:408da3b28b6c065a593e10391269baaa9c5f8caebc0c69d9f0aabbab2a99256b", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 100002, + "transaction_type": "TransOrd", + "state_update_old": "8bd59004e47c7d1d9605c098e41101607cc4a817c8862c7030751705a008e200", + "state_update_new": "84487059fe162eeb85175326dfb891fa194937a76c50589df3c93d3da13f32e0", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 5440000000, + "fwd_fee": 1056009, + "ihr_fee": 0, + "destination": { + "address": "0:408da3b28b6c065a593e10391269baaa9c5f8caebc0c69d9f0aabbab2a99256b", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:ef59caea6ebbee8542839162aa654b76f416e712ce22752da647d7e22cf1097f", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "b5ee9c7201010201003500014e0000000054656c656772616d205072656d69756d20666f722033206d6f6e746873200a0a526566010012236852326179717150", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "Telegram Premium for 3 months \n\nRef#hR2ayqqP" + } + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "13a57613681e1cbd13fff32f2c95bac72b0814c73d9f111d7da7d304921b11b9", + "prev_trans_lt": 43458901000003, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 100000, + "gas_used": 62, + "gas_credit": 0, + "gas_limit": 1000000, + "vm_steps": 3, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 2, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 5440000000 + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 0, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 0, + "total_fees": 0, + "msgs_created": 0, + "total_msg_size_cells": 0, + "total_msg_size_bits": 0 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "3bc1b460f988c907c3d294a869f5e8b755568c5d9f90c0031e6834faa7f72cc1", + "lt": 43458908000003, + "account": { + "address": "0:5d258e19e94d2a99f37ec0101d54bcfced2e2261b2df026590a345b9b8b051bb", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 10038288, + "transaction_type": "TransOrd", + "state_update_old": "27687753f081608ed0090fd422e67bea61a937759a23156c064e85abdfc2e7f7", + "state_update_new": "1af62b8b7e5b657afdad1e4d0ef332b693b2dcf91c09979df12a9c99f1582f5c", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": true, + "bounce": true, + "bounced": false, + "value": 22000000, + "fwd_fee": 1284010, + "ihr_fee": 0, + "destination": { + "address": "0:5d258e19e94d2a99f37ec0101d54bcfced2e2261b2df026590a345b9b8b051bb", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:5c6a0dadaf3bb47d408349d06152c3d14cb3a18810e0c29a1287857a677ade70", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000001", + "raw_body": "b5ee9c7201010301007b00012f000000010000385fcdfa80000000385fcdfa800034c4b40801018580118416eee1c3da556c381a0e0813efec064cc35556eed470f24d45fceaf375be300171a836b6bceed1f5020d2741854b0f4532ce862043830a684a1e15e99deb79c202003036313938343132383739343632342f6d6574612e6a736f6e" + }, + "out_msgs": [ + { + "msg_type": "int_msg", + "created_lt": 43458908000004, + "ihr_disabled": true, + "bounce": true, + "bounced": false, + "value": 5000000, + "fwd_fee": 7002721, + "ihr_fee": 0, + "destination": { + "address": "0:1ed2b620da9cfd71e78aabbc3ea2e860fb37c69b87eeaf460845e27a77498808", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:5d258e19e94d2a99f37ec0101d54bcfced2e2261b2df026590a345b9b8b051bb", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x80118416", + "init": { + "boc": "b5ee9c720102150100036f0002013401020114ff00f4a413f4bcf2c80b0300530000385fcdfa8000800ba4b1c33d29a5533e6fd80203aa979f9da5c44c365be04cb21468b737160a377002016204050202ce060702012013140201200809020120111204b90c8871c02497c0f83434c0c05c6c2497c0f83e903e900c7e800c5c75c87e800c7e800c1cea6d003c00816cf8c081f4c7f4cfe08417f30f45148c2ea3a28c8412040dc409841140b820840bf2c9a8948c2eb8c0a0840701104a948c2ea00a0b0c0d00113e910c1c2ebcb8536000d25b6c22345232c705f2e19501fa40d4fa4025103554443601f00321c701c0008e4401fa00218e3a821005138d9170c85006cf1658cf161034413073708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00925f04e2925f03e201f65136c705f2e191fa4021f001fa40d20031fa00820afaf0801ca121945315a0a1de22d70b01c300209206a19136e220c2fff2e192218e3e821005138d91c8500acf16500ccf1671244a145446b0708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00105894102b385be20e0080135f03333334347082108b77173504c8cbff58cf164430128040708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00015e8e8a32104810371026104502e03136373782101a0b9d5116ba9e5131c705f2e19a01d4304400f003e05f06840ff2f00f0082028e3527f0018210d53276db103845006d71708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb0093303335e25503f00301f65134c705f2e191fa4021f001fa40d20031fa00820afaf0801ca121945315a0a1de22d70b01c300209206a19136e220c2fff2e192218e3e8210511a4463c85008cf16500ccf1671244814544690708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00103894102b365be2100082028e3527f0018210d53276db103848006d71708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb0093303630e25503f00300413b513434cffe900835d27080271fc07e90353e900c040d440d380c1c165b5b5b600025013232cfd400f3c58073c5b30073c5b27b5520000dbf03a78013628c000bbc7e7f801184" + }, + "raw_body": "b5ee9c7201010201006000018580118416eee1c3da556c381a0e0813efec064cc35556eed470f24d45fceaf375be300171a836b6bceed1f5020d2741854b0f4532ce862043830a684a1e15e99deb79c201003036313938343132383739343632342f6d6574612e6a736f6e" + } + ], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "f9c5b1488265eaca1378f9dea7c28599cfe4f76d58ef9688892b39849d47de31", + "prev_trans_lt": 43458904000003, + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 6537000, + "gas_used": 6537, + "gas_credit": 0, + "gas_limit": 22000, + "vm_steps": 120, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 9, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 22000000 + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 1, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 10504000, + "total_fees": 3501279, + "msgs_created": 1, + "total_msg_size_cells": 24, + "total_msg_size_bits": 7902 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "911dc08d4fec452f14ca0e3f8929431bc74fe0cbe980c3f111c4b99895d58b25", + "lt": 43458908000005, + "account": { + "address": "0:1ed2b620da9cfd71e78aabbc3ea2e860fb37c69b87eeaf460845e27a77498808", + "is_scam": false, + "is_wallet": false + }, + "success": true, + "utime": 1703503059, + "orig_status": "nonexist", + "end_status": "active", + "total_fees": 3611000, + "transaction_type": "TransOrd", + "state_update_old": "90aec8965afabb16ebc3cb9b408ebae71b618d78788bc80d09843593cac98da4", + "state_update_new": "02e2f6aa564f87d333e2cc90bcc581780fa81f4791ff01717a622b85b957b7e1", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000004, + "ihr_disabled": true, + "bounce": true, + "bounced": false, + "value": 5000000, + "fwd_fee": 7002721, + "ihr_fee": 0, + "destination": { + "address": "0:1ed2b620da9cfd71e78aabbc3ea2e860fb37c69b87eeaf460845e27a77498808", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:5d258e19e94d2a99f37ec0101d54bcfced2e2261b2df026590a345b9b8b051bb", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x80118416", + "init": { + "boc": "b5ee9c720102150100036f0002013401020114ff00f4a413f4bcf2c80b0300530000385fcdfa8000800ba4b1c33d29a5533e6fd80203aa979f9da5c44c365be04cb21468b737160a377002016204050202ce060702012013140201200809020120111204b90c8871c02497c0f83434c0c05c6c2497c0f83e903e900c7e800c5c75c87e800c7e800c1cea6d003c00816cf8c081f4c7f4cfe08417f30f45148c2ea3a28c8412040dc409841140b820840bf2c9a8948c2eb8c0a0840701104a948c2ea00a0b0c0d00113e910c1c2ebcb8536000d25b6c22345232c705f2e19501fa40d4fa4025103554443601f00321c701c0008e4401fa00218e3a821005138d9170c85006cf1658cf161034413073708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00925f04e2925f03e201f65136c705f2e191fa4021f001fa40d20031fa00820afaf0801ca121945315a0a1de22d70b01c300209206a19136e220c2fff2e192218e3e821005138d91c8500acf16500ccf1671244a145446b0708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00105894102b385be20e0080135f03333334347082108b77173504c8cbff58cf164430128040708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00015e8e8a32104810371026104502e03136373782101a0b9d5116ba9e5131c705f2e19a01d4304400f003e05f06840ff2f00f0082028e3527f0018210d53276db103845006d71708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb0093303335e25503f00301f65134c705f2e191fa4021f001fa40d20031fa00820afaf0801ca121945315a0a1de22d70b01c300209206a19136e220c2fff2e192218e3e8210511a4463c85008cf16500ccf1671244814544690708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb00103894102b365be2100082028e3527f0018210d53276db103848006d71708010c8cb055007cf165005fa0215cb6a12cb1fcb3f226eb39458cf17019132e201c901fb0093303630e25503f00300413b513434cffe900835d27080271fc07e90353e900c040d440d380c1c165b5b5b600025013232cfd400f3c58073c5b30073c5b27b5520000dbf03a78013628c000bbc7e7f801184" + }, + "raw_body": "b5ee9c7201010201006000018580118416eee1c3da556c381a0e0813efec064cc35556eed470f24d45fceaf375be300171a836b6bceed1f5020d2741854b0f4532ce862043830a684a1e15e99deb79c201003036313938343132383739343632342f6d6574612e6a736f6e" + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "compute_phase": { + "skipped": false, + "success": true, + "msg_state_used": false, + "account_activated": false, + "gas_fees": 3611000, + "gas_used": 3611, + "gas_credit": 0, + "gas_limit": 5000, + "vm_steps": 91, + "exit_code": 0, + "exit_arg": 0, + "mode": 0 + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 5000000 + }, + "action_phase": { + "success": true, + "valid": true, + "no_funds": false, + "status_change": "acst_unchanged", + "result_code": 0, + "result_arg": 0, + "total_actions": 0, + "spec_actions": 0, + "skipped_actions": 0, + "fwd_fees": 0, + "total_fees": 0, + "msgs_created": 0, + "total_msg_size_cells": 0, + "total_msg_size_bits": 0 + }, + "aborted": false, + "destroyed": false + }, + { + "hash": "05c7c2c2db0f04ddd39af1c46b90a4901fdf743b05a7dd0ad6439b42d907a464", + "lt": 43458908000006, + "account": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "success": false, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransOrd", + "state_update_old": "6d50a0d77efd01cfe6c7e270da992bb2b26465072082a780e6d4d869d51bd85e", + "state_update_new": "789fc030d759313852cf231e36d8f4a5ec30f86a13e614edc31bb68aa6bd25cb", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000002, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "241c3741bccafe2027ade117ce290a5b5274b72cbb3372fcc1c5fcd682c396ec", + "prev_trans_lt": 43458908000001, + "compute_phase": { + "skipped": true, + "skip_reason": "cskip_no_gas" + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 0 + }, + "aborted": true, + "destroyed": false + }, + { + "hash": "5f2e3cca271bca8b3d7d9519a6fe65967af8fcc81cdb60a183f6b08c4dc6141b", + "lt": 43458908000007, + "account": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "success": false, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransOrd", + "state_update_old": "789fc030d759313852cf231e36d8f4a5ec30f86a13e614edc31bb68aa6bd25cb", + "state_update_new": "5a39dc058823ed42f16c61a7235a300ab210187f722f24ae39143128063fca7d", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000003, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "05c7c2c2db0f04ddd39af1c46b90a4901fdf743b05a7dd0ad6439b42d907a464", + "prev_trans_lt": 43458908000006, + "compute_phase": { + "skipped": true, + "skip_reason": "cskip_no_gas" + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 0 + }, + "aborted": true, + "destroyed": false + }, + { + "hash": "76942e5b100a34b17080d37f2aea19c4ae5b09da88853b9c5a377586f746740c", + "lt": 43458908000008, + "account": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "success": false, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransOrd", + "state_update_old": "5a39dc058823ed42f16c61a7235a300ab210187f722f24ae39143128063fca7d", + "state_update_new": "5ca05f8920b19ad50138336ef45af6f7659962dc9b95915d9efa47993ba8d096", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000004, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "5f2e3cca271bca8b3d7d9519a6fe65967af8fcc81cdb60a183f6b08c4dc6141b", + "prev_trans_lt": 43458908000007, + "compute_phase": { + "skipped": true, + "skip_reason": "cskip_no_gas" + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 0 + }, + "aborted": true, + "destroyed": false + }, + { + "hash": "b58464659054a4f74300282b4f9c58173d55866f29793395517ead0783e3db09", + "lt": 43458908000009, + "account": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "success": false, + "utime": 1703503059, + "orig_status": "active", + "end_status": "active", + "total_fees": 0, + "transaction_type": "TransOrd", + "state_update_old": "5ca05f8920b19ad50138336ef45af6f7659962dc9b95915d9efa47993ba8d096", + "state_update_new": "c6ea24370ff04f875b7dcca18b4a3936a1747a2ae053c466bcbba16e22539c01", + "in_msg": { + "msg_type": "int_msg", + "created_lt": 43458908000005, + "ihr_disabled": true, + "bounce": false, + "bounced": false, + "value": 0, + "fwd_fee": 1197343, + "ihr_fee": 0, + "destination": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "source": { + "address": "0:9e3d853c0f62395253d3b244372b4799530b4be52ce8db46ce31f28f1f504ee7", + "is_scam": false, + "is_wallet": false + }, + "import_fee": 0, + "created_at": 1703503059, + "op_code": "0x00000000", + "raw_body": "00000000646174613a6170706c69636174696f6e2f6a736f6e2c7b2270223a22746f6e2d3230222c226f70223a226d696e74222c227469636b223a22646f6765222c22616d74223a22313030303030303030303030227d", + "decoded_op_name": "text_comment", + "decoded_body": { + "text": "data:application/json,{\"p\":\"ton-20\",\"op\":\"mint\",\"tick\":\"doge\",\"amt\":\"100000000000\"}" + } + }, + "out_msgs": [], + "block": "(0,8000000000000000,40834551)", + "prev_trans_hash": "76942e5b100a34b17080d37f2aea19c4ae5b09da88853b9c5a377586f746740c", + "prev_trans_lt": 43458908000008, + "compute_phase": { + "skipped": true, + "skip_reason": "cskip_no_gas" + }, + "storage_phase": { + "fees_collected": 0, + "status_change": "acst_unchanged" + }, + "credit_phase": { + "fees_collected": 0, + "credit": 0 + }, + "aborted": true, + "destroyed": false + } + ] + } \ No newline at end of file diff --git a/pkg/bath/bubble.go b/pkg/bath/bubble.go index de83aa39..7cc2a6b9 100644 --- a/pkg/bath/bubble.go +++ b/pkg/bath/bubble.go @@ -110,8 +110,8 @@ func fromTrace(trace *core.Trace) *Bubble { b.Children[i] = fromTrace(c) } if actionPhase := trace.Transaction.ActionPhase; actionPhase != nil { - aggregatedFee += int64(actionPhase.FwdFees) - aggregatedFee -= int64(actionPhase.TotalFees) + aggregatedFee += int64(actionPhase.TotalFwdFees) + aggregatedFee -= int64(actionPhase.TotalActionFees) } contractDeployed := trace.EndStatus == tlb.AccountActive && trace.OrigStatus != tlb.AccountActive if contractDeployed { diff --git a/pkg/core/converters.go b/pkg/core/converters.go index dc3d8bca..1d7a5a94 100644 --- a/pkg/core/converters.go +++ b/pkg/core/converters.go @@ -92,19 +92,39 @@ func convertComputePhase(phase tlb.TrComputePhase) *TxComputePhase { SkipReason: phase.TrPhaseComputeSkipped.Reason, } default: - return &TxComputePhase{ - Success: phase.TrPhaseComputeVm.Success, - GasFees: uint64(phase.TrPhaseComputeVm.GasFees), - GasUsed: big.Int(phase.TrPhaseComputeVm.Vm.GasUsed), - VmSteps: phase.TrPhaseComputeVm.Vm.VmSteps, - ExitCode: phase.TrPhaseComputeVm.Vm.ExitCode, + gasUsed := big.Int(phase.TrPhaseComputeVm.Vm.GasUsed) + gasLimit := big.Int(phase.TrPhaseComputeVm.Vm.GasLimit) + ph := &TxComputePhase{ + Success: phase.TrPhaseComputeVm.Success, + MsgStateUsed: phase.TrPhaseComputeVm.MsgStateUsed, + AccountActivated: phase.TrPhaseComputeVm.AccountActivated, + GasFees: uint64(phase.TrPhaseComputeVm.GasFees), + GasUsed: gasUsed.Uint64(), + GasLimit: gasLimit.Uint64(), + Mode: phase.TrPhaseComputeVm.Vm.Mode, + VmSteps: phase.TrPhaseComputeVm.Vm.VmSteps, + ExitCode: phase.TrPhaseComputeVm.Vm.ExitCode, + // gas credit and exit args are optional + // if not set, they are zero + // according to https://github.com/ton-blockchain/ton/blob/v2023.10/crypto/block/transaction.cpp#L2372 + GasCredit: 0, + ExitArg: 0, + } + if phase.TrPhaseComputeVm.Vm.GasCredit.Exists { + credit := big.Int(phase.TrPhaseComputeVm.Vm.GasCredit.Value) + ph.GasCredit = credit.Uint64() + } + if phase.TrPhaseComputeVm.Vm.ExitArg.Exists { + ph.ExitArg = phase.TrPhaseComputeVm.Vm.ExitArg.Value } + return ph } } func convertCreditPhase(phase tlb.TrCreditPhase) *TxCreditPhase { ph := TxCreditPhase{ CreditGrams: uint64(phase.Credit.Grams), + CreditExtra: ToExtraCurrency(phase.Credit.Other), } if phase.DueFeesCollected.Exists { ph.DueFeesCollected = uint64(phase.DueFeesCollected.Value) @@ -125,18 +145,58 @@ func convertStoragePhase(phase tlb.TrStoragePhase) *TxStoragePhase { } func convertActionPhase(phase tlb.TrActionPhase) *TxActionPhase { + cells := big.Int(phase.TotMsgSize.Cells) + bits := big.Int(phase.TotMsgSize.Bits) return &TxActionPhase{ - Success: phase.Success, - TotalActions: phase.TotActions, - SkippedActions: phase.SkippedActions, - FwdFees: uint64(phase.TotalFwdFees.Value), - TotalFees: uint64(phase.TotalActionFees.Value), + Success: phase.Success, + Valid: phase.Valid, + NoFunds: phase.NoFunds, + StatusChange: phase.StatusChange, + ResultCode: phase.ResultCode, + ResultArg: phase.ResultArg.Value, // zero is not serialized, so if it is not set, it is zero. + TotalActions: phase.TotActions, + SpecActions: phase.SpecActions, + SkippedActions: phase.SkippedActions, + TotalFwdFees: uint64(phase.TotalFwdFees.Value), + TotalActionFees: uint64(phase.TotalActionFees.Value), + MsgsCreated: phase.MsgsCreated, + TotMsgSize: StorageUsedShort{ + Cells: cells.Int64(), + Bits: bits.Int64(), + }, } } func convertBouncePhase(phase tlb.TrBouncePhase) *TxBouncePhase { - return &TxBouncePhase{ - Type: BouncePhaseType(phase.SumType), + switch phase.SumType { + case "TrPhaseBounceNegfunds": + return &TxBouncePhase{ + Type: BounceNegFunds, + } + case "TrPhaseBounceNofunds": + cells := big.Int(phase.TrPhaseBounceNofunds.MsgSize.Cells) + bits := big.Int(phase.TrPhaseBounceNofunds.MsgSize.Bits) + return &TxBouncePhase{ + Type: BounceNoFunds, + ReqFwdFees: g.Pointer(uint64(phase.TrPhaseBounceNofunds.ReqFwdFees)), + MsgSize: &StorageUsedShort{ + Cells: cells.Int64(), + Bits: bits.Int64(), + }, + } + case "TrPhaseBounceOk": + cells := big.Int(phase.TrPhaseBounceNofunds.MsgSize.Cells) + bits := big.Int(phase.TrPhaseBounceNofunds.MsgSize.Bits) + return &TxBouncePhase{ + Type: BounceOk, + MsgFees: g.Pointer(uint64(phase.TrPhaseBounceOk.MsgFees)), + FwdFees: g.Pointer(uint64(phase.TrPhaseBounceOk.FwdFees)), + MsgSize: &StorageUsedShort{ + Cells: cells.Int64(), + Bits: bits.Int64(), + }, + } } + panic("invalid bounce phase") } func maybeInvoke[Result any, T any](fn func(t T) *Result, maybe tlb.Maybe[T]) *Result { @@ -221,8 +281,8 @@ func ConvertTransaction(workchain int32, tx tongo.Transaction) (*Transaction, er } aggregatedFee := int64(tx.TotalFees.Grams) if actionPhase != nil { - aggregatedFee += int64(actionPhase.FwdFees) - aggregatedFee -= int64(actionPhase.TotalFees) + aggregatedFee += int64(actionPhase.TotalFwdFees) + aggregatedFee -= int64(actionPhase.TotalActionFees) } var storageFee int64 if storagePhase != nil { @@ -239,6 +299,7 @@ func ConvertTransaction(workchain int32, tx tongo.Transaction) (*Transaction, er Type: TransactionType(desc.SumType), StorageFee: storageFee, TotalFee: int64(tx.TotalFees.Grams), + TotalFeeExtra: ToExtraCurrency(tx.TotalFees.Other), Utime: int64(tx.Now), InMsg: inMsg, OutMsgs: outMessage, diff --git a/pkg/core/currency.go b/pkg/core/currency.go new file mode 100644 index 00000000..18b66e64 --- /dev/null +++ b/pkg/core/currency.go @@ -0,0 +1,28 @@ +package core + +import ( + "fmt" + "math/big" + + "github.com/tonkeeper/tongo/tlb" +) + +// ExtraCurrency represents Other part of tlb.CurrencyCollection +// and it is a collection of currencies that are not Grams. +type ExtraCurrency map[string]string + +func ToExtraCurrency(collection tlb.ExtraCurrencyCollection) ExtraCurrency { + if len(collection.Dict.Keys()) == 0 { + return nil + } + res := make(ExtraCurrency, len(collection.Dict.Keys())) + for _, item := range collection.Dict.Items() { + value := big.Int(item.Value) + res[fmt.Sprintf("%d", item.Key)] = value.String() + } + return res +} + +func (c ExtraCurrency) IsNotEmpty() bool { + return len(c) > 0 +} diff --git a/pkg/core/testdata/convert-tx-1.json b/pkg/core/testdata/convert-tx-1.json index 82479282..6c9e9e3e 100644 --- a/pkg/core/testdata/convert-tx-1.json +++ b/pkg/core/testdata/convert-tx-1.json @@ -76,10 +76,16 @@ "Skipped": false, "SkipReason": "", "Success": true, + "MsgStateUsed": false, + "AccountActivated": false, "GasFees": 6400000, "GasUsed": 6400, - "VmSteps": 116, - "ExitCode": 0 + "GasLimit": 50000, + "GasCredit": 0, + "Mode": 0, + "ExitCode": 0, + "ExitArg": 0, + "VmSteps": 116 }, "StoragePhase": { "StorageFeesCollected": 126, @@ -88,18 +94,31 @@ }, "CreditPhase": { "DueFeesCollected": 0, - "CreditGrams": 50000000 + "CreditGrams": 50000000, + "CreditExtra": null }, "ActionPhase": { "Success": true, + "Valid": true, + "NoFunds": false, + "StatusChange": "acst_unchanged", + "ResultCode": 0, + "ResultArg": 0, "TotalActions": 1, + "SpecActions": 0, "SkippedActions": 0, - "FwdFees": 10134000, - "TotalFees": 3377948 + "TotalFwdFees": 10134000, + "TotalActionFees": 3377948, + "MsgsCreated": 1, + "TotMsgSize": { + "Cells": 22, + "Bits": 7740 + } }, "BouncePhase": null, "Aborted": false, "Destroyed": false, "StorageFee": 126, - "TotalFee": 9778074 + "TotalFee": 9778074, + "TotalFeeExtra": null } \ No newline at end of file diff --git a/pkg/core/transactions.go b/pkg/core/transactions.go index 7bb65292..8cbbc084 100644 --- a/pkg/core/transactions.go +++ b/pkg/core/transactions.go @@ -1,8 +1,6 @@ package core import ( - "math/big" - "github.com/tonkeeper/tongo/boc" "github.com/tonkeeper/tongo/abi" @@ -39,13 +37,19 @@ type TxComputeSkipReason = tlb.ComputeSkipReason type TxAccStatusChange = tlb.AccStatusChange type TxComputePhase struct { - Skipped bool - SkipReason TxComputeSkipReason - Success bool - GasFees uint64 - GasUsed big.Int - VmSteps uint32 - ExitCode int32 + Skipped bool + SkipReason TxComputeSkipReason + Success bool + MsgStateUsed bool + AccountActivated bool + GasFees uint64 + GasUsed uint64 + GasLimit uint64 + GasCredit uint64 + Mode int8 + ExitCode int32 + ExitArg int32 + VmSteps uint32 } type TxStoragePhase struct { @@ -57,18 +61,36 @@ type TxStoragePhase struct { type TxCreditPhase struct { DueFeesCollected uint64 CreditGrams uint64 + CreditExtra ExtraCurrency } type TxActionPhase struct { - Success bool - TotalActions uint16 - SkippedActions uint16 - FwdFees uint64 - TotalFees uint64 + Success bool + Valid bool + NoFunds bool + StatusChange TxAccStatusChange + ResultCode int32 + ResultArg int32 + TotalActions uint16 + SpecActions uint16 + SkippedActions uint16 + TotalFwdFees uint64 + TotalActionFees uint64 + MsgsCreated uint16 + TotMsgSize StorageUsedShort +} + +type StorageUsedShort struct { + Cells int64 + Bits int64 } type TxBouncePhase struct { - Type BouncePhaseType + Type BouncePhaseType + MsgSize *StorageUsedShort // BounceNofunds + BounceOk + ReqFwdFees *uint64 // BounceNofunds + MsgFees *uint64 // BounceOk + FwdFees *uint64 // BounceOk } type BouncePhaseType string @@ -106,7 +128,8 @@ type Transaction struct { // StorageFee collected during the Storage Phase. StorageFee int64 // TotalFee is the original total_fee of a transaction directly from the blockchain. - TotalFee int64 + TotalFee int64 + TotalFeeExtra ExtraCurrency } type MessageID struct { diff --git a/pkg/oas/oas_json_gen.go b/pkg/oas/oas_json_gen.go index 77d6c697..8053e656 100644 --- a/pkg/oas/oas_json_gen.go +++ b/pkg/oas/oas_json_gen.go @@ -2015,10 +2015,34 @@ func (s *ActionPhase) encodeFields(e *jx.Encoder) { e.FieldStart("success") e.Bool(s.Success) } + { + e.FieldStart("valid") + e.Bool(s.Valid) + } + { + e.FieldStart("no_funds") + e.Bool(s.NoFunds) + } + { + e.FieldStart("status_change") + s.StatusChange.Encode(e) + } + { + e.FieldStart("result_code") + e.Int32(s.ResultCode) + } + { + e.FieldStart("result_arg") + e.Int32(s.ResultArg) + } { e.FieldStart("total_actions") e.Int32(s.TotalActions) } + { + e.FieldStart("spec_actions") + e.Int32(s.SpecActions) + } { e.FieldStart("skipped_actions") e.Int32(s.SkippedActions) @@ -2031,14 +2055,35 @@ func (s *ActionPhase) encodeFields(e *jx.Encoder) { e.FieldStart("total_fees") e.Int64(s.TotalFees) } + { + e.FieldStart("msgs_created") + e.Int16(s.MsgsCreated) + } + { + e.FieldStart("total_msg_size_cells") + e.Int64(s.TotalMsgSizeCells) + } + { + e.FieldStart("total_msg_size_bits") + e.Int64(s.TotalMsgSizeBits) + } } -var jsonFieldsNameOfActionPhase = [5]string{ - 0: "success", - 1: "total_actions", - 2: "skipped_actions", - 3: "fwd_fees", - 4: "total_fees", +var jsonFieldsNameOfActionPhase = [14]string{ + 0: "success", + 1: "valid", + 2: "no_funds", + 3: "status_change", + 4: "result_code", + 5: "result_arg", + 6: "total_actions", + 7: "spec_actions", + 8: "skipped_actions", + 9: "fwd_fees", + 10: "total_fees", + 11: "msgs_created", + 12: "total_msg_size_cells", + 13: "total_msg_size_bits", } // Decode decodes ActionPhase from json. @@ -2046,7 +2091,7 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { if s == nil { return errors.New("invalid: unable to decode ActionPhase to nil") } - var requiredBitSet [1]uint8 + var requiredBitSet [2]uint8 if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { @@ -2062,8 +2107,66 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"success\"") } - case "total_actions": + case "valid": requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Bool() + s.Valid = bool(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"valid\"") + } + case "no_funds": + requiredBitSet[0] |= 1 << 2 + if err := func() error { + v, err := d.Bool() + s.NoFunds = bool(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"no_funds\"") + } + case "status_change": + requiredBitSet[0] |= 1 << 3 + if err := func() error { + if err := s.StatusChange.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"status_change\"") + } + case "result_code": + requiredBitSet[0] |= 1 << 4 + if err := func() error { + v, err := d.Int32() + s.ResultCode = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"result_code\"") + } + case "result_arg": + requiredBitSet[0] |= 1 << 5 + if err := func() error { + v, err := d.Int32() + s.ResultArg = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"result_arg\"") + } + case "total_actions": + requiredBitSet[0] |= 1 << 6 if err := func() error { v, err := d.Int32() s.TotalActions = int32(v) @@ -2074,8 +2177,20 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"total_actions\"") } + case "spec_actions": + requiredBitSet[0] |= 1 << 7 + if err := func() error { + v, err := d.Int32() + s.SpecActions = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"spec_actions\"") + } case "skipped_actions": - requiredBitSet[0] |= 1 << 2 + requiredBitSet[1] |= 1 << 0 if err := func() error { v, err := d.Int32() s.SkippedActions = int32(v) @@ -2087,7 +2202,7 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"skipped_actions\"") } case "fwd_fees": - requiredBitSet[0] |= 1 << 3 + requiredBitSet[1] |= 1 << 1 if err := func() error { v, err := d.Int64() s.FwdFees = int64(v) @@ -2099,7 +2214,7 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"fwd_fees\"") } case "total_fees": - requiredBitSet[0] |= 1 << 4 + requiredBitSet[1] |= 1 << 2 if err := func() error { v, err := d.Int64() s.TotalFees = int64(v) @@ -2110,6 +2225,42 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"total_fees\"") } + case "msgs_created": + requiredBitSet[1] |= 1 << 3 + if err := func() error { + v, err := d.Int16() + s.MsgsCreated = int16(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"msgs_created\"") + } + case "total_msg_size_cells": + requiredBitSet[1] |= 1 << 4 + if err := func() error { + v, err := d.Int64() + s.TotalMsgSizeCells = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"total_msg_size_cells\"") + } + case "total_msg_size_bits": + requiredBitSet[1] |= 1 << 5 + if err := func() error { + v, err := d.Int64() + s.TotalMsgSizeBits = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"total_msg_size_bits\"") + } default: return d.Skip() } @@ -2119,8 +2270,9 @@ func (s *ActionPhase) Decode(d *jx.Decoder) error { } // Validate required fields. var failures []validate.FieldError - for i, mask := range [1]uint8{ - 0b00011111, + for i, mask := range [2]uint8{ + 0b11111111, + 0b00111111, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. @@ -10617,6 +10769,185 @@ func (s *BlockchainRawAccountExtraBalance) UnmarshalJSON(data []byte) error { return s.Decode(d) } +// Encode implements json.Marshaler. +func (s *BouncePhase) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *BouncePhase) encodeFields(e *jx.Encoder) { + { + e.FieldStart("bounce_type") + s.BounceType.Encode(e) + } + { + if s.MsgSizeCells.Set { + e.FieldStart("msg_size_cells") + s.MsgSizeCells.Encode(e) + } + } + { + if s.MsgSizeBits.Set { + e.FieldStart("msg_size_bits") + s.MsgSizeBits.Encode(e) + } + } + { + if s.ReqFwdFees.Set { + e.FieldStart("req_fwd_fees") + s.ReqFwdFees.Encode(e) + } + } + { + if s.MsgFees.Set { + e.FieldStart("msg_fees") + s.MsgFees.Encode(e) + } + } + { + if s.FwdFees.Set { + e.FieldStart("fwd_fees") + s.FwdFees.Encode(e) + } + } +} + +var jsonFieldsNameOfBouncePhase = [6]string{ + 0: "bounce_type", + 1: "msg_size_cells", + 2: "msg_size_bits", + 3: "req_fwd_fees", + 4: "msg_fees", + 5: "fwd_fees", +} + +// Decode decodes BouncePhase from json. +func (s *BouncePhase) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode BouncePhase to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "bounce_type": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + if err := s.BounceType.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"bounce_type\"") + } + case "msg_size_cells": + if err := func() error { + s.MsgSizeCells.Reset() + if err := s.MsgSizeCells.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"msg_size_cells\"") + } + case "msg_size_bits": + if err := func() error { + s.MsgSizeBits.Reset() + if err := s.MsgSizeBits.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"msg_size_bits\"") + } + case "req_fwd_fees": + if err := func() error { + s.ReqFwdFees.Reset() + if err := s.ReqFwdFees.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"req_fwd_fees\"") + } + case "msg_fees": + if err := func() error { + s.MsgFees.Reset() + if err := s.MsgFees.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"msg_fees\"") + } + case "fwd_fees": + if err := func() error { + s.FwdFees.Reset() + if err := s.FwdFees.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"fwd_fees\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode BouncePhase") + } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [1]uint8{ + 0b00000001, + } { + if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { + // Mask only required fields and check equality to mask using XOR. + // + // If XOR result is not zero, result is not equal to expected, so some fields are missed. + // Bits of fields which would be set are actually bits of missed fields. + missed := bits.OnesCount8(result) + for bitN := 0; bitN < missed; bitN++ { + bitIdx := bits.TrailingZeros8(result) + fieldIdx := i*8 + bitIdx + var name string + if fieldIdx < len(jsonFieldsNameOfBouncePhase) { + name = jsonFieldsNameOfBouncePhase[fieldIdx] + } else { + name = strconv.Itoa(fieldIdx) + } + failures = append(failures, validate.FieldError{ + Name: name, + Error: validate.ErrFieldRequired, + }) + // Reset bit. + result &^= 1 << bitIdx + } + } + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *BouncePhase) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *BouncePhase) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + // Encode encodes BouncePhaseType as json. func (s BouncePhaseType) Encode(e *jx.Encoder) { e.Str(string(s)) @@ -10684,6 +11015,18 @@ func (s *ComputePhase) encodeFields(e *jx.Encoder) { s.Success.Encode(e) } } + { + if s.MsgStateUsed.Set { + e.FieldStart("msg_state_used") + s.MsgStateUsed.Encode(e) + } + } + { + if s.AccountActivated.Set { + e.FieldStart("account_activated") + s.AccountActivated.Encode(e) + } + } { if s.GasFees.Set { e.FieldStart("gas_fees") @@ -10696,6 +11039,18 @@ func (s *ComputePhase) encodeFields(e *jx.Encoder) { s.GasUsed.Encode(e) } } + { + if s.GasCredit.Set { + e.FieldStart("gas_credit") + s.GasCredit.Encode(e) + } + } + { + if s.GasLimit.Set { + e.FieldStart("gas_limit") + s.GasLimit.Encode(e) + } + } { if s.VMSteps.Set { e.FieldStart("vm_steps") @@ -10708,16 +11063,34 @@ func (s *ComputePhase) encodeFields(e *jx.Encoder) { s.ExitCode.Encode(e) } } + { + if s.ExitArg.Set { + e.FieldStart("exit_arg") + s.ExitArg.Encode(e) + } + } + { + if s.Mode.Set { + e.FieldStart("mode") + s.Mode.Encode(e) + } + } } -var jsonFieldsNameOfComputePhase = [7]string{ - 0: "skipped", - 1: "skip_reason", - 2: "success", - 3: "gas_fees", - 4: "gas_used", - 5: "vm_steps", - 6: "exit_code", +var jsonFieldsNameOfComputePhase = [13]string{ + 0: "skipped", + 1: "skip_reason", + 2: "success", + 3: "msg_state_used", + 4: "account_activated", + 5: "gas_fees", + 6: "gas_used", + 7: "gas_credit", + 8: "gas_limit", + 9: "vm_steps", + 10: "exit_code", + 11: "exit_arg", + 12: "mode", } // Decode decodes ComputePhase from json. @@ -10725,7 +11098,7 @@ func (s *ComputePhase) Decode(d *jx.Decoder) error { if s == nil { return errors.New("invalid: unable to decode ComputePhase to nil") } - var requiredBitSet [1]uint8 + var requiredBitSet [2]uint8 if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { @@ -10761,6 +11134,26 @@ func (s *ComputePhase) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"success\"") } + case "msg_state_used": + if err := func() error { + s.MsgStateUsed.Reset() + if err := s.MsgStateUsed.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"msg_state_used\"") + } + case "account_activated": + if err := func() error { + s.AccountActivated.Reset() + if err := s.AccountActivated.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"account_activated\"") + } case "gas_fees": if err := func() error { s.GasFees.Reset() @@ -10781,6 +11174,26 @@ func (s *ComputePhase) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"gas_used\"") } + case "gas_credit": + if err := func() error { + s.GasCredit.Reset() + if err := s.GasCredit.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"gas_credit\"") + } + case "gas_limit": + if err := func() error { + s.GasLimit.Reset() + if err := s.GasLimit.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"gas_limit\"") + } case "vm_steps": if err := func() error { s.VMSteps.Reset() @@ -10801,6 +11214,26 @@ func (s *ComputePhase) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"exit_code\"") } + case "exit_arg": + if err := func() error { + s.ExitArg.Reset() + if err := s.ExitArg.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"exit_arg\"") + } + case "mode": + if err := func() error { + s.Mode.Reset() + if err := s.Mode.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"mode\"") + } default: return d.Skip() } @@ -10810,8 +11243,9 @@ func (s *ComputePhase) Decode(d *jx.Decoder) error { } // Validate required fields. var failures []validate.FieldError - for i, mask := range [1]uint8{ + for i, mask := range [2]uint8{ 0b00000001, + 0b00000000, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. @@ -26585,6 +27019,39 @@ func (s *OptBool) UnmarshalJSON(data []byte) error { return s.Decode(d) } +// Encode encodes BouncePhase as json. +func (o OptBouncePhase) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes BouncePhase from json. +func (o *OptBouncePhase) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptBouncePhase to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptBouncePhase) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptBouncePhase) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + // Encode encodes BouncePhaseType as json. func (o OptBouncePhaseType) Encode(e *jx.Encoder) { if !o.Set { @@ -27218,6 +27685,41 @@ func (s *OptInt64) UnmarshalJSON(data []byte) error { return s.Decode(d) } +// Encode encodes int8 as json. +func (o OptInt8) Encode(e *jx.Encoder) { + if !o.Set { + return + } + e.Int8(int8(o.Value)) +} + +// Decode decodes int8 from json. +func (o *OptInt8) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptInt8 to nil") + } + o.Set = true + v, err := d.Int8() + if err != nil { + return err + } + o.Value = int8(v) + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptInt8) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptInt8) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + // Encode encodes JettonBridgePrices as json. func (o OptJettonBridgePrices) Encode(e *jx.Encoder) { if !o.Set { @@ -33025,6 +33527,12 @@ func (s *Transaction) encodeFields(e *jx.Encoder) { s.BouncePhase.Encode(e) } } + { + if s.Bounce.Set { + e.FieldStart("bounce") + s.Bounce.Encode(e) + } + } { e.FieldStart("aborted") e.Bool(s.Aborted) @@ -33035,7 +33543,7 @@ func (s *Transaction) encodeFields(e *jx.Encoder) { } } -var jsonFieldsNameOfTransaction = [23]string{ +var jsonFieldsNameOfTransaction = [24]string{ 0: "hash", 1: "lt", 2: "account", @@ -33057,8 +33565,9 @@ var jsonFieldsNameOfTransaction = [23]string{ 18: "credit_phase", 19: "action_phase", 20: "bounce_phase", - 21: "aborted", - 22: "destroyed", + 21: "bounce", + 22: "aborted", + 23: "destroyed", } // Decode decodes Transaction from json. @@ -33304,8 +33813,18 @@ func (s *Transaction) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"bounce_phase\"") } + case "bounce": + if err := func() error { + s.Bounce.Reset() + if err := s.Bounce.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"bounce\"") + } case "aborted": - requiredBitSet[2] |= 1 << 5 + requiredBitSet[2] |= 1 << 6 if err := func() error { v, err := d.Bool() s.Aborted = bool(v) @@ -33317,7 +33836,7 @@ func (s *Transaction) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"aborted\"") } case "destroyed": - requiredBitSet[2] |= 1 << 6 + requiredBitSet[2] |= 1 << 7 if err := func() error { v, err := d.Bool() s.Destroyed = bool(v) @@ -33340,7 +33859,7 @@ func (s *Transaction) Decode(d *jx.Decoder) error { for i, mask := range [3]uint8{ 0b11111111, 0b00110111, - 0b01100000, + 0b11000000, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. diff --git a/pkg/oas/oas_schemas_gen.go b/pkg/oas/oas_schemas_gen.go index ed80b06a..eb8e6127 100644 --- a/pkg/oas/oas_schemas_gen.go +++ b/pkg/oas/oas_schemas_gen.go @@ -855,11 +855,20 @@ func (s *Action) SetSimplePreview(val ActionSimplePreview) { // Ref: #/components/schemas/ActionPhase type ActionPhase struct { - Success bool `json:"success"` - TotalActions int32 `json:"total_actions"` - SkippedActions int32 `json:"skipped_actions"` - FwdFees int64 `json:"fwd_fees"` - TotalFees int64 `json:"total_fees"` + Success bool `json:"success"` + Valid bool `json:"valid"` + NoFunds bool `json:"no_funds"` + StatusChange AccStatusChange `json:"status_change"` + ResultCode int32 `json:"result_code"` + ResultArg int32 `json:"result_arg"` + TotalActions int32 `json:"total_actions"` + SpecActions int32 `json:"spec_actions"` + SkippedActions int32 `json:"skipped_actions"` + FwdFees int64 `json:"fwd_fees"` + TotalFees int64 `json:"total_fees"` + MsgsCreated int16 `json:"msgs_created"` + TotalMsgSizeCells int64 `json:"total_msg_size_cells"` + TotalMsgSizeBits int64 `json:"total_msg_size_bits"` } // GetSuccess returns the value of Success. @@ -867,11 +876,41 @@ func (s *ActionPhase) GetSuccess() bool { return s.Success } +// GetValid returns the value of Valid. +func (s *ActionPhase) GetValid() bool { + return s.Valid +} + +// GetNoFunds returns the value of NoFunds. +func (s *ActionPhase) GetNoFunds() bool { + return s.NoFunds +} + +// GetStatusChange returns the value of StatusChange. +func (s *ActionPhase) GetStatusChange() AccStatusChange { + return s.StatusChange +} + +// GetResultCode returns the value of ResultCode. +func (s *ActionPhase) GetResultCode() int32 { + return s.ResultCode +} + +// GetResultArg returns the value of ResultArg. +func (s *ActionPhase) GetResultArg() int32 { + return s.ResultArg +} + // GetTotalActions returns the value of TotalActions. func (s *ActionPhase) GetTotalActions() int32 { return s.TotalActions } +// GetSpecActions returns the value of SpecActions. +func (s *ActionPhase) GetSpecActions() int32 { + return s.SpecActions +} + // GetSkippedActions returns the value of SkippedActions. func (s *ActionPhase) GetSkippedActions() int32 { return s.SkippedActions @@ -887,16 +926,61 @@ func (s *ActionPhase) GetTotalFees() int64 { return s.TotalFees } +// GetMsgsCreated returns the value of MsgsCreated. +func (s *ActionPhase) GetMsgsCreated() int16 { + return s.MsgsCreated +} + +// GetTotalMsgSizeCells returns the value of TotalMsgSizeCells. +func (s *ActionPhase) GetTotalMsgSizeCells() int64 { + return s.TotalMsgSizeCells +} + +// GetTotalMsgSizeBits returns the value of TotalMsgSizeBits. +func (s *ActionPhase) GetTotalMsgSizeBits() int64 { + return s.TotalMsgSizeBits +} + // SetSuccess sets the value of Success. func (s *ActionPhase) SetSuccess(val bool) { s.Success = val } +// SetValid sets the value of Valid. +func (s *ActionPhase) SetValid(val bool) { + s.Valid = val +} + +// SetNoFunds sets the value of NoFunds. +func (s *ActionPhase) SetNoFunds(val bool) { + s.NoFunds = val +} + +// SetStatusChange sets the value of StatusChange. +func (s *ActionPhase) SetStatusChange(val AccStatusChange) { + s.StatusChange = val +} + +// SetResultCode sets the value of ResultCode. +func (s *ActionPhase) SetResultCode(val int32) { + s.ResultCode = val +} + +// SetResultArg sets the value of ResultArg. +func (s *ActionPhase) SetResultArg(val int32) { + s.ResultArg = val +} + // SetTotalActions sets the value of TotalActions. func (s *ActionPhase) SetTotalActions(val int32) { s.TotalActions = val } +// SetSpecActions sets the value of SpecActions. +func (s *ActionPhase) SetSpecActions(val int32) { + s.SpecActions = val +} + // SetSkippedActions sets the value of SkippedActions. func (s *ActionPhase) SetSkippedActions(val int32) { s.SkippedActions = val @@ -912,6 +996,21 @@ func (s *ActionPhase) SetTotalFees(val int64) { s.TotalFees = val } +// SetMsgsCreated sets the value of MsgsCreated. +func (s *ActionPhase) SetMsgsCreated(val int16) { + s.MsgsCreated = val +} + +// SetTotalMsgSizeCells sets the value of TotalMsgSizeCells. +func (s *ActionPhase) SetTotalMsgSizeCells(val int64) { + s.TotalMsgSizeCells = val +} + +// SetTotalMsgSizeBits sets the value of TotalMsgSizeBits. +func (s *ActionPhase) SetTotalMsgSizeBits(val int64) { + s.TotalMsgSizeBits = val +} + // Shortly describes what this action is about. // Ref: #/components/schemas/ActionSimplePreview type ActionSimplePreview struct { @@ -3869,6 +3968,76 @@ func (s *BlockchainRawAccountExtraBalance) init() BlockchainRawAccountExtraBalan return m } +// Ref: #/components/schemas/BouncePhase +type BouncePhase struct { + BounceType BouncePhaseType `json:"bounce_type"` + MsgSizeCells OptInt64 `json:"msg_size_cells"` + MsgSizeBits OptInt64 `json:"msg_size_bits"` + ReqFwdFees OptInt64 `json:"req_fwd_fees"` + MsgFees OptInt64 `json:"msg_fees"` + FwdFees OptInt64 `json:"fwd_fees"` +} + +// GetBounceType returns the value of BounceType. +func (s *BouncePhase) GetBounceType() BouncePhaseType { + return s.BounceType +} + +// GetMsgSizeCells returns the value of MsgSizeCells. +func (s *BouncePhase) GetMsgSizeCells() OptInt64 { + return s.MsgSizeCells +} + +// GetMsgSizeBits returns the value of MsgSizeBits. +func (s *BouncePhase) GetMsgSizeBits() OptInt64 { + return s.MsgSizeBits +} + +// GetReqFwdFees returns the value of ReqFwdFees. +func (s *BouncePhase) GetReqFwdFees() OptInt64 { + return s.ReqFwdFees +} + +// GetMsgFees returns the value of MsgFees. +func (s *BouncePhase) GetMsgFees() OptInt64 { + return s.MsgFees +} + +// GetFwdFees returns the value of FwdFees. +func (s *BouncePhase) GetFwdFees() OptInt64 { + return s.FwdFees +} + +// SetBounceType sets the value of BounceType. +func (s *BouncePhase) SetBounceType(val BouncePhaseType) { + s.BounceType = val +} + +// SetMsgSizeCells sets the value of MsgSizeCells. +func (s *BouncePhase) SetMsgSizeCells(val OptInt64) { + s.MsgSizeCells = val +} + +// SetMsgSizeBits sets the value of MsgSizeBits. +func (s *BouncePhase) SetMsgSizeBits(val OptInt64) { + s.MsgSizeBits = val +} + +// SetReqFwdFees sets the value of ReqFwdFees. +func (s *BouncePhase) SetReqFwdFees(val OptInt64) { + s.ReqFwdFees = val +} + +// SetMsgFees sets the value of MsgFees. +func (s *BouncePhase) SetMsgFees(val OptInt64) { + s.MsgFees = val +} + +// SetFwdFees sets the value of FwdFees. +func (s *BouncePhase) SetFwdFees(val OptInt64) { + s.FwdFees = val +} + // Ref: #/components/schemas/BouncePhaseType type BouncePhaseType string @@ -3920,13 +4089,19 @@ func (s *BouncePhaseType) UnmarshalText(data []byte) error { // Ref: #/components/schemas/ComputePhase type ComputePhase struct { - Skipped bool `json:"skipped"` - SkipReason OptComputeSkipReason `json:"skip_reason"` - Success OptBool `json:"success"` - GasFees OptInt64 `json:"gas_fees"` - GasUsed OptInt64 `json:"gas_used"` - VMSteps OptUint32 `json:"vm_steps"` - ExitCode OptInt32 `json:"exit_code"` + Skipped bool `json:"skipped"` + SkipReason OptComputeSkipReason `json:"skip_reason"` + Success OptBool `json:"success"` + MsgStateUsed OptBool `json:"msg_state_used"` + AccountActivated OptBool `json:"account_activated"` + GasFees OptInt64 `json:"gas_fees"` + GasUsed OptInt64 `json:"gas_used"` + GasCredit OptInt64 `json:"gas_credit"` + GasLimit OptInt64 `json:"gas_limit"` + VMSteps OptUint32 `json:"vm_steps"` + ExitCode OptInt32 `json:"exit_code"` + ExitArg OptInt32 `json:"exit_arg"` + Mode OptInt8 `json:"mode"` } // GetSkipped returns the value of Skipped. @@ -3944,6 +4119,16 @@ func (s *ComputePhase) GetSuccess() OptBool { return s.Success } +// GetMsgStateUsed returns the value of MsgStateUsed. +func (s *ComputePhase) GetMsgStateUsed() OptBool { + return s.MsgStateUsed +} + +// GetAccountActivated returns the value of AccountActivated. +func (s *ComputePhase) GetAccountActivated() OptBool { + return s.AccountActivated +} + // GetGasFees returns the value of GasFees. func (s *ComputePhase) GetGasFees() OptInt64 { return s.GasFees @@ -3954,6 +4139,16 @@ func (s *ComputePhase) GetGasUsed() OptInt64 { return s.GasUsed } +// GetGasCredit returns the value of GasCredit. +func (s *ComputePhase) GetGasCredit() OptInt64 { + return s.GasCredit +} + +// GetGasLimit returns the value of GasLimit. +func (s *ComputePhase) GetGasLimit() OptInt64 { + return s.GasLimit +} + // GetVMSteps returns the value of VMSteps. func (s *ComputePhase) GetVMSteps() OptUint32 { return s.VMSteps @@ -3964,6 +4159,16 @@ func (s *ComputePhase) GetExitCode() OptInt32 { return s.ExitCode } +// GetExitArg returns the value of ExitArg. +func (s *ComputePhase) GetExitArg() OptInt32 { + return s.ExitArg +} + +// GetMode returns the value of Mode. +func (s *ComputePhase) GetMode() OptInt8 { + return s.Mode +} + // SetSkipped sets the value of Skipped. func (s *ComputePhase) SetSkipped(val bool) { s.Skipped = val @@ -3979,6 +4184,16 @@ func (s *ComputePhase) SetSuccess(val OptBool) { s.Success = val } +// SetMsgStateUsed sets the value of MsgStateUsed. +func (s *ComputePhase) SetMsgStateUsed(val OptBool) { + s.MsgStateUsed = val +} + +// SetAccountActivated sets the value of AccountActivated. +func (s *ComputePhase) SetAccountActivated(val OptBool) { + s.AccountActivated = val +} + // SetGasFees sets the value of GasFees. func (s *ComputePhase) SetGasFees(val OptInt64) { s.GasFees = val @@ -3989,6 +4204,16 @@ func (s *ComputePhase) SetGasUsed(val OptInt64) { s.GasUsed = val } +// SetGasCredit sets the value of GasCredit. +func (s *ComputePhase) SetGasCredit(val OptInt64) { + s.GasCredit = val +} + +// SetGasLimit sets the value of GasLimit. +func (s *ComputePhase) SetGasLimit(val OptInt64) { + s.GasLimit = val +} + // SetVMSteps sets the value of VMSteps. func (s *ComputePhase) SetVMSteps(val OptUint32) { s.VMSteps = val @@ -3999,6 +4224,16 @@ func (s *ComputePhase) SetExitCode(val OptInt32) { s.ExitCode = val } +// SetExitArg sets the value of ExitArg. +func (s *ComputePhase) SetExitArg(val OptInt32) { + s.ExitArg = val +} + +// SetMode sets the value of Mode. +func (s *ComputePhase) SetMode(val OptInt8) { + s.Mode = val +} + // Ref: #/components/schemas/ComputeSkipReason type ComputeSkipReason string @@ -10377,6 +10612,52 @@ func (o OptBool) Or(d bool) bool { return d } +// NewOptBouncePhase returns new OptBouncePhase with value set to v. +func NewOptBouncePhase(v BouncePhase) OptBouncePhase { + return OptBouncePhase{ + Value: v, + Set: true, + } +} + +// OptBouncePhase is optional BouncePhase. +type OptBouncePhase struct { + Value BouncePhase + Set bool +} + +// IsSet returns true if OptBouncePhase was set. +func (o OptBouncePhase) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptBouncePhase) Reset() { + var v BouncePhase + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptBouncePhase) SetTo(v BouncePhase) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptBouncePhase) Get() (v BouncePhase, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptBouncePhase) Or(d BouncePhase) BouncePhase { + if v, ok := o.Get(); ok { + return v + } + return d +} + // NewOptBouncePhaseType returns new OptBouncePhaseType with value set to v. func NewOptBouncePhaseType(v BouncePhaseType) OptBouncePhaseType { return OptBouncePhaseType{ @@ -11251,6 +11532,52 @@ func (o OptInt64) Or(d int64) int64 { return d } +// NewOptInt8 returns new OptInt8 with value set to v. +func NewOptInt8(v int8) OptInt8 { + return OptInt8{ + Value: v, + Set: true, + } +} + +// OptInt8 is optional int8. +type OptInt8 struct { + Value int8 + Set bool +} + +// IsSet returns true if OptInt8 was set. +func (o OptInt8) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptInt8) Reset() { + var v int8 + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptInt8) SetTo(v int8) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptInt8) Get() (v int8, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptInt8) Or(d int8) int8 { + if v, ok := o.Get(); ok { + return v + } + return d +} + // NewOptJettonBridgePrices returns new OptJettonBridgePrices with value set to v. func NewOptJettonBridgePrices(v JettonBridgePrices) OptJettonBridgePrices { return OptJettonBridgePrices{ @@ -14269,6 +14596,7 @@ type Transaction struct { CreditPhase OptCreditPhase `json:"credit_phase"` ActionPhase OptActionPhase `json:"action_phase"` BouncePhase OptBouncePhaseType `json:"bounce_phase"` + Bounce OptBouncePhase `json:"bounce"` Aborted bool `json:"aborted"` Destroyed bool `json:"destroyed"` } @@ -14378,6 +14706,11 @@ func (s *Transaction) GetBouncePhase() OptBouncePhaseType { return s.BouncePhase } +// GetBounce returns the value of Bounce. +func (s *Transaction) GetBounce() OptBouncePhase { + return s.Bounce +} + // GetAborted returns the value of Aborted. func (s *Transaction) GetAborted() bool { return s.Aborted @@ -14493,6 +14826,11 @@ func (s *Transaction) SetBouncePhase(val OptBouncePhaseType) { s.BouncePhase = val } +// SetBounce sets the value of Bounce. +func (s *Transaction) SetBounce(val OptBouncePhase) { + s.Bounce = val +} + // SetAborted sets the value of Aborted. func (s *Transaction) SetAborted(val bool) { s.Aborted = val diff --git a/pkg/oas/oas_validators_gen.go b/pkg/oas/oas_validators_gen.go index b2b94661..adefbe52 100644 --- a/pkg/oas/oas_validators_gen.go +++ b/pkg/oas/oas_validators_gen.go @@ -459,6 +459,25 @@ func (s *Action) Validate() error { return nil } +func (s *ActionPhase) Validate() error { + var failures []validate.FieldError + if err := func() error { + if err := s.StatusChange.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "status_change", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + func (s *ActionSimplePreview) Validate() error { var failures []validate.FieldError if err := func() error { @@ -1489,6 +1508,25 @@ func (s *BlockchainConfig9) Validate() error { return nil } +func (s *BouncePhase) Validate() error { + var failures []validate.FieldError + if err := func() error { + if err := s.BounceType.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "bounce_type", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + func (s BouncePhaseType) Validate() error { switch s { case "TrPhaseBounceNegfunds": @@ -3655,6 +3693,24 @@ func (s *Transaction) Validate() error { Error: err, }) } + if err := func() error { + if value, ok := s.ActionPhase.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "action_phase", + Error: err, + }) + } if err := func() error { if value, ok := s.BouncePhase.Get(); ok { if err := func() error { @@ -3673,6 +3729,24 @@ func (s *Transaction) Validate() error { Error: err, }) } + if err := func() error { + if value, ok := s.Bounce.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "bounce", + Error: err, + }) + } if len(failures) > 0 { return &validate.Error{Fields: failures} }