Skip to content

Commit 3f37711

Browse files
authored
Merge pull request #364 from multiversx/indexer-unexecutable-txs
Index unexecutable transactions
2 parents e0dc46b + d47cdda commit 3f37711

File tree

6 files changed

+157
-18
lines changed

6 files changed

+157
-18
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/gin-gonic/gin v1.10.0
99
github.com/google/uuid v1.6.0
1010
github.com/multiversx/mx-chain-communication-go v1.3.0
11-
github.com/multiversx/mx-chain-core-go v1.4.2-0.20251208114845-28456d47841d
11+
github.com/multiversx/mx-chain-core-go v1.4.2-0.20260130090903-7407465d70c6
1212
github.com/multiversx/mx-chain-logger-go v1.1.0
1313
github.com/multiversx/mx-chain-vm-common-go v1.6.0
1414
github.com/prometheus/client_model v0.6.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
118118
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
119119
github.com/multiversx/mx-chain-communication-go v1.3.0 h1:ziNM1dRuiR/7al2L/jGEA/a/hjurtJ/HEqgazHNt9P8=
120120
github.com/multiversx/mx-chain-communication-go v1.3.0/go.mod h1:gDVWn6zUW6aCN1YOm/FbbT5MUmhgn/L1Rmpl8EoH3Yg=
121-
github.com/multiversx/mx-chain-core-go v1.4.2-0.20251208114845-28456d47841d h1:BwBgijQGyCW4fbNyoGDky0mdRRPNuSbuTDlZZLxmMyQ=
122-
github.com/multiversx/mx-chain-core-go v1.4.2-0.20251208114845-28456d47841d/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g=
121+
github.com/multiversx/mx-chain-core-go v1.4.2-0.20260130090903-7407465d70c6 h1:OpV/546No27cXiePXupD/GCPspka98AAHLUxJAy9CII=
122+
github.com/multiversx/mx-chain-core-go v1.4.2-0.20260130090903-7407465d70c6/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g=
123123
github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k=
124124
github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM=
125125
github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM=

process/elasticproc/block/blockProcessor.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ func (bp *blockProcessor) PrepareBlockForDB(obh *outport.OutportBlockWithHeader)
137137

138138
bp.addEpochStartInfoForMeta(obh.Header, elasticBlock)
139139

140-
elasticBlock.MiniBlocksDetails = prepareMiniBlockDetails(obh.Header.GetMiniBlockHeaderHandlers(), obh.BlockData.Body, obh.TransactionPool)
140+
areProposedMBs := obh.Header.IsHeaderV3()
141+
elasticBlock.MiniBlocksDetails = prepareMiniBlockDetails(obh.Header.GetMiniBlockHeaderHandlers(), obh.BlockData.Body, obh.TransactionPool, areProposedMBs)
141142

142143
appendBlockDetailsFromIntraShardMbs(elasticBlock, obh.BlockData.IntraShardMiniBlocks, obh.TransactionPool, len(obh.Header.GetMiniBlockHeaderHandlers()))
143144

