From 5709b0b0c463e0baf74114ea2738c7e064eda0b1 Mon Sep 17 00:00:00 2001 From: miiu Date: Thu, 17 Oct 2024 13:32:33 +0300 Subject: [PATCH] treat multiple scrs --- data/scresult.go | 1 + data/transaction.go | 9 +- go.mod | 2 +- go.sum | 4 +- integrationtests/relayedTxV3_test.go | 140 ++++++++++++++++++ .../relayedTxV3/relayed-v3-no-refund.json | 58 ++++++++ .../relayed-v3-with-one-refund.json | 58 ++++++++ .../relayed-v3-with-two-refunds.json | 58 ++++++++ .../transactions/scrsDataToTransactions.go | 9 +- process/elasticproc/transactions/serialize.go | 24 ++- .../smartContractResultsProcessor.go | 1 + 11 files changed, 352 insertions(+), 12 deletions(-) create mode 100644 integrationtests/testdata/relayedTxV3/relayed-v3-no-refund.json create mode 100644 integrationtests/testdata/relayedTxV3/relayed-v3-with-one-refund.json create mode 100644 integrationtests/testdata/relayedTxV3/relayed-v3-with-two-refunds.json diff --git a/data/scresult.go b/data/scresult.go index b246528d..f3fc93ad 100644 --- a/data/scresult.go +++ b/data/scresult.go @@ -43,4 +43,5 @@ type ScResult struct { SenderAddressBytes []byte `json:"-"` InitialTxGasUsed uint64 `json:"-"` InitialTxFee string `json:"-"` + ForRelayed bool `json:"-"` } diff --git a/data/transaction.go b/data/transaction.go index 64f6347a..cde848c5 100644 --- a/data/transaction.go +++ b/data/transaction.go @@ -89,10 +89,11 @@ type ResponseTransactionDB struct { // FeeData is the structure that contains data about transaction fee and gas used type FeeData struct { - FeeNum float64 - Fee string - GasUsed uint64 - Receiver string + FeeNum float64 + Fee string + GasUsed uint64 + Receiver string + ForRelayed bool } // InnerTransaction is the structure that contains data about an inner transaction diff --git a/go.mod b/go.mod index eb32dd80..51148ec8 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/gin-contrib/cors v1.4.0 github.com/gin-gonic/gin v1.9.1 github.com/multiversx/mx-chain-communication-go v1.1.0 - github.com/multiversx/mx-chain-core-go v1.2.21 + github.com/multiversx/mx-chain-core-go v1.2.23-0.20241017083841-5e7b1485b6a1 github.com/multiversx/mx-chain-logger-go v1.0.15 github.com/multiversx/mx-chain-vm-common-go v1.5.13 github.com/prometheus/client_model v0.4.0 diff --git a/go.sum b/go.sum index 82f3a0f7..2347e509 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,8 @@ github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-communication-go v1.1.0 h1:J7bX6HoN3HiHY7cUeEjG8AJWgQDDPcY+OPDOsSUOkRE= github.com/multiversx/mx-chain-communication-go v1.1.0/go.mod h1:WK6bP4pGEHGDDna/AYRIMtl6G9OA0NByI1Lw8PmOnRM= -github.com/multiversx/mx-chain-core-go v1.2.21 h1:+XVKznPTlUU5EFS1A8chtS8fStW60upRIyF4Pgml19I= -github.com/multiversx/mx-chain-core-go v1.2.21/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= +github.com/multiversx/mx-chain-core-go v1.2.23-0.20241017083841-5e7b1485b6a1 h1:TyWMSr3wx1DR3rlKnp7Iw/nEMYDp7any7DtMpz2aAlU= +github.com/multiversx/mx-chain-core-go v1.2.23-0.20241017083841-5e7b1485b6a1/go.mod h1:B5zU4MFyJezmEzCsAHE9YNULmGCm2zbPHvl9hazNxmE= github.com/multiversx/mx-chain-crypto-go v1.2.12 h1:zWip7rpUS4CGthJxfKn5MZfMfYPjVjIiCID6uX5BSOk= github.com/multiversx/mx-chain-logger-go v1.0.15 h1:HlNdK8etyJyL9NQ+6mIXyKPEBo+wRqOwi3n+m2QIHXc= github.com/multiversx/mx-chain-logger-go v1.0.15/go.mod h1:t3PRKaWB1M+i6gUfD27KXgzLJJC+mAQiN+FLlL1yoGQ= diff --git a/integrationtests/relayedTxV3_test.go b/integrationtests/relayedTxV3_test.go index 28329ebb..6204b69f 100644 --- a/integrationtests/relayedTxV3_test.go +++ b/integrationtests/relayedTxV3_test.go @@ -380,3 +380,143 @@ func TestRelayedV3WithSCRCross(t *testing.T) { string(genericResponse.Docs[0].Source), ) } + +func TestRelayedV3TransactionWithMultipleRefunds(t *testing.T) { + setLogLevelDebug() + + esClient, err := createESClient(esURL) + require.Nil(t, err) + + esProc, err := CreateElasticProcessor(esClient) + require.Nil(t, err) + + txHash := []byte("relayedTxV3WithMultipleRefunds") + header := &dataBlock.Header{ + Round: 50, + TimeStamp: 5040, + } + + body := &dataBlock.Body{ + MiniBlocks: dataBlock.MiniBlockSlice{ + { + Type: dataBlock.TxBlock, + SenderShardID: 0, + ReceiverShardID: 0, + TxHashes: [][]byte{txHash}, + }, + }, + } + + initialTx := &transaction.Transaction{ + Nonce: 1000, + SndAddr: decodeAddress("erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a"), + RcvAddr: decodeAddress("erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a"), + GasLimit: 500_000_000, + GasPrice: 1000000000, + Value: big.NewInt(0), + InnerTransactions: []*transaction.Transaction{ + { + Nonce: 5, + SndAddr: decodeAddress("erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8"), + RcvAddr: decodeAddress("erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r"), + GasLimit: 60_000_000, + GasPrice: 1000000000, + Value: big.NewInt(10000000000000000), + Data: []byte("doSomething"), + }, + { + Nonce: 3, + SndAddr: decodeAddress("erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8"), + RcvAddr: decodeAddress("erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r"), + GasLimit: 60_000_000, + GasPrice: 1000000000, + Value: big.NewInt(10000000000000000), + Data: []byte("doSomething"), + }, + }, + } + + txInfo := &outport.TxInfo{ + Transaction: initialTx, + FeeInfo: &outport.FeeInfo{ + GasUsed: 180_150_000, + Fee: big.NewInt(2864760000000000), + InitialPaidFee: big.NewInt(2864760000000000), + }, + ExecutionOrder: 0, + } + + pool := &outport.TransactionPool{ + Transactions: map[string]*outport.TxInfo{ + hex.EncodeToString(txHash): txInfo, + }, + } + err = esProc.SaveTransactions(createOutportBlockWithHeader(body, header, pool, nil, testNumOfShards)) + require.Nil(t, err) + + ids := []string{hex.EncodeToString(txHash)} + genericResponse := &GenericResponse{} + err = esClient.DoMultiGet(context.Background(), ids, indexerdata.TransactionsIndex, true, genericResponse) + require.Nil(t, err) + + require.JSONEq(t, + readExpectedResult("./testdata/relayedTxV3/relayed-v3-no-refund.json"), + string(genericResponse.Docs[0].Source), + ) + + // execute first SCR with refund + pool = &outport.TransactionPool{ + SmartContractResults: map[string]*outport.SCRInfo{ + "scrHash": { + SmartContractResult: &smartContractResult.SmartContractResult{ + OriginalTxHash: txHash, + }, + FeeInfo: &outport.FeeInfo{ + ForRelayed: true, + GasUsed: 9_692_000, + Fee: big.NewInt(96920000000000), + }, + }, + }, + } + err = esProc.SaveTransactions(createOutportBlockWithHeader(body, header, pool, nil, testNumOfShards)) + require.Nil(t, err) + + ids = []string{hex.EncodeToString(txHash)} + genericResponse = &GenericResponse{} + err = esClient.DoMultiGet(context.Background(), ids, indexerdata.TransactionsIndex, true, genericResponse) + require.Nil(t, err) + + require.JSONEq(t, + readExpectedResult("./testdata/relayedTxV3/relayed-v3-with-one-refund.json"), + string(genericResponse.Docs[0].Source), + ) + + // execute second SCR with refund + pool = &outport.TransactionPool{ + SmartContractResults: map[string]*outport.SCRInfo{ + "scrHash": { + SmartContractResult: &smartContractResult.SmartContractResult{ + OriginalTxHash: txHash, + }, + FeeInfo: &outport.FeeInfo{ + ForRelayed: true, + GasUsed: 9_692_000, + Fee: big.NewInt(96920000000000), + }, + }, + }, + } + err = esProc.SaveTransactions(createOutportBlockWithHeader(body, header, pool, nil, testNumOfShards)) + require.Nil(t, err) + + ids = []string{hex.EncodeToString(txHash)} + genericResponse = &GenericResponse{} + err = esClient.DoMultiGet(context.Background(), ids, indexerdata.TransactionsIndex, true, genericResponse) + require.Nil(t, err) + + require.JSONEq(t, + readExpectedResult("./testdata/relayedTxV3/relayed-v3-with-two-refunds.json"), + string(genericResponse.Docs[0].Source), + ) +} diff --git a/integrationtests/testdata/relayedTxV3/relayed-v3-no-refund.json b/integrationtests/testdata/relayedTxV3/relayed-v3-no-refund.json new file mode 100644 index 00000000..cfdcd81f --- /dev/null +++ b/integrationtests/testdata/relayedTxV3/relayed-v3-no-refund.json @@ -0,0 +1,58 @@ +{ + "miniBlockHash": "785a251c08b314939528e553ac879dbee0627fbe2b76c0bca601c3f1e7162640", + "nonce": 1000, + "round": 50, + "value": "0", + "valueNum": 0, + "receiver": "erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a", + "sender": "erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a", + "receiverShard": 0, + "senderShard": 0, + "gasPrice": 1000000000, + "gasLimit": 500000000, + "gasUsed": 180150000, + "fee": "2864760000000000", + "feeNum": 0.00286476, + "initialPaidFee": "2864760000000000", + "data": null, + "signature": "", + "timestamp": 5040, + "status": "success", + "searchOrder": 0, + "receivers": [ + "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r" + ], + "receiversShardIDs": [ + 1, + 1 + ], + "operation": "transfer", + "isRelayed": true, + "innerTransactions": [ + { + "hash": "1f2283b94bcc0ff11237db3f2048c54794f0199565cdddd722d3a18bde214809", + "nonce": 5, + "value": "10000000000000000", + "receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "sender": "erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8", + "gasPrice": 1000000000, + "gasLimit": 60000000, + "data": "ZG9Tb21ldGhpbmc=", + "chainID": "", + "version": 0 + }, + { + "hash": "aeac946abbb792f91d3498bf70d7ce1a1be91f6e5acffc316066474c36c1b181", + "nonce": 3, + "value": "10000000000000000", + "receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "sender": "erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8", + "gasPrice": 1000000000, + "gasLimit": 60000000, + "data": "ZG9Tb21ldGhpbmc=", + "chainID": "", + "version": 0 + } + ] +} \ No newline at end of file diff --git a/integrationtests/testdata/relayedTxV3/relayed-v3-with-one-refund.json b/integrationtests/testdata/relayedTxV3/relayed-v3-with-one-refund.json new file mode 100644 index 00000000..b94735a5 --- /dev/null +++ b/integrationtests/testdata/relayedTxV3/relayed-v3-with-one-refund.json @@ -0,0 +1,58 @@ +{ + "miniBlockHash": "785a251c08b314939528e553ac879dbee0627fbe2b76c0bca601c3f1e7162640", + "nonce": 1000, + "round": 50, + "value": "0", + "valueNum": 0, + "receiver": "erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a", + "sender": "erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a", + "receiverShard": 0, + "senderShard": 0, + "gasPrice": 1000000000, + "gasLimit": 500000000, + "gasUsed": 170458000, + "fee": "2767840000000000", + "feeNum": 0.00276784, + "initialPaidFee": "2864760000000000", + "data": null, + "signature": "", + "timestamp": 5040, + "status": "success", + "searchOrder": 0, + "receivers": [ + "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r" + ], + "receiversShardIDs": [ + 1, + 1 + ], + "operation": "transfer", + "isRelayed": true, + "innerTransactions": [ + { + "hash": "1f2283b94bcc0ff11237db3f2048c54794f0199565cdddd722d3a18bde214809", + "nonce": 5, + "value": "10000000000000000", + "receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "sender": "erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8", + "gasPrice": 1000000000, + "gasLimit": 60000000, + "data": "ZG9Tb21ldGhpbmc=", + "chainID": "", + "version": 0 + }, + { + "hash": "aeac946abbb792f91d3498bf70d7ce1a1be91f6e5acffc316066474c36c1b181", + "nonce": 3, + "value": "10000000000000000", + "receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "sender": "erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8", + "gasPrice": 1000000000, + "gasLimit": 60000000, + "data": "ZG9Tb21ldGhpbmc=", + "chainID": "", + "version": 0 + } + ] +} diff --git a/integrationtests/testdata/relayedTxV3/relayed-v3-with-two-refunds.json b/integrationtests/testdata/relayedTxV3/relayed-v3-with-two-refunds.json new file mode 100644 index 00000000..7c6c3607 --- /dev/null +++ b/integrationtests/testdata/relayedTxV3/relayed-v3-with-two-refunds.json @@ -0,0 +1,58 @@ +{ + "miniBlockHash": "785a251c08b314939528e553ac879dbee0627fbe2b76c0bca601c3f1e7162640", + "nonce": 1000, + "round": 50, + "value": "0", + "valueNum": 0, + "receiver": "erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a", + "sender": "erd1ykqd64fxxpp4wsz0v7sjqem038wfpzlljhx4mhwx8w9lcxmdzcfszrp64a", + "receiverShard": 0, + "senderShard": 0, + "gasPrice": 1000000000, + "gasLimit": 500000000, + "gasUsed": 160766000, + "fee": "2670920000000000", + "feeNum": 0.0026709200000000002, + "initialPaidFee": "2864760000000000", + "data": null, + "signature": "", + "timestamp": 5040, + "status": "success", + "searchOrder": 0, + "receivers": [ + "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r" + ], + "receiversShardIDs": [ + 1, + 1 + ], + "operation": "transfer", + "isRelayed": true, + "innerTransactions": [ + { + "hash": "1f2283b94bcc0ff11237db3f2048c54794f0199565cdddd722d3a18bde214809", + "nonce": 5, + "value": "10000000000000000", + "receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "sender": "erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8", + "gasPrice": 1000000000, + "gasLimit": 60000000, + "data": "ZG9Tb21ldGhpbmc=", + "chainID": "", + "version": 0 + }, + { + "hash": "aeac946abbb792f91d3498bf70d7ce1a1be91f6e5acffc316066474c36c1b181", + "nonce": 3, + "value": "10000000000000000", + "receiver": "erd1aduqqezzw0u3j7tywlq3mrl0yn4z6f6vytdju8gg0neq38fauyzsa5yy6r", + "sender": "erd10ksryjr065ad5475jcg82pnjfg9j9qtszjsrp24anl6ym7cmeddshwnru8", + "gasPrice": 1000000000, + "gasLimit": 60000000, + "data": "ZG9Tb21ldGhpbmc=", + "chainID": "", + "version": 0 + } + ] +} diff --git a/process/elasticproc/transactions/scrsDataToTransactions.go b/process/elasticproc/transactions/scrsDataToTransactions.go index f18aa741..13b509ea 100644 --- a/process/elasticproc/transactions/scrsDataToTransactions.go +++ b/process/elasticproc/transactions/scrsDataToTransactions.go @@ -70,10 +70,11 @@ func (st *scrsDataToTransactions) processSCRsWithoutTx(scrs []*data.ScResult) ma } txHashRefund[scr.OriginalTxHash] = &data.FeeData{ - FeeNum: feeNum, - Fee: scr.InitialTxFee, - GasUsed: scr.InitialTxGasUsed, - Receiver: scr.Receiver, + FeeNum: feeNum, + Fee: scr.InitialTxFee, + GasUsed: scr.InitialTxGasUsed, + Receiver: scr.Receiver, + ForRelayed: scr.ForRelayed, } } diff --git a/process/elasticproc/transactions/serialize.go b/process/elasticproc/transactions/serialize.go index 939742a0..0ece7737 100644 --- a/process/elasticproc/transactions/serialize.go +++ b/process/elasticproc/transactions/serialize.go @@ -51,7 +51,28 @@ func (tdp *txsDatabaseProcessor) SerializeReceipts(receipts []*data.Receipt, buf func (tdp *txsDatabaseProcessor) SerializeTransactionsFeeData(txHashRefund map[string]*data.FeeData, buffSlice *data.BufferSlice, index string) error { for txHash, feeData := range txHashRefund { meta := []byte(fmt.Sprintf(`{"update":{ "_index":"%s","_id":"%s"}}%s`, index, converters.JsonEscape(txHash), "\n")) - codeToExecute := ` + + var codeToExecute string + if feeData.ForRelayed { + codeToExecute = ` + if ('create' == ctx.op) { + ctx.op = 'noop' + } else { + BigInteger feeFromSource = new BigInteger(ctx._source.fee); + BigInteger fee = new BigInteger(params.fee); + if (feeFromSource.compareTo(fee) > 0) { + ctx._source.fee = feeFromSource.subtract(fee).toString(); + } + if (ctx._source.feeNum > params.feeNum) { + ctx._source.feeNum -= params.feeNum; + } + if (ctx._source.gasUsed > params.gasUsed) { + ctx._source.gasUsed -= params.gasUsed; + } + } +` + } else { + codeToExecute = ` if ('create' == ctx.op) { ctx.op = 'noop' } else { @@ -60,6 +81,7 @@ func (tdp *txsDatabaseProcessor) SerializeTransactionsFeeData(txHashRefund map[s ctx._source.gasUsed = params.gasUsed; } ` + } serializedDataStr := fmt.Sprintf(`{"scripted_upsert": true, "script": {`+ `"source": "%s",`+ diff --git a/process/elasticproc/transactions/smartContractResultsProcessor.go b/process/elasticproc/transactions/smartContractResultsProcessor.go index 2fcb7ccf..5a3797b4 100644 --- a/process/elasticproc/transactions/smartContractResultsProcessor.go +++ b/process/elasticproc/transactions/smartContractResultsProcessor.go @@ -189,6 +189,7 @@ func (proc *smartContractResultsProcessor) prepareSmartContractResult( OriginalSender: originalSenderAddr, InitialTxFee: feeInfo.Fee.String(), InitialTxGasUsed: feeInfo.GasUsed, + ForRelayed: feeInfo.ForRelayed, ExecutionOrder: int(scrInfo.ExecutionOrder), } }