Skip to content

Commit

Permalink
- added support for v2 relayed transactions as well
Browse files Browse the repository at this point in the history
  • Loading branch information
iulianpascalau committed Feb 14, 2024
1 parent a977822 commit 2dc3755
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 13 deletions.
3 changes: 3 additions & 0 deletions process/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import (
proxyData "github.com/multiversx/mx-chain-proxy-go/data"
)

// RelayedTxV2DataMarker -
const RelayedTxV2DataMarker = relayedTxV2DataMarker

// SetDelayForCheckingNodesSyncState -
func (bp *BaseProcessor) SetDelayForCheckingNodesSyncState(delay time.Duration) {
bp.delayForCheckingNodesSyncState = delay
Expand Down
57 changes: 57 additions & 0 deletions process/testdata/finishedOKRelayedV2TxIntraShard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"transaction": {
"type": "normal",
"processingTypeOnSource": "RelayedTxV2",
"processingTypeOnDestination": "RelayedTxV2",
"hash": "47845341c9bf9172fdb8ebc8a7db729ff91c66c8d708e042af7a0b3f6a3c337e",
"nonce": 0,
"round": 1590,
"epoch": 7,
"value": "0",
"receiver": "erd1jrvq9emyfd97xs2kq53qedkz4sv40aayjt7tjcw9x6kjujvuv8uqnww788",
"sender": "erd19al0qr2zcgu067sku2m86djxp5dexle6we2lrlm63z29q2yawfsqmnxk78",
"data": "cmVsYXllZFR4VjJAYWY2ZjM2M2E4NWVkNmRjYWQwMDJkNjRhMzdlMmMyMmQwYWVjYTEzNWY0MWZlM2UwYjhhNDlkYzAwNWZkZDNhOEAwMUA3MjYxNmU2NDZmNmRAZDVjNDRiNDk5MTI3ZDA3ZWE5YTdhYTgyMDVlYjUxMmMyYzRmYzhjZTA2NzcwN2QxMWZkNmI2NmI0ZmEzYWQwMWRiNzk4ODY2YzEyMzM3Y2JjODYyZWMzMzllNzAzMzBlMGZkZGQyZTBjZTViNGUzOGYxYzdjZGM0ZTczYWFmMDU=",
"notarizedAtSourceInMetaNonce": 1477,
"NotarizedAtSourceInMetaHash": "20d21f4610e5c997a82ede2e9da9bb6ba4e806488829a5e88d74ec6f735979a5",
"notarizedAtDestinationInMetaNonce": 1477,
"notarizedAtDestinationInMetaHash": "20d21f4610e5c997a82ede2e9da9bb6ba4e806488829a5e88d74ec6f735979a5",
"smartContractResults": [
{
"hash": "SCR-hash1",
"receiver": "erd14ahnvw59a4ku45qz6e9r0ckz959wegf47s078c9c5jwuqp0a6w5qgfjy87",
"sender": "erd1jrvq9emyfd97xs2kq53qedkz4sv40aayjt7tjcw9x6kjujvuv8uqnww788",
"relayerAddress": "erd19al0qr2zcgu067sku2m86djxp5dexle6we2lrlm63z29q2yawfsqmnxk78",
"data": "random",
"operation": "transfer"
}
],
"status": "success",
"receivers": [
"erd14ahnvw59a4ku45qz6e9r0ckz959wegf47s078c9c5jwuqp0a6w5qgfjy87"
],
"receiversShardIDs": [
0
],
"operation": "transfer",
"initiallyPaidFee": "481500000000000",
"fee": "481500000000000",
"isRelayed": true,
"chainID": "1",
"version": 1,
"options": 0
},
"scrs": [
{
"type": "unsigned",
"processingTypeOnSource": "MoveBalance",
"processingTypeOnDestination": "MoveBalance",
"hash": "SCR-hash1",
"receiver": "erd14ahnvw59a4ku45qz6e9r0ckz959wegf47s078c9c5jwuqp0a6w5qgfjy87",
"sender": "erd1jrvq9emyfd97xs2kq53qedkz4sv40aayjt7tjcw9x6kjujvuv8uqnww788",
"data": "cmFuZG9t",
"miniblockType": "SmartContractResultBlock",
"callType": "directCall",
"relayerAddress": "erd19al0qr2zcgu067sku2m86djxp5dexle6we2lrlm63z29q2yawfsqmnxk78"
}
]
}
43 changes: 43 additions & 0 deletions process/testdata/malformedRelayedV2TxIntraShard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"transaction": {
"type": "normal",
"processingTypeOnSource": "RelayedTxV2",
"processingTypeOnDestination": "RelayedTxV2",
"hash": "47845341c9bf9172fdb8ebc8a7db729ff91c66c8d708e042af7a0b3f6a3c337e",
"nonce": 0,
"round": 1590,
"epoch": 7,
"value": "0",
"receiver": "erd1jrvq9emyfd97xs2kq53qedkz4sv40aayjt7tjcw9x6kjujvuv8uqnww788",
"sender": "erd19al0qr2zcgu067sku2m86djxp5dexle6we2lrlm63z29q2yawfsqmnxk78",
"data": "cmVsYXllZFR4VjJAYWY2ZjM2M2E4NWVkNmRjYWQwMDJkNjRhMzdlMmMyMmQwYWVjYTEzNWY0MWZlM2UwYjhhNDlkYzAwNWZkZDNhOEAwMUA3MjYxNmU2NDZmNmRAZDVjNDRiNDk5MTI3ZDA3ZWE5YTdhYTgyMDVlYjUxMmMyYzRmYzhjZTA2NzcwN2QxMWZkNmI2NmI0ZmEzYWQwMWRiNzk4ODY2YzEyMzM3Y2JjODYyZWMzMzllNzAzMzBlMGZkZGQyZTBjZTViNGUzOGYxYzdjZGM0ZTczYWFmMDU=",
"notarizedAtSourceInMetaNonce": 1477,
"NotarizedAtSourceInMetaHash": "20d21f4610e5c997a82ede2e9da9bb6ba4e806488829a5e88d74ec6f735979a5",
"notarizedAtDestinationInMetaNonce": 1477,
"notarizedAtDestinationInMetaHash": "20d21f4610e5c997a82ede2e9da9bb6ba4e806488829a5e88d74ec6f735979a5",
"smartContractResults": [
{
"hash": "SCR-hash1",
"receiver": "erd14ahnvw59a4ku45qz6e9r0ckz959wegf47s078c9c5jwuqp0a6w5qgfjy87",
"sender": "erd1jrvq9emyfd97xs2kq53qedkz4sv40aayjt7tjcw9x6kjujvuv8uqnww788",
"relayerAddress": "erd19al0qr2zcgu067sku2m86djxp5dexle6we2lrlm63z29q2yawfsqmnxk78",
"data": "random",
"operation": "transfer"
}
],
"status": "success",
"receivers": [
"erd14ahnvw59a4ku45qz6e9r0ckz959wegf47s078c9c5jwuqp0a6w5qgfjy87"
],
"receiversShardIDs": [
0
],
"operation": "transfer",
"initiallyPaidFee": "481500000000000",
"fee": "481500000000000",
"isRelayed": true,
"chainID": "1",
"version": 1,
"options": 0
}
}
74 changes: 61 additions & 13 deletions process/transactionProcessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ const (
nonceGapsParam = "?nonce-gaps=true"
internalVMErrorsEventIdentifier = "internalVMErrors" // TODO export this in mx-chain-core-go, remove unexported definitions from mx-chain-vm's
moveBalanceDescriptor = "MoveBalance"
relayedTransactionDescriptor = "RelayedTx"
relayedV1TransactionDescriptor = "RelayedTx"
relayedV2TransactionDescriptor = "RelayedTxV2"
relayedTxV1DataMarker = "relayedTx@"
relayedTxV2DataMarker = "relayedTxV2"
argumentsSeparator = "@"
)