@@ -188,12 +189,12 @@ func (bp *blockProcessor) prepareExecutionResult(baseExecutionResult coreData.Ba
188189

189190
switch t := baseExecutionResult.(type) {
190191
case *nodeBlock.MetaExecutionResult:
191-
executionResult.MiniBlocksDetails = prepareMiniBlockDetails(t.GetMiniBlockHeadersHandlers(), executionResultData.Body, executionResultData.TransactionPool)
192+
executionResult.MiniBlocksDetails = prepareMiniBlockDetails(t.GetMiniBlockHeadersHandlers(), executionResultData.Body, executionResultData.TransactionPool, false)
192193
executionResult.AccumulatedFees = t.AccumulatedFees.String()
193194
executionResult.DeveloperFees = t.DeveloperFees.String()
194195
executionResult.TxCount = t.ExecutedTxCount
195196
case *nodeBlock.ExecutionResult:
196-
executionResult.MiniBlocksDetails = prepareMiniBlockDetails(t.GetMiniBlockHeadersHandlers(), executionResultData.Body, executionResultData.TransactionPool)
197+
executionResult.MiniBlocksDetails = prepareMiniBlockDetails(t.GetMiniBlockHeadersHandlers(), executionResultData.Body, executionResultData.TransactionPool, false)
197198
executionResult.AccumulatedFees = t.AccumulatedFees.String()
198199
executionResult.DeveloperFees = t.DeveloperFees.String()
199200
executionResult.TxCount = t.ExecutedTxCount
@@ -360,7 +361,7 @@ func (bp *blockProcessor) getEncodedMBSHashes(body *nodeBlock.Body, intraShardMb
360361
return miniblocksHashes
361362
}
362363

363-
func prepareMiniBlockDetails(mbHeaders []coreData.MiniBlockHeaderHandler, body *nodeBlock.Body, pool *outport.TransactionPool) []*data.MiniBlocksDetails {
364+
func prepareMiniBlockDetails(mbHeaders []coreData.MiniBlockHeaderHandler, body *nodeBlock.Body, pool *outport.TransactionPool, areProposed bool) []*data.MiniBlocksDetails {
364365
mbsDetails := make([]*data.MiniBlocksDetails, 0, len(mbHeaders))
365366
for idx, mbHeader := range mbHeaders {
366367
mbType := nodeBlock.Type(mbHeader.GetTypeInt32())
@@ -369,17 +370,22 @@ func prepareMiniBlockDetails(mbHeaders []coreData.MiniBlockHeaderHandler, body *
369370
}
370371

371372
txsHashes := body.MiniBlocks[idx].TxHashes
372-
mbsDetails = append(mbsDetails, &data.MiniBlocksDetails{
373-
IndexFirstProcessedTx: mbHeader.GetIndexOfFirstTxProcessed(),
374-
IndexLastProcessedTx: mbHeader.GetIndexOfLastTxProcessed(),
375-
MBIndex: idx,
376-
ProcessingType: nodeBlock.ProcessingType(mbHeader.GetProcessingType()).String(),
377-
Type: mbType.String(),
378-
SenderShardID: mbHeader.GetSenderShardID(),
379-
ReceiverShardID: mbHeader.GetReceiverShardID(),
380-
TxsHashes: hexEncodeSlice(txsHashes),
381-
ExecutionOrderTxsIndices: extractExecutionOrderIndicesFromPool(mbHeader, txsHashes, pool),
382-
})
373+
mbDetails := &data.MiniBlocksDetails{
374+
IndexFirstProcessedTx: mbHeader.GetIndexOfFirstTxProcessed(),
375+
IndexLastProcessedTx: mbHeader.GetIndexOfLastTxProcessed(),
376+
MBIndex: idx,
377+
ProcessingType: nodeBlock.ProcessingType(mbHeader.GetProcessingType()).String(),
378+
Type: mbType.String(),
379+
SenderShardID: mbHeader.GetSenderShardID(),
380+
ReceiverShardID: mbHeader.GetReceiverShardID(),
381+
TxsHashes: hexEncodeSlice(txsHashes),
382+
}
383+
if !areProposed {
384+
mbDetails.ExecutionOrderTxsIndices = extractExecutionOrderIndicesFromPool(mbHeader, txsHashes, pool)
385+
}
386+
387+
mbsDetails = append(mbsDetails, mbDetails)
388+
383389
}
384390

385391
return mbsDetails

process/elasticproc/transactions/transactionDBBuilder.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/multiversx/mx-chain-core-go/data/block"
1010
"github.com/multiversx/mx-chain-core-go/data/outport"
1111
"github.com/multiversx/mx-chain-core-go/data/receipt"
12+
"github.com/multiversx/mx-chain-core-go/data/transaction"
1213
"github.com/multiversx/mx-chain-es-indexer-go/data"
1314
"github.com/multiversx/mx-chain-es-indexer-go/process/dataindexer"
1415
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/converters"
@@ -35,6 +36,67 @@ func newTransactionDBBuilder(
3536
}
3637
}
3738

39+
func (dtb *dbTransactionBuilder) prepareUnexecutableTransaction(txHashHex string, tx *transaction.Transaction, headerData *data.HeaderData) *data.Transaction {
40+
res := dtb.dataFieldParser.Parse(tx.Data, tx.SndAddr, tx.RcvAddr, headerData.NumberOfShards)
41+
receiversAddr, _ := dtb.addressPubkeyConverter.EncodeSlice(res.Receivers)
42+
43+
valueNum, err := dtb.balanceConverter.ConvertBigValueToFloat(tx.Value)
44+
if err != nil {
45+
log.Warn("dbTransactionBuilder.prepareUnexecutableTransaction: cannot compute value as num", "value", tx.Value,
46+
"hash", txHashHex, "error", err)
47+
}
48+
49+
esdtValuesNum, err := dtb.balanceConverter.ComputeSliceOfStringsAsFloat(res.ESDTValues)
50+
if err != nil {
51+
log.Warn("dbTransactionBuilder.prepareTransaction: cannot compute esdt values as num",
52+
"esdt values", res.ESDTValues, "hash", txHashHex, "error", err)
53+
}
54+
55+
var esdtValues []string
56+
if areESDTValuesOK(res.ESDTValues) {
57+
esdtValues = res.ESDTValues
58+
}
59+
guardianAddress := ""
60+
if len(tx.GuardianAddr) > 0 {
61+
guardianAddress = dtb.addressPubkeyConverter.SilentEncode(tx.GuardianAddr, log)
62+
}
63+
relayedAddress := ""
64+
if len(tx.RelayerAddr) > 0 {
65+
relayedAddress = dtb.addressPubkeyConverter.SilentEncode(tx.RelayerAddr, log)
66+
}
67+
68+
return &data.Transaction{
69+
Hash: txHashHex,
70+
Nonce: tx.Nonce,
71+
Round: headerData.Round,
72+
Value: tx.Value.String(),
73+
Receiver: dtb.addressPubkeyConverter.SilentEncode(tx.RcvAddr, log),
74+
Sender: dtb.addressPubkeyConverter.SilentEncode(tx.SndAddr, log),
75+
ValueNum: valueNum,
76+
ReceiverShard: sharding.ComputeShardID(tx.RcvAddr, headerData.NumberOfShards),
77+
SenderShard: sharding.ComputeShardID(tx.SndAddr, headerData.NumberOfShards),
78+
GasPrice: tx.GasPrice,
79+
GasLimit: tx.GasLimit,
80+
Data: tx.Data,
81+
Signature: hex.EncodeToString(tx.Signature),
82+
Status: transaction.TxStatusNotExecutable.String(),
83+
IsScCall: core.IsSmartContractAddress(tx.RcvAddr),
84+
ESDTValues: esdtValues,
85+
ESDTValuesNum: esdtValuesNum,
86+
Receivers: receiversAddr,
87+
Version: tx.Version,
88+
GuardianAddress: guardianAddress,
89+
GuardianSignature: hex.EncodeToString(tx.GuardianSignature),
90+
Operation: res.Operation,
91+
RelayedSignature: hex.EncodeToString(tx.RelayerSignature),
92+
RelayedAddr: relayedAddress,
93+
UUID: converters.GenerateBase64UUID(),
94+
Epoch: headerData.Epoch,
95+
Timestamp: headerData.Timestamp,
96+
TimestampMs: headerData.TimestampMs,
97+
}
98+
}
99+
38100
func (dtb *dbTransactionBuilder) prepareTransaction(
39101
txInfo *outport.TxInfo,
40102
txHash []byte,

process/elasticproc/transactions/transactionDBBuilder_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,65 @@ func TestGetMoveBalanceTransactionInvalid(t *testing.T) {
301301
dbTx.UUID = ""
302302
require.Equal(t, expectedTx, dbTx)
303303
}
304+
305+
func TestPrepareUnexecutableTransaction(t *testing.T) {
306+
t.Parallel()
307+
308+
txHash := []byte("txHash")
309+
headerData := &data.HeaderData{
310+
Timestamp: 1234,
311+
TimestampMs: 1234000,
312+
NumberOfShards: 3,
313+
}
314+
gasPrice := uint64(1000)
315+
gasLimit := uint64(1000)
316+
cp := createCommonProcessor()
317+
318+
tx := &transaction.Transaction{
319+
Nonce: 1,
320+
Value: big.NewInt(1000),
321+
RcvAddr: []byte("receiver"),
322+
SndAddr: []byte("sender"),
323+
GasPrice: gasPrice,
324+
GasLimit: gasLimit,
325+
Data: []byte("data"),
326+
ChainID: []byte("1"),
327+
Version: 1,
328+
Signature: []byte("signature"),
329+
RcvUserName: []byte("rcv"),
330+
SndUserName: []byte("snd"),
331+
}
332+
333+
senderAddr, err := cp.addressPubkeyConverter.Encode(tx.RcvAddr)
334+
require.Nil(t, err)
335+
receiverAddr, err := cp.addressPubkeyConverter.Encode(tx.SndAddr)
336+
require.Nil(t, err)
337+
338+
expectedTx := &data.Transaction{
339+
Hash: string(txHash),
340+
Nonce: tx.Nonce,
341+
Round: headerData.Round,
342+
Value: tx.Value.String(),
343+
ValueNum: 1e-15,
344+
Receiver: senderAddr,
345+
Sender: receiverAddr,
346+
GasPrice: gasPrice,
347+
GasLimit: gasLimit,
348+
Data: tx.Data,
349+
Signature: hex.EncodeToString(tx.Signature),
350+
Status: transaction.TxStatusNotExecutable.String(),
351+
ESDTValuesNum: []float64{},
352+
Operation: "transfer",
353+
Version: 1,
354+
Receivers: []string{},
355+
Timestamp: 1234,
356+
TimestampMs: 1234000,
357+
ReceiverShard: uint32(2),
358+
SenderShard: uint32(2),
359+
}
360+
361+
dbTx := cp.prepareUnexecutableTransaction(string(txHash), tx, headerData)
362+
dbTx.UUID = ""
363+
364+
require.Equal(t, expectedTx, dbTx)
365+
}

process/elasticproc/transactions/transactionsProcessor.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ func (tdp *txsDatabaseProcessor) PrepareTransactionsForDatabase(
117117
}
118118
}
119119

120+
for hashHex, tx := range pool.UnexecutableTransactions {
121+
decodedHash, errD := hex.DecodeString(hashHex)
122+
if errD != nil {
123+
continue
124+
}
125+
126+
normalTxs[string(decodedHash)] = tdp.txBuilder.prepareUnexecutableTransaction(hashHex, tx, headerData)
127+
}
128+
120129
normalTxs = tdp.setTransactionSearchOrder(normalTxs)
121130
dbReceipts := tdp.txsGrouper.groupReceipts(headerData, pool.Receipts)
122131
dbSCResults := tdp.scrsProc.processSCRs(miniBlocks, headerData, pool.SmartContractResults)

0 commit comments

Comments
 (0)