Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inner transactions in operations index #298

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 70 additions & 49 deletions data/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,59 @@ package data

import (
"time"

"github.com/multiversx/mx-chain-core-go/data/transaction"
)

// Transaction is a structure containing all the fields that need
// to be saved for a transaction. It has all the default fields
// plus some extra information for ease of search and filter
type Transaction struct {
MBHash string `json:"miniBlockHash"`
Nonce uint64 `json:"nonce"`
Round uint64 `json:"round"`
Value string `json:"value"`
ValueNum float64 `json:"valueNum"`
Receiver string `json:"receiver"`
Sender string `json:"sender"`
ReceiverShard uint32 `json:"receiverShard"`
SenderShard uint32 `json:"senderShard"`
GasPrice uint64 `json:"gasPrice"`
GasLimit uint64 `json:"gasLimit"`
GasUsed uint64 `json:"gasUsed"`
Fee string `json:"fee"`
FeeNum float64 `json:"feeNum"`
InitialPaidFee string `json:"initialPaidFee,omitempty"`
Data []byte `json:"data"`
Signature string `json:"signature"`
Timestamp time.Duration `json:"timestamp"`
Status string `json:"status"`
SearchOrder uint32 `json:"searchOrder"`
SenderUserName []byte `json:"senderUserName,omitempty"`
ReceiverUserName []byte `json:"receiverUserName,omitempty"`
HasSCR bool `json:"hasScResults,omitempty"`
IsScCall bool `json:"isScCall,omitempty"`
HasOperations bool `json:"hasOperations,omitempty"`
HasLogs bool `json:"hasLogs,omitempty"`
Tokens []string `json:"tokens,omitempty"`
ESDTValues []string `json:"esdtValues,omitempty"`
ESDTValuesNum []float64 `json:"esdtValuesNum,omitempty"`
Receivers []string `json:"receivers,omitempty"`
ReceiversShardIDs []uint32 `json:"receiversShardIDs,omitempty"`
Type string `json:"type,omitempty"`
Operation string `json:"operation,omitempty"`
Function string `json:"function,omitempty"`
IsRelayed bool `json:"isRelayed,omitempty"`
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"`
RelayedAddr string `json:"relayed,omitempty"`
InnerTransactions []*transaction.FrontendTransaction `json:"innerTransactions,omitempty"`
ExecutionOrder int `json:"-"`
SmartContractResults []*ScResult `json:"-"`
Hash string `json:"-"`
BlockHash string `json:"-"`
HadRefund bool `json:"-"`
MBHash string `json:"miniBlockHash"`
Nonce uint64 `json:"nonce"`
Round uint64 `json:"round"`
Value string `json:"value"`
ValueNum float64 `json:"valueNum"`
Receiver string `json:"receiver"`
Sender string `json:"sender"`
ReceiverShard uint32 `json:"receiverShard"`
SenderShard uint32 `json:"senderShard"`
GasPrice uint64 `json:"gasPrice"`
GasLimit uint64 `json:"gasLimit"`
GasUsed uint64 `json:"gasUsed"`
Fee string `json:"fee"`
FeeNum float64 `json:"feeNum"`
InitialPaidFee string `json:"initialPaidFee,omitempty"`
Data []byte `json:"data"`
Signature string `json:"signature"`
Timestamp time.Duration `json:"timestamp"`
Status string `json:"status"`
SearchOrder uint32 `json:"searchOrder"`
SenderUserName []byte `json:"senderUserName,omitempty"`
ReceiverUserName []byte `json:"receiverUserName,omitempty"`
HasSCR bool `json:"hasScResults,omitempty"`
IsScCall bool `json:"isScCall,omitempty"`
HasOperations bool `json:"hasOperations,omitempty"`
HasLogs bool `json:"hasLogs,omitempty"`
Tokens []string `json:"tokens,omitempty"`
ESDTValues []string `json:"esdtValues,omitempty"`
ESDTValuesNum []float64 `json:"esdtValuesNum,omitempty"`
Receivers []string `json:"receivers,omitempty"`
ReceiversShardIDs []uint32 `json:"receiversShardIDs,omitempty"`
Type string `json:"type,omitempty"`
Operation string `json:"operation,omitempty"`
Function string `json:"function,omitempty"`
IsRelayed bool `json:"isRelayed,omitempty"`
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"`
RelayedAddr string `json:"relayed,omitempty"`
InnerTransactions []*InnerTransaction `json:"innerTransactions,omitempty"`
ExecutionOrder int `json:"-"`
SmartContractResults []*ScResult `json:"-"`
Hash string `json:"-"`
BlockHash string `json:"-"`
HadRefund bool `json:"-"`
}