type requestType int
Expand Down Expand Up @@ -504,7 +507,7 @@ func (tp *TransactionProcessor) addMissingLogsOnProcessingExceptions(
allLogs []*transaction.ApiLogs,
allScrs []*transaction.ApiTransactionResult,
) ([]*transaction.ApiLogs, error) {
newLogs, err := tp.handleIntraShardRelayedV1MoveBalanceTransactions(tx, allScrs)
newLogs, err := tp.handleIntraShardRelayedMoveBalanceTransactions(tx, allScrs)
if err != nil {
return nil, err
}
Expand All @@ -514,12 +517,12 @@ func (tp *TransactionProcessor) addMissingLogsOnProcessingExceptions(
return allLogs, nil
}

func (tp *TransactionProcessor) handleIntraShardRelayedV1MoveBalanceTransactions(
func (tp *TransactionProcessor) handleIntraShardRelayedMoveBalanceTransactions(
tx *transaction.ApiTransactionResult,
allScrs []*transaction.ApiTransactionResult,
) ([]*transaction.ApiLogs, error) {
var newLogs []*transaction.ApiLogs
isIntraShardRelayedV1MoveBalanceTransaction, err := tp.isIntraShardRelayedV1MoveBalanceTransaction(tx, allScrs)
isIntraShardRelayedV1MoveBalanceTransaction, err := tp.isIntraShardRelayedMoveBalanceTransaction(tx, allScrs)
if err != nil {
return newLogs, err
}
Expand All @@ -539,7 +542,7 @@ func (tp *TransactionProcessor) handleIntraShardRelayedV1MoveBalanceTransactions
return newLogs, nil
}

func (tp *TransactionProcessor) isIntraShardRelayedV1MoveBalanceTransaction(
func (tp *TransactionProcessor) isIntraShardRelayedMoveBalanceTransaction(
tx *transaction.ApiTransactionResult,
allScrs []*transaction.ApiTransactionResult,
) (bool, error) {
Expand All @@ -548,7 +551,10 @@ func (tp *TransactionProcessor) isIntraShardRelayedV1MoveBalanceTransaction(
return false, nil
}

isRelayedTransaction := tx.ProcessingTypeOnSource == relayedTransactionDescriptor && tx.ProcessingTypeOnDestination == relayedTransactionDescriptor
isRelayedV1 := tx.ProcessingTypeOnSource == relayedV1TransactionDescriptor && tx.ProcessingTypeOnDestination == relayedV1TransactionDescriptor
isRelayedV2 := tx.ProcessingTypeOnSource == relayedV2TransactionDescriptor && tx.ProcessingTypeOnDestination == relayedV2TransactionDescriptor

isRelayedTransaction := isRelayedV1 || isRelayedV2
if !isRelayedTransaction {
return false, nil
}
Expand All @@ -572,12 +578,33 @@ func (tp *TransactionProcessor) isIntraShardRelayedV1MoveBalanceTransaction(
return false, err
}

dataField := string(tx.Data)
if strings.Index(dataField, relayedTxV1DataMarker) != 0 {
isSameShardOnRelayed := tp.proc.GetShardCoordinator().SameShard(senderAddress, receiverAddress)
isInnerTxSameShard, err := tp.isSameShardSenderReceiverOfInnerTx(senderAddress, tx)

return isSameShardOnRelayed && isInnerTxSameShard, err
}

func (tp *TransactionProcessor) isSameShardSenderReceiverOfInnerTx(
relayedSender []byte,
relayedTx *transaction.ApiTransactionResult,
) (bool, error) {
if relayedTx.ProcessingTypeOnSource == relayedV1TransactionDescriptor {
return tp.isSameShardSenderReceiverOfInnerTxV1(relayedSender, relayedTx)
}

return tp.isSameShardSenderReceiverOfInnerTxV2(relayedSender, relayedTx)
}

func (tp *TransactionProcessor) isSameShardSenderReceiverOfInnerTxV1(
relayedSender []byte,
relayedTx *transaction.ApiTransactionResult,
) (bool, error) {
relayedDataField := string(relayedTx.Data)
if strings.Index(relayedDataField, relayedTxV1DataMarker) != 0 {
return false, fmt.Errorf("wrong relayed v1 data marker position")
}

hexedInnerTxData := dataField[len(relayedTxV1DataMarker):]
hexedInnerTxData := relayedDataField[len(relayedTxV1DataMarker):]
innerTxData, err := hex.DecodeString(hexedInnerTxData)
if err != nil {
return false, err
Expand All @@ -589,11 +616,32 @@ func (tp *TransactionProcessor) isIntraShardRelayedV1MoveBalanceTransaction(
return false, err
}

isSameShardOnRelayed := tp.proc.GetShardCoordinator().SameShard(senderAddress, receiverAddress)
isSameShardOnInnerForReceiver := tp.proc.GetShardCoordinator().SameShard(senderAddress, innerTx.RcvAddr)
isSameShardOnInnerForSender := tp.proc.GetShardCoordinator().SameShard(senderAddress, innerTx.SndAddr)
isSameShardOnInnerForReceiver := tp.proc.GetShardCoordinator().SameShard(relayedSender, innerTx.RcvAddr)
isSameShardOnInnerForSender := tp.proc.GetShardCoordinator().SameShard(relayedSender, innerTx.SndAddr)

return isSameShardOnInnerForReceiver && isSameShardOnInnerForSender, nil
}

func (tp *TransactionProcessor) isSameShardSenderReceiverOfInnerTxV2(
relayedSender []byte,
relayedTx *transaction.ApiTransactionResult,
) (bool, error) {
relayedDataField := string(relayedTx.Data)
if strings.Index(relayedDataField, relayedTxV2DataMarker) != 0 {
return false, fmt.Errorf("wrong relayed v2 data marker position")
}
arguments := strings.Split(relayedDataField, argumentsSeparator)
if len(arguments) < 2 {
return false, fmt.Errorf("wrong relayed v2 formatted data field")
}

hexedReceiver := arguments[1]
receiver, err := hex.DecodeString(hexedReceiver)
if err != nil {
return false, err
}

return isSameShardOnRelayed && isSameShardOnInnerForReceiver && isSameShardOnInnerForSender, nil
return tp.proc.GetShardCoordinator().SameShard(relayedSender, receiver), nil
}

func findIdentifierInLogs(logs []*transaction.ApiLogs, identifier string) bool {
Expand Down
40 changes: 40 additions & 0 deletions process/transactionProcessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1925,6 +1925,15 @@ func TestTransactionProcessor_computeTransactionStatus(t *testing.T) {
status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, transaction.TxStatusSuccess, status)
})
t.Run("ok relayed v2 move balance intra shard transaction", func(t *testing.T) {
t.Parallel()

testData := loadJsonIntoTxAndScrs(t, "./testdata/finishedOKRelayedV2TxIntraShard.json")
tp := createTestProcessorFromScenarioData(testData)

status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, transaction.TxStatusSuccess, status)
})
t.Run("ok relayed sc call function balance intra shard transaction still pending", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -2010,6 +2019,28 @@ func TestTransactionProcessor_computeTransactionStatus(t *testing.T) {
status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, data.TxStatusUnknown, status)
})
t.Run("malformed relayed v2 - missing marker", func(t *testing.T) {
t.Parallel()

testData := loadJsonIntoTxAndScrs(t, "./testdata/finishedOKRelayedV2TxIntraShard.json")
tp := createTestProcessorFromScenarioData(testData)

testData.Transaction.Data = []byte("aa")

status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, data.TxStatusUnknown, status)
})
t.Run("malformed relayed v2 - not enough arguments", func(t *testing.T) {
t.Parallel()

testData := loadJsonIntoTxAndScrs(t, "./testdata/finishedOKRelayedV2TxIntraShard.json")
tp := createTestProcessorFromScenarioData(testData)

testData.Transaction.Data = []byte(process.RelayedTxV2DataMarker)

status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, data.TxStatusUnknown, status)
})
t.Run("malformed relayed v1 - not a hex character after the marker", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -2049,6 +2080,15 @@ func TestTransactionProcessor_computeTransactionStatus(t *testing.T) {
testData := loadJsonIntoTxAndScrs(t, "./testdata/malformedRelayedTxIntraShard.json")
tp := createTestProcessorFromScenarioData(testData)

status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, data.TxStatusUnknown, status)
})
t.Run("malformed relayed v2 - no scr generated", func(t *testing.T) {
t.Parallel()

testData := loadJsonIntoTxAndScrs(t, "./testdata/malformedRelayedV2TxIntraShard.json")
tp := createTestProcessorFromScenarioData(testData)

status := tp.ComputeTransactionStatus(testData.Transaction, withResults)
require.Equal(t, data.TxStatusUnknown, status)
})
Expand Down

0 comments on commit 2dc3755

Please sign in to comment.