From f9c0c7c1e1d7a5b5c29171cd1a271380aa7ff949 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Mon, 3 Jul 2023 10:50:06 +0300 Subject: [PATCH] initial implementation --- data/logs.go | 8 + data/transaction.go | 3 +- go.mod | 2 +- go.sum | 4 +- mock/dbTransactionsHandlerStub.go | 2 +- process/elasticproc/elasticProcessor.go | 12 +- process/elasticproc/interface.go | 2 +- .../logsevents/informativeLogsProcessor.go | 54 +++++-- .../informativeLogsProcessor_test.go | 5 +- process/elasticproc/logsevents/interface.go | 7 + .../logsevents/logsAndEventsProcessor.go | 1 + process/elasticproc/logsevents/logsData.go | 2 + process/elasticproc/logsevents/statusInfo.go | 37 +++++ .../elasticproc/logsevents/statusInfo_test.go | 1 + .../transactions/scrsDataToTransactions.go | 148 +++--------------- .../scrsDataToTransactions_test.go | 14 +- process/elasticproc/transactions/serialize.go | 38 ++++- .../transactions/serialize_test.go | 6 +- .../transactions/transactionsProcessor.go | 3 +- .../transactionsProcessor_test.go | 2 +- 20 files changed, 170 insertions(+), 181 deletions(-) create mode 100644 process/elasticproc/logsevents/statusInfo.go create mode 100644 process/elasticproc/logsevents/statusInfo_test.go diff --git a/data/logs.go b/data/logs.go index d8a62ec6..a3baf0d5 100644 --- a/data/logs.go +++ b/data/logs.go @@ -24,12 +24,20 @@ type Event struct { Order int `json:"order"` } +// StatusInfo holds the fields for the transaction status +type StatusInfo struct { + CompletedEvent bool `json:"completedEvent"` + ErrorEvent bool `json:"errorEvent"` + Status string `json:"status"` +} + // PreparedLogsResults is the DTO that holds all the results after processing type PreparedLogsResults struct { Tokens TokensHandler TokensSupply TokensHandler ScDeploys map[string]*ScDeployInfo Delegators map[string]*Delegator + TxHashStatusInfo map[string]*StatusInfo TokensInfo []*TokenInfo NFTsDataUpdates []*NFTDataUpdate TokenRolesAndProperties *tokeninfo.TokenRolesAndProperties diff --git a/data/transaction.go b/data/transaction.go index fc00b972..04b7364f 100644 --- a/data/transaction.go +++ b/data/transaction.go @@ -46,6 +46,8 @@ type Transaction struct { Version uint32 `json:"version,omitempty"` GuardianAddress string `json:"guardian,omitempty"` GuardianSignature string `json:"guardianSignature,omitempty"` + ErrorEvent bool `json:"errorEvent,omitempty"` + CompletedEvent bool `json:"completedEvent,omitempty"` SmartContractResults []*ScResult `json:"-"` Hash string `json:"-"` BlockHash string `json:"-"` @@ -67,7 +69,6 @@ type PreparedResults struct { Transactions []*Transaction ScResults []*ScResult Receipts []*Receipt - TxHashStatus map[string]string TxHashFee map[string]*FeeData } diff --git a/go.mod b/go.mod index 325b7928..0d81c4a4 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.17 require ( github.com/elastic/go-elasticsearch/v7 v7.12.0 github.com/multiversx/mx-chain-communication-go v1.0.3 - github.com/multiversx/mx-chain-core-go v1.2.7 + github.com/multiversx/mx-chain-core-go v1.2.8-0.20230630085500-96880f1bce4c github.com/multiversx/mx-chain-logger-go v1.0.11 github.com/multiversx/mx-chain-vm-common-go v1.4.1 github.com/stretchr/testify v1.8.2 diff --git a/go.sum b/go.sum index 9fcf9ca6..dc0ea0bb 100644 --- a/go.sum +++ b/go.sum @@ -476,8 +476,8 @@ github.com/multiversx/mx-chain-communication-go v1.0.3/go.mod h1:7oTI77XfWmRWwVE github.com/multiversx/mx-chain-core-go v1.1.30/go.mod h1:8gGEQv6BWuuJwhd25qqhCOZbBSv9mk+hLeKvinSaSMk= github.com/multiversx/mx-chain-core-go v1.2.1/go.mod h1:8gGEQv6BWuuJwhd25qqhCOZbBSv9mk+hLeKvinSaSMk= github.com/multiversx/mx-chain-core-go v1.2.5/go.mod h1:jzYFSiYBuO0dGpGFXnZWSwcwcKP7Flyn/X41y4zIQrQ= -github.com/multiversx/mx-chain-core-go v1.2.7 h1:cP4h/B4Arnz0K6ieRd1OAf+z5gBejiMA6lzcWewR7kk= -github.com/multiversx/mx-chain-core-go v1.2.7/go.mod h1:jzYFSiYBuO0dGpGFXnZWSwcwcKP7Flyn/X41y4zIQrQ= +github.com/multiversx/mx-chain-core-go v1.2.8-0.20230630085500-96880f1bce4c h1:UfPvZLUYZUsI+ZtxHFroyr3q+CDPgkT0n3eqKNdrJuM= +github.com/multiversx/mx-chain-core-go v1.2.8-0.20230630085500-96880f1bce4c/go.mod h1:jzYFSiYBuO0dGpGFXnZWSwcwcKP7Flyn/X41y4zIQrQ= github.com/multiversx/mx-chain-crypto-go v1.2.6/go.mod h1:rOj0Rr19HTOYt9YTeym7RKxlHt91NXln3LVKjHKVmA0= github.com/multiversx/mx-chain-logger-go v1.0.11 h1:DFsHa+sc5fKwhDR50I8uBM99RTDTEW68ESyr5ALRDwE= github.com/multiversx/mx-chain-logger-go v1.0.11/go.mod h1:1srDkP0DQucWQ+rYfaq0BX2qLnULsUdRPADpYUTM6dA= diff --git a/mock/dbTransactionsHandlerStub.go b/mock/dbTransactionsHandlerStub.go index 15b50e11..a810af5d 100644 --- a/mock/dbTransactionsHandlerStub.go +++ b/mock/dbTransactionsHandlerStub.go @@ -43,7 +43,7 @@ func (tps *DBTransactionProcessorStub) SerializeReceipts(recs []*data.Receipt, b } // SerializeTransactions - -func (tps *DBTransactionProcessorStub) SerializeTransactions(_ []*data.Transaction, _ map[string]string, _ uint32, _ *data.BufferSlice, _ string) error { +func (tps *DBTransactionProcessorStub) SerializeTransactions(_ []*data.Transaction, _ map[string]*data.StatusInfo, _ uint32, _ *data.BufferSlice, _ string) error { return nil } diff --git a/process/elasticproc/elasticProcessor.go b/process/elasticproc/elasticProcessor.go index b40c2a29..d70fff04 100644 --- a/process/elasticproc/elasticProcessor.go +++ b/process/elasticproc/elasticProcessor.go @@ -414,12 +414,12 @@ func (ei *elasticProcessor) SaveTransactions(obh *outport.OutportBlockWithHeader logsData := ei.logsAndEventsProc.ExtractDataFromLogs(obh.TransactionPool.Logs, preparedResults, headerTimestamp, obh.Header.GetShardID(), obh.NumberOfShards) buffers := data.NewBufferSlice(ei.bulkRequestMaxSize) - err := ei.indexTransactions(preparedResults.Transactions, preparedResults.TxHashStatus, obh.Header, buffers) + err := ei.indexTransactions(preparedResults.Transactions, logsData.TxHashStatusInfo, obh.Header, buffers) if err != nil { return err } - err = ei.prepareAndIndexOperations(preparedResults.Transactions, preparedResults.TxHashStatus, obh.Header, preparedResults.ScResults, buffers, ei.isImportDB()) + err = ei.prepareAndIndexOperations(preparedResults.Transactions, logsData.TxHashStatusInfo, obh.Header, preparedResults.ScResults, buffers, ei.isImportDB()) if err != nil { return err } @@ -539,17 +539,17 @@ func (ei *elasticProcessor) indexScDeploys(deployData map[string]*data.ScDeployI return ei.logsAndEventsProc.SerializeSCDeploys(deployData, buffSlice, elasticIndexer.SCDeploysIndex) } -func (ei *elasticProcessor) indexTransactions(txs []*data.Transaction, txHashStatus map[string]string, header coreData.HeaderHandler, bytesBuff *data.BufferSlice) error { +func (ei *elasticProcessor) indexTransactions(txs []*data.Transaction, txHashStatusInfo map[string]*data.StatusInfo, header coreData.HeaderHandler, bytesBuff *data.BufferSlice) error { if !ei.isIndexEnabled(elasticIndexer.TransactionsIndex) { return nil } - return ei.transactionsProc.SerializeTransactions(txs, txHashStatus, header.GetShardID(), bytesBuff, elasticIndexer.TransactionsIndex) + return ei.transactionsProc.SerializeTransactions(txs, txHashStatusInfo, header.GetShardID(), bytesBuff, elasticIndexer.TransactionsIndex) } func (ei *elasticProcessor) prepareAndIndexOperations( txs []*data.Transaction, - txHashStatus map[string]string, + txHashStatusInfo map[string]*data.StatusInfo, header coreData.HeaderHandler, scrs []*data.ScResult, buffSlice *data.BufferSlice, @@ -561,7 +561,7 @@ func (ei *elasticProcessor) prepareAndIndexOperations( processedTxs, processedSCRs := ei.operationsProc.ProcessTransactionsAndSCRs(txs, scrs, isImportDB, header.GetShardID()) - err := ei.transactionsProc.SerializeTransactions(processedTxs, txHashStatus, header.GetShardID(), buffSlice, elasticIndexer.OperationsIndex) + err := ei.transactionsProc.SerializeTransactions(processedTxs, txHashStatusInfo, header.GetShardID(), buffSlice, elasticIndexer.OperationsIndex) if err != nil { return err } diff --git a/process/elasticproc/interface.go b/process/elasticproc/interface.go index eeb12cd4..f7fcef17 100644 --- a/process/elasticproc/interface.go +++ b/process/elasticproc/interface.go @@ -66,7 +66,7 @@ type DBTransactionsHandler interface { GetHexEncodedHashesForRemove(header coreData.HeaderHandler, body *block.Body) ([]string, []string) SerializeReceipts(receipts []*data.Receipt, buffSlice *data.BufferSlice, index string) error - SerializeTransactions(transactions []*data.Transaction, txHashStatus map[string]string, selfShardID uint32, buffSlice *data.BufferSlice, index string) error + SerializeTransactions(transactions []*data.Transaction, txHashStatusInfo map[string]*data.StatusInfo, selfShardID uint32, buffSlice *data.BufferSlice, index string) error SerializeTransactionsFeeData(txHashRefund map[string]*data.FeeData, buffSlice *data.BufferSlice, index string) error SerializeScResults(scResults []*data.ScResult, buffSlice *data.BufferSlice, index string) error } diff --git a/process/elasticproc/logsevents/informativeLogsProcessor.go b/process/elasticproc/logsevents/informativeLogsProcessor.go index 1e64bf8b..d9725dc2 100644 --- a/process/elasticproc/logsevents/informativeLogsProcessor.go +++ b/process/elasticproc/logsevents/informativeLogsProcessor.go @@ -1,12 +1,9 @@ package logsevents import ( + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" -) - -const ( - writeLogOperation = "writeLog" - signalErrorOperation = "signalError" + "github.com/multiversx/mx-chain-es-indexer-go/data" ) type informativeLogsProcessor struct { @@ -16,8 +13,10 @@ type informativeLogsProcessor struct { func newInformativeLogsProcessor() *informativeLogsProcessor { return &informativeLogsProcessor{ operations: map[string]struct{}{ - writeLogOperation: {}, - signalErrorOperation: {}, + core.WriteLogIdentifier: {}, + core.SignalErrorOperation: {}, + core.CompletedTxEventIdentifier: {}, + core.InternalVMErrorsOperation: {}, }, } } @@ -31,19 +30,22 @@ func (ilp *informativeLogsProcessor) processEvent(args *argsProcessEvent) argOut tx, ok := args.txs[args.txHashHexEncoded] if !ok { - return argOutputProcessEvent{ - processed: true, - } + return processEventNoTx(args) } switch identifier { - case writeLogOperation: + case core.CompletedTxEventIdentifier: + { + tx.CompletedEvent = true + } + case core.WriteLogIdentifier: { tx.Status = transaction.TxStatusSuccess.String() } - case signalErrorOperation: + case core.SignalErrorOperation, core.InternalVMErrorsOperation: { tx.Status = transaction.TxStatusFail.String() + tx.ErrorEvent = true } } @@ -51,3 +53,31 @@ func (ilp *informativeLogsProcessor) processEvent(args *argsProcessEvent) argOut processed: true, } } + +func processEventNoTx(args *argsProcessEvent) argOutputProcessEvent { + scr, ok := args.scrs[args.txHashHexEncoded] + if !ok { + return argOutputProcessEvent{ + processed: true, + } + } + + record := &data.StatusInfo{} + switch string(args.event.GetIdentifier()) { + case core.CompletedTxEventIdentifier: + { + record.CompletedEvent = true + } + case core.SignalErrorOperation, core.InternalVMErrorsOperation: + { + record.Status = transaction.TxStatusFail.String() + record.ErrorEvent = true + } + } + + args.txHashStatusInfoProc.addRecord(scr.OriginalTxHash, record) + + return argOutputProcessEvent{ + processed: true, + } +} diff --git a/process/elasticproc/logsevents/informativeLogsProcessor_test.go b/process/elasticproc/logsevents/informativeLogsProcessor_test.go index 6e4e64c5..e1ec5d1e 100644 --- a/process/elasticproc/logsevents/informativeLogsProcessor_test.go +++ b/process/elasticproc/logsevents/informativeLogsProcessor_test.go @@ -3,6 +3,7 @@ package logsevents import ( "testing" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-es-indexer-go/data" "github.com/stretchr/testify/require" @@ -40,7 +41,7 @@ func TestInformativeLogsProcessorWriteLog(t *testing.T) { event := &transaction.Event{ Address: []byte("addr"), - Identifier: []byte(writeLogOperation), + Identifier: []byte(core.WriteLogIdentifier), } args := &argsProcessEvent{ timestamp: 1234, @@ -73,7 +74,7 @@ func TestInformativeLogsProcessorSignalError(t *testing.T) { event := &transaction.Event{ Address: []byte("addr"), - Identifier: []byte(signalErrorOperation), + Identifier: []byte(core.SignalErrorOperation), } args := &argsProcessEvent{ timestamp: 1234, diff --git a/process/elasticproc/logsevents/interface.go b/process/elasticproc/logsevents/interface.go index c6092353..b3d4d9ba 100644 --- a/process/elasticproc/logsevents/interface.go +++ b/process/elasticproc/logsevents/interface.go @@ -10,10 +10,12 @@ type argsProcessEvent struct { txHashHexEncoded string scDeploys map[string]*data.ScDeployInfo txs map[string]*data.Transaction + scrs map[string]*data.ScResult event coreData.EventHandler tokens data.TokensHandler tokensSupply data.TokensHandler tokenRolesAndProperties *tokeninfo.TokenRolesAndProperties + txHashStatusInfoProc txHashStatusInfoHandler timestamp uint64 logAddress []byte selfShardID uint32 @@ -30,3 +32,8 @@ type argOutputProcessEvent struct { type eventsProcessor interface { processEvent(args *argsProcessEvent) argOutputProcessEvent } + +type txHashStatusInfoHandler interface { + addRecord(hash string, statusInfo *data.StatusInfo) + getAllRecords() map[string]*data.StatusInfo +} diff --git a/process/elasticproc/logsevents/logsAndEventsProcessor.go b/process/elasticproc/logsevents/logsAndEventsProcessor.go index 2efbced0..a8c06e19 100644 --- a/process/elasticproc/logsevents/logsAndEventsProcessor.go +++ b/process/elasticproc/logsevents/logsAndEventsProcessor.go @@ -123,6 +123,7 @@ func (lep *logsAndEventsProcessor) ExtractDataFromLogs( Delegators: lep.logsData.delegators, NFTsDataUpdates: lep.logsData.nftsDataUpdates, TokenRolesAndProperties: lep.logsData.tokenRolesAndProperties, + TxHashStatusInfo: lep.logsData.txHashStatusInfoProc.getAllRecords(), } } diff --git a/process/elasticproc/logsevents/logsData.go b/process/elasticproc/logsevents/logsData.go index 0936e0f0..2d0aab4e 100644 --- a/process/elasticproc/logsevents/logsData.go +++ b/process/elasticproc/logsevents/logsData.go @@ -8,6 +8,7 @@ import ( type logsData struct { timestamp uint64 + txHashStatusInfoProc txHashStatusInfoHandler tokens data.TokensHandler tokensSupply data.TokensHandler txsMap map[string]*data.Transaction @@ -36,6 +37,7 @@ func newLogsData( ld.delegators = make(map[string]*data.Delegator) ld.nftsDataUpdates = make([]*data.NFTDataUpdate, 0) ld.tokenRolesAndProperties = tokeninfo.NewTokenRolesAndProperties() + ld.txHashStatusInfoProc = newTxHashStatusInfo() return ld } diff --git a/process/elasticproc/logsevents/statusInfo.go b/process/elasticproc/logsevents/statusInfo.go new file mode 100644 index 00000000..e440c555 --- /dev/null +++ b/process/elasticproc/logsevents/statusInfo.go @@ -0,0 +1,37 @@ +package logsevents + +import ( + "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-es-indexer-go/data" +) + +type txHashStatusInfoProc struct { + hashStatusInfo map[string]*data.StatusInfo +} + +// NewTxHashStatusInfo will create a new instance of TxHashStatusInfo +func newTxHashStatusInfo() *txHashStatusInfoProc { + return &txHashStatusInfoProc{ + hashStatusInfo: make(map[string]*data.StatusInfo), + } +} + +// AddRecord will add a new record for the given hash +func (ths *txHashStatusInfoProc) addRecord(hash string, statusInfo *data.StatusInfo) { + statusInfoFromMap, found := ths.hashStatusInfo[hash] + if !found { + ths.hashStatusInfo[hash] = statusInfo + } + + if statusInfoFromMap.Status != transaction.TxStatusFail.String() { + statusInfoFromMap.Status = statusInfo.Status + } + + statusInfoFromMap.ErrorEvent = statusInfoFromMap.ErrorEvent || statusInfo.ErrorEvent + statusInfoFromMap.CompletedEvent = statusInfoFromMap.CompletedEvent || statusInfo.CompletedEvent +} + +// GetAllRecords will return all the records +func (ths *txHashStatusInfoProc) getAllRecords() map[string]*data.StatusInfo { + return ths.hashStatusInfo +} diff --git a/process/elasticproc/logsevents/statusInfo_test.go b/process/elasticproc/logsevents/statusInfo_test.go new file mode 100644 index 00000000..2fd5536f --- /dev/null +++ b/process/elasticproc/logsevents/statusInfo_test.go @@ -0,0 +1 @@ +package logsevents diff --git a/process/elasticproc/transactions/scrsDataToTransactions.go b/process/elasticproc/transactions/scrsDataToTransactions.go index becb2299..08383872 100644 --- a/process/elasticproc/transactions/scrsDataToTransactions.go +++ b/process/elasticproc/transactions/scrsDataToTransactions.go @@ -3,13 +3,9 @@ package transactions import ( "encoding/hex" "math/big" - "strings" - "github.com/multiversx/mx-chain-core-go/core" - "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-es-indexer-go/data" "github.com/multiversx/mx-chain-es-indexer-go/process/dataindexer" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" ) const ( @@ -17,25 +13,11 @@ const ( ) type scrsDataToTransactions struct { - retCodes []string balanceConverter dataindexer.BalanceConverter } func newScrsDataToTransactions(balanceConverter dataindexer.BalanceConverter) *scrsDataToTransactions { return &scrsDataToTransactions{ - retCodes: []string{ - vmcommon.FunctionNotFound.String(), - vmcommon.FunctionWrongSignature.String(), - vmcommon.ContractNotFound.String(), - vmcommon.UserError.String(), - vmcommon.OutOfGas.String(), - vmcommon.AccountCollision.String(), - vmcommon.OutOfFunds.String(), - vmcommon.CallStackOverFlow.String(), - vmcommon.ContractInvalid.String(), - vmcommon.ExecutionFailed.String(), - vmcommon.UpgradeFailed.String(), - }, balanceConverter: balanceConverter, } } @@ -65,127 +47,35 @@ func (st *scrsDataToTransactions) processTransactionsAfterSCRsWereAttached(trans if len(tx.SmartContractResults) == 0 { continue } - - st.fillTxWithSCRsFields(tx) - } -} - -func (st *scrsDataToTransactions) fillTxWithSCRsFields(tx *data.Transaction) { - tx.HasSCR = true - - if isRelayedTx(tx) { - return - } - - // ignore invalid transaction because status and gas fields were already set - if tx.Status == transaction.TxStatusInvalid.String() { - return - } - - if hasSuccessfulSCRs(tx) { - return + tx.HasSCR = true } - - if hasCrossShardPendingTransfer(tx) { - return - } - - if st.hasSCRWithErrorCode(tx) { - tx.Status = transaction.TxStatusFail.String() - } -} - -func (st *scrsDataToTransactions) hasSCRWithErrorCode(tx *data.Transaction) bool { - for _, scr := range tx.SmartContractResults { - for _, codeStr := range st.retCodes { - if strings.Contains(string(scr.Data), hex.EncodeToString([]byte(codeStr))) || - scr.ReturnMessage == codeStr { - return true - } - } - } - - return false -} - -func hasSuccessfulSCRs(tx *data.Transaction) bool { - for _, scr := range tx.SmartContractResults { - if isScResultSuccessful(scr.Data) { - return true - } - } - - return false } -func hasCrossShardPendingTransfer(tx *data.Transaction) bool { - for _, scr := range tx.SmartContractResults { - splitData := strings.Split(string(scr.Data), data.AtSeparator) - if len(splitData) < 2 { - continue - } - - isMultiTransferOrNFTTransfer := splitData[0] == core.BuiltInFunctionESDTNFTTransfer || splitData[0] == core.BuiltInFunctionMultiESDTNFTTransfer - if !isMultiTransferOrNFTTransfer { - continue - } - - if scr.SenderShard != scr.ReceiverShard { - return true - } - } - - return false -} - -func (st *scrsDataToTransactions) processSCRsWithoutTx(scrs []*data.ScResult) (map[string]string, map[string]*data.FeeData) { - txHashStatus := make(map[string]string) +func (st *scrsDataToTransactions) processSCRsWithoutTx(scrs []*data.ScResult) map[string]*data.FeeData { txHashRefund := make(map[string]*data.FeeData) for _, scr := range scrs { - if scr.InitialTxGasUsed != 0 { - var feeNum float64 - var err error - initialTxFeeBig, ok := big.NewInt(0).SetString(scr.InitialTxFee, 10) - if ok { - feeNum, err = st.balanceConverter.ComputeESDTBalanceAsFloat(initialTxFeeBig) - } - if err != nil { - log.Warn("scrsDataToTransactions.processSCRsWithoutTx: cannot compute fee as num", - "initial Tx fee", initialTxFeeBig, "error", err) - } - - txHashRefund[scr.OriginalTxHash] = &data.FeeData{ - FeeNum: feeNum, - Fee: scr.InitialTxFee, - GasUsed: scr.InitialTxGasUsed, - Receiver: scr.Receiver, - } - } - - if !st.isESDTNFTTransferOrMultiTransferWithError(string(scr.Data)) { + if scr.InitialTxGasUsed == 0 { continue } - txHashStatus[scr.OriginalTxHash] = transaction.TxStatusFail.String() - } - - return txHashStatus, txHashRefund -} - -func (st *scrsDataToTransactions) isESDTNFTTransferOrMultiTransferWithError(scrData string) bool { - splitData := strings.Split(scrData, data.AtSeparator) - isMultiTransferOrNFTTransfer := splitData[0] == core.BuiltInFunctionESDTNFTTransfer || splitData[0] == core.BuiltInFunctionMultiESDTNFTTransfer - if !isMultiTransferOrNFTTransfer || len(splitData) < minNumOfArgumentsNFTTransferORMultiTransfer { - return false - } + var feeNum float64 + var err error + initialTxFeeBig, ok := big.NewInt(0).SetString(scr.InitialTxFee, 10) + if ok { + feeNum, err = st.balanceConverter.ComputeESDTBalanceAsFloat(initialTxFeeBig) + } + if err != nil { + log.Warn("scrsDataToTransactions.processSCRsWithoutTx: cannot compute fee as num", + "initial Tx fee", initialTxFeeBig, "error", err) + } - latestArgumentFromDataField := splitData[len(splitData)-1] - for _, retCode := range st.retCodes { - isWithError := latestArgumentFromDataField == hex.EncodeToString([]byte(retCode)) - if isWithError { - return true + txHashRefund[scr.OriginalTxHash] = &data.FeeData{ + FeeNum: feeNum, + Fee: scr.InitialTxFee, + GasUsed: scr.InitialTxGasUsed, + Receiver: scr.Receiver, } } - return false + return txHashRefund } diff --git a/process/elasticproc/transactions/scrsDataToTransactions_test.go b/process/elasticproc/transactions/scrsDataToTransactions_test.go index fddfbb1a..4858c642 100644 --- a/process/elasticproc/transactions/scrsDataToTransactions_test.go +++ b/process/elasticproc/transactions/scrsDataToTransactions_test.go @@ -88,19 +88,7 @@ func TestProcessTransactionsAfterSCRsWereAttached(t *testing.T) { } scrsDataToTxs.processTransactionsAfterSCRsWereAttached(txs) - require.Equal(t, "fail", tx1.Status) + require.Equal(t, "", tx1.Status) require.Equal(t, tx1.GasLimit, tx1.GasUsed) require.Equal(t, "168805000000000", tx1.Fee) } - -func TestIsESDTNFTTransferWithUserError(t *testing.T) { - t.Parallel() - - bc, _ := converters.NewBalanceConverter(18) - scrsDataToTxs := newScrsDataToTransactions(bc) - - require.False(t, scrsDataToTxs.isESDTNFTTransferOrMultiTransferWithError("ESDTNFTTransfer@45474c444d4558462d333766616239@06f5@045d2bd2629df0d2ea@0801120a00045d2bd2629df0d2ea226408f50d1a2000000000000000000500e809539d1d8febc54df4e6fe826fdc8ab6c88cf07ceb32003a3b00000007401c82df9c05a80000000000000407000000000000040f010000000009045d2bd2629df0d2ea0000000000000009045d2bd2629df0d2ea@636c61696d52657761726473")) - require.False(t, scrsDataToTxs.isESDTNFTTransferOrMultiTransferWithError("ESDTTransfer@4d45582d623662623764@74b7e37e3c2efe5f11@")) - require.False(t, scrsDataToTxs.isESDTNFTTransferOrMultiTransferWithError("ESDTNFTTransfer@45474c444d4558462d333766616239@070f@045d2bd2629df0d2ea@0801120a00045d2bd2629df0d2ea2264088f0e1a2000000000000000000500e809539d1d8febc54df4e6fe826fdc8ab6c88cf07ceb32003a3b000000074034d62af2b6930000000000000407000000000000040f010000000009045d2bd2629df0d2ea0000000000000009045d2bd2629df0d2ea@")) - require.True(t, scrsDataToTxs.isESDTNFTTransferOrMultiTransferWithError("MultiESDTNFTTransfer@02@5745474c442d626434643739@00@38e62046fb1a0000@584d45582d666461333535@07@0801120c00048907e58284c28e898e2922520807120a4d45582d3435356335371a20000000000000000005007afb2c871d1647372fd53a9eb3e53e5a8ec9251cb05532003a1e0000000a4d45582d343535633537000000000000000000000000000008e8@657865637574696f6e206661696c6564")) -} diff --git a/process/elasticproc/transactions/serialize.go b/process/elasticproc/transactions/serialize.go index 0d01c51b..3d3429bf 100644 --- a/process/elasticproc/transactions/serialize.go +++ b/process/elasticproc/transactions/serialize.go @@ -80,7 +80,7 @@ func (tdp *txsDatabaseProcessor) SerializeTransactionsFeeData(txHashRefund map[s // SerializeTransactions will serialize the transactions in a way that Elasticsearch expects a bulk request func (tdp *txsDatabaseProcessor) SerializeTransactions( transactions []*data.Transaction, - txHashStatus map[string]string, + txHashStatusInfo map[string]*data.StatusInfo, selfShardID uint32, buffSlice *data.BufferSlice, index string, @@ -97,7 +97,7 @@ func (tdp *txsDatabaseProcessor) SerializeTransactions( } } - err := serializeTxHashStatus(buffSlice, txHashStatus, index) + err := serializeTxHashStatus(buffSlice, txHashStatusInfo, index) if err != nil { return err } @@ -105,22 +105,46 @@ func (tdp *txsDatabaseProcessor) SerializeTransactions( return nil } -func serializeTxHashStatus(buffSlice *data.BufferSlice, txHashStatus map[string]string, index string) error { - for txHash, status := range txHashStatus { +func serializeTxHashStatus(buffSlice *data.BufferSlice, txHashStatusInfo map[string]*data.StatusInfo, index string) error { + for txHash, statusInfo := range txHashStatusInfo { metaData := []byte(fmt.Sprintf(`{"update":{ "_index":"%s","_id":"%s"}}%s`, index, txHash, "\n")) newTx := &data.Transaction{ - Status: status, + Status: statusInfo.Status, + ErrorEvent: statusInfo.ErrorEvent, + CompletedEvent: statusInfo.CompletedEvent, } marshaledTx, err := json.Marshal(newTx) if err != nil { return err } + marshaledStatusInfo, err := json.Marshal(statusInfo) + if err != nil { + return err + } codeToExecute := ` - ctx._source.status = params.status + if (params.statusInfo.status != "") { + ctx._source.status = params.statusInfo.status + } + + if (ctx._source.containsKey('completedEvent')) { + if (!ctx._source.completedEvent) { + ctx._source.completedEvent = params.statusInfo.completedEvent + } + } else { + ctx._source.completedEvent = params.statusInfo.completedEvent + } + + if (ctx._source.containsKey('errorEvent')) { + if (!ctx._source.errorEvent) { + ctx._source.errorEvent = params.statusInfo.errorEvent + } + } else { + ctx._source.errorEvent = params.statusInfo.errorEvent + } ` - serializedData := []byte(fmt.Sprintf(`{"script": {"source": "%s","lang": "painless","params": {"status": "%s"}},"upsert": %s }`, converters.FormatPainlessSource(codeToExecute), converters.JsonEscape(status), string(marshaledTx))) + serializedData := []byte(fmt.Sprintf(`{"script": {"source": "%s","lang": "painless","params": {"statusInfo": %s}},"upsert": %s }`, converters.FormatPainlessSource(codeToExecute), string(marshaledStatusInfo), string(marshaledTx))) err = buffSlice.PutData(metaData, serializedData) if err != nil { return err diff --git a/process/elasticproc/transactions/serialize_test.go b/process/elasticproc/transactions/serialize_test.go index d81dd6aa..bccad6ca 100644 --- a/process/elasticproc/transactions/serialize_test.go +++ b/process/elasticproc/transactions/serialize_test.go @@ -81,7 +81,7 @@ func TestSerializeTransactionsIntraShardTx(t *testing.T) { err := (&txsDatabaseProcessor{}).SerializeTransactions([]*data.Transaction{{ Hash: "txHash", SmartContractResults: []*data.ScResult{{}}, - }}, map[string]string{}, 0, buffSlice, "transactions") + }}, map[string]*data.StatusInfo{}, 0, buffSlice, "transactions") require.Nil(t, err) expectedBuff := `{ "index" : { "_index":"transactions", "_id" : "txHash" } } @@ -100,7 +100,7 @@ func TestSerializeTransactionCrossShardTxSource(t *testing.T) { ReceiverShard: 1, SmartContractResults: []*data.ScResult{{}}, Version: 1, - }}, map[string]string{}, 0, buffSlice, "transactions") + }}, map[string]*data.StatusInfo{}, 0, buffSlice, "transactions") require.Nil(t, err) expectedBuff := `{"update":{ "_index":"transactions", "_id":"txHash"}} @@ -119,7 +119,7 @@ func TestSerializeTransactionsCrossShardTxDestination(t *testing.T) { ReceiverShard: 0, SmartContractResults: []*data.ScResult{{}}, Version: 1, - }}, map[string]string{}, 0, buffSlice, "transactions") + }}, map[string]*data.StatusInfo{}, 0, buffSlice, "transactions") require.Nil(t, err) expectedBuff := `{ "index" : { "_index":"transactions", "_id" : "txHash" } } diff --git a/process/elasticproc/transactions/transactionsProcessor.go b/process/elasticproc/transactions/transactionsProcessor.go index d8f089e7..3c7494cf 100644 --- a/process/elasticproc/transactions/transactionsProcessor.go +++ b/process/elasticproc/transactions/transactionsProcessor.go @@ -124,7 +124,7 @@ func (tdp *txsDatabaseProcessor) PrepareTransactionsForDatabase( srcsNoTxInCurrentShard := tdp.scrsDataToTxs.attachSCRsToTransactionsAndReturnSCRsWithoutTx(normalTxs, dbSCResults) tdp.scrsDataToTxs.processTransactionsAfterSCRsWereAttached(normalTxs) - txHashStatus, txHashFee := tdp.scrsDataToTxs.processSCRsWithoutTx(srcsNoTxInCurrentShard) + txHashFee := tdp.scrsDataToTxs.processSCRsWithoutTx(srcsNoTxInCurrentShard) sliceNormalTxs := convertMapTxsToSlice(normalTxs) sliceRewardsTxs := convertMapTxsToSlice(rewardsTxs) @@ -134,7 +134,6 @@ func (tdp *txsDatabaseProcessor) PrepareTransactionsForDatabase( Transactions: txsSlice, ScResults: dbSCResults, Receipts: dbReceipts, - TxHashStatus: txHashStatus, TxHashFee: txHashFee, } } diff --git a/process/elasticproc/transactions/transactionsProcessor_test.go b/process/elasticproc/transactions/transactionsProcessor_test.go index d33c9571..f4eb6b66 100644 --- a/process/elasticproc/transactions/transactionsProcessor_test.go +++ b/process/elasticproc/transactions/transactionsProcessor_test.go @@ -662,6 +662,6 @@ func TestTxsDatabaseProcessor_IssueESDTTx(t *testing.T) { } res = txDbProc.PrepareTransactionsForDatabase(body, header, pool, false, 3) - require.Equal(t, "fail", res.Transactions[0].Status) + require.Equal(t, "success", res.Transactions[0].Status) require.Equal(t, 1, len(res.ScResults)) }