// Receipt is a structure containing all the fields that need to be safe for a Receipt
Expand Down Expand Up @@ -96,3 +94,26 @@ type FeeData struct {
GasUsed uint64
Receiver string
}

// InnerTransaction is the structure that contains data about an inner transaction
type InnerTransaction struct {
Hash string `json:"hash,omitempty"`
Type string `json:"type,omitempty"`
Nonce uint64 `json:"nonce"`
Value string `json:"value"`
Receiver string `json:"receiver"`
Sender string `json:"sender"`
SenderUsername []byte `json:"senderUsername,omitempty"`
ReceiverUsername []byte `json:"receiverUsername,omitempty"`
GasPrice uint64 `json:"gasPrice"`
GasLimit uint64 `json:"gasLimit"`
Data []byte `json:"data,omitempty"`
Signature string `json:"signature,omitempty"`
ChainID string `json:"chainID"`
Version uint32 `json:"version"`
Options uint32 `json:"options,omitempty"`
GuardianAddr string `json:"guardian,omitempty"`
GuardianSignature string `json:"guardianSignature,omitempty"`
Relayer string `json:"relayer,omitempty"`
RelayedTxHash string `json:"relayedTxHash,omitempty"`
}
13 changes: 13 additions & 0 deletions integrationtests/relayedTxV3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ func TestRelayedTxV3(t *testing.T) {
readExpectedResult("./testdata/relayedTxV3/relayed-tx-v3.json"),
string(genericResponse.Docs[0].Source),
)

ids = []string{"13b41efddcb2c01dbaba26ebc387a7f58a4ea0757a73420267818224f939e77a", "f8b8b93e42afb737a59dd622af054e34d970663b09b90138e7dc2712565ca8db"}
err = esClient.DoMultiGet(context.Background(), ids, indexerdata.OperationsIndex, true, genericResponse)
require.Nil(t, err)

require.JSONEq(t,
readExpectedResult("./testdata/relayedTxV3/innerTx1.json"),
string(genericResponse.Docs[0].Source),
)
require.JSONEq(t,
readExpectedResult("./testdata/relayedTxV3/innerTx2.json"),
string(genericResponse.Docs[1].Source),
)
}

func TestRelayedTxV3WithSignalErrorAndCompletedEvent(t *testing.T) {
Expand Down
12 changes: 12 additions & 0 deletions integrationtests/testdata/relayedTxV3/innerTx1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "innerTx",
"nonce": 20,
"value": "1000",
"receiver": "erd14eyayfrvlrhzfrwg5zwleua25mkzgncggn35nvc6xhv5yxwml2es0f3dht",
"sender": "erd1k7j6ewjsla4zsgv8v6f6fe3dvrkgv3d0d9jerczw45hzedhyed8sh2u34u",
"gasPrice": 1000000000,
"gasLimit": 15406000,
"chainID": "",
"version": 0,
"relayedTxHash": "72656c6179656454785633"
}
12 changes: 12 additions & 0 deletions integrationtests/testdata/relayedTxV3/innerTx2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "innerTx",
"nonce": 10,
"value": "0",
"receiver": "erd14eyayfrvlrhzfrwg5zwleua25mkzgncggn35nvc6xhv5yxwml2es0f3dht",
"sender": "erd1k7j6ewjsla4zsgv8v6f6fe3dvrkgv3d0d9jerczw45hzedhyed8sh2u34u",
"gasPrice": 1000000000,
"gasLimit": 15406000,
"chainID": "",
"version": 0,
"relayedTxHash": "72656c6179656454785633"
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"completedEvent": true,
"innerTransactions": [
{
"hash": "0521127b7d727e5d5e82ce963870ac16dde71f438b5dc2a64bd476ad3b8e96c2",
"nonce": 5,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand All @@ -47,6 +48,7 @@
"version": 0
},
{
"hash": "c4d7ee5288fb2f02789e36970a2b22d977870e506eb6df07e10aad12aaf67dbd",
"nonce": 3,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand All @@ -57,6 +59,7 @@
"version": 0
},
{
"hash": "5ab08906cd2d05abaca912fa450df5fb6f9cf64481f649d118f8fd14aa81b1be",
"nonce": 4,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand Down
2 changes: 2 additions & 0 deletions integrationtests/testdata/relayedTxV3/relayed-tx-v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"isRelayed": true,
"innerTransactions": [
{
"hash": "f8b8b93e42afb737a59dd622af054e34d970663b09b90138e7dc2712565ca8db",
"nonce": 10,
"value": "0",
"receiver": "erd14eyayfrvlrhzfrwg5zwleua25mkzgncggn35nvc6xhv5yxwml2es0f3dht",
Expand All @@ -41,6 +42,7 @@
"version": 0
},
{
"hash": "13b41efddcb2c01dbaba26ebc387a7f58a4ea0757a73420267818224f939e77a",
"nonce": 20,
"value": "1000",
"receiver": "erd14eyayfrvlrhzfrwg5zwleua25mkzgncggn35nvc6xhv5yxwml2es0f3dht",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"errorEvent": true,
"innerTransactions": [
{
"hash": "0521127b7d727e5d5e82ce963870ac16dde71f438b5dc2a64bd476ad3b8e96c2",
"nonce": 5,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand All @@ -45,6 +46,7 @@
"version": 0
},
{
"hash": "c4d7ee5288fb2f02789e36970a2b22d977870e506eb6df07e10aad12aaf67dbd",
"nonce": 3,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"completedEvent": true,
"innerTransactions": [
{
"hash": "0521127b7d727e5d5e82ce963870ac16dde71f438b5dc2a64bd476ad3b8e96c2",
"nonce": 5,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand All @@ -44,6 +45,7 @@
"version": 0
},
{
"hash": "c4d7ee5288fb2f02789e36970a2b22d977870e506eb6df07e10aad12aaf67dbd",
"nonce": 3,
"value": "10000000000000000",
"receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r",
Expand Down
3 changes: 3 additions & 0 deletions process/dataindexer/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,8 @@ var ErrNilBalanceConverter = errors.New("nil balance converter")
// ErrNilOperationsHandler signals that a nil operations handler has been provided
var ErrNilOperationsHandler = errors.New("nil operations handler")

// ErrNilInnerTxsHandler signals that a nil inner transaction handler has been provided
var ErrNilInnerTxsHandler = errors.New("nil inner transactions handler")

// ErrNilBlockContainerHandler signals that a nil block container handler has been provided
var ErrNilBlockContainerHandler = errors.New("nil bock container handler")
3 changes: 3 additions & 0 deletions process/elasticproc/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ func checkArguments(arguments *ArgElasticProcessor) error {
if check.IfNilReflect(arguments.OperationsProc) {
return elasticIndexer.ErrNilOperationsHandler
}
if check.IfNilReflect(arguments.InnerTxsHandler) {
return elasticIndexer.ErrNilInnerTxsHandler
}

return nil
}
11 changes: 10 additions & 1 deletion process/elasticproc/elasticProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type ArgElasticProcessor struct {
DBClient DatabaseClientHandler
LogsAndEventsProc DBLogsAndEventsHandler
OperationsProc OperationsHandler
InnerTxsHandler InnerTxsHandler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing nil check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the check for nil is the check.go file and it's done on line 82.

Version string
}

Expand All @@ -73,6 +74,7 @@ type elasticProcessor struct {
validatorsProc DBValidatorsHandler
logsAndEventsProc DBLogsAndEventsHandler
operationsProc OperationsHandler
innerTxsHandler InnerTxsHandler
}

// NewElasticProcessor handles Elasticsearch operations such as initialization, adding, modifying or removing data
Expand All @@ -94,6 +96,7 @@ func NewElasticProcessor(arguments *ArgElasticProcessor) (*elasticProcessor, err
logsAndEventsProc: arguments.LogsAndEventsProc,
operationsProc: arguments.OperationsProc,
bulkRequestMaxSize: arguments.BulkRequestMaxSize,
innerTxsHandler: arguments.InnerTxsHandler,
}

err = ei.init(arguments.UseKibana, arguments.IndexTemplates, arguments.IndexPolicies, arguments.ExtraMappings)
Expand Down Expand Up @@ -584,9 +587,15 @@ func (ei *elasticProcessor) prepareAndIndexOperations(
return nil
}

innerTxs := ei.innerTxsHandler.ExtractInnerTxs(txs)
err := ei.innerTxsHandler.SerializeInnerTxs(innerTxs, buffSlice, elasticIndexer.OperationsIndex)
if err != nil {
return err
}

processedTxs, processedSCRs := ei.operationsProc.ProcessTransactionsAndSCRs(txs, scrs, isImportDB, header.GetShardID())

err := ei.transactionsProc.SerializeTransactions(processedTxs, txHashStatusInfo, header.GetShardID(), buffSlice, elasticIndexer.OperationsIndex)
err = ei.transactionsProc.SerializeTransactions(processedTxs, txHashStatusInfo, header.GetShardID(), buffSlice, elasticIndexer.OperationsIndex)
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions process/elasticproc/elasticProcessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/accounts"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/block"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/converters"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/innerTxs"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/logsevents"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/miniblocks"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/operations"
Expand Down Expand Up @@ -73,6 +74,7 @@ func createMockElasticProcessorArgs() *ArgElasticProcessor {
}
lp, _ := logsevents.NewLogsAndEventsProcessor(args)
op, _ := operations.NewOperationsProcessor()
ip := innerTxs.NewInnerTxsProcessor()

return &ArgElasticProcessor{
DBClient: &mock.DatabaseWriterStub{},
Expand All @@ -87,6 +89,7 @@ func createMockElasticProcessorArgs() *ArgElasticProcessor {
BlockProc: bp,
LogsAndEventsProc: lp,
OperationsProc: op,
InnerTxsHandler: ip,
}
}

Expand Down
2 changes: 2 additions & 0 deletions process/elasticproc/factory/elasticProcessorFactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/accounts"
blockProc "github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/block"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/converters"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/innerTxs"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/logsevents"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/miniblocks"
"github.com/multiversx/mx-chain-es-indexer-go/process/elasticproc/operations"
Expand Down Expand Up @@ -127,6 +128,7 @@ func CreateElasticProcessor(arguments ArgElasticProcessorFactory) (dataindexer.E
OperationsProc: operationsProc,
ImportDB: arguments.ImportDB,
Version: arguments.Version,
InnerTxsHandler: innerTxs.NewInnerTxsProcessor(),
}

return elasticproc.NewElasticProcessor(args)
Expand Down
32 changes: 32 additions & 0 deletions process/elasticproc/innerTxs/innerTxsProcessor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package innerTxs

import "github.com/multiversx/mx-chain-es-indexer-go/data"

// InnerTxType is the type for an inner transaction
const InnerTxType = "innerTx"

type innerTxsProcessor struct {
}

// NewInnerTxsProcessor will create a new instance of inner transactions processor
func NewInnerTxsProcessor() *innerTxsProcessor {
return &innerTxsProcessor{}
}

// ExtractInnerTxs will extract the inner transactions from the transaction array
func (ip *innerTxsProcessor) ExtractInnerTxs(
txs []*data.Transaction,
) []*data.InnerTransaction {
innerTxs := make([]*data.InnerTransaction, 0)
for _, tx := range txs {
for _, innerTx := range tx.InnerTransactions {
innerTxCopy := *innerTx

innerTxCopy.Type = InnerTxType
innerTxCopy.RelayedTxHash = tx.Hash
innerTxs = append(innerTxs, &innerTxCopy)
}
}

return innerTxs
}
Loading
Loading