diff --git a/server/services/testdata/blocks_with_contract_calls.json b/server/services/testdata/blocks_with_contract_calls.json new file mode 100644 index 00000000..43f6a7d0 --- /dev/null +++ b/server/services/testdata/blocks_with_contract_calls.json @@ -0,0 +1,52 @@ +[ + { + "comment": "block with intra-shard contract call, with move balance, with signal error", + "miniBlocks": [ + { + "transactions": [ + { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "9851ab6cb221bce5800030f9db2a5fbd8ed4a9db4c6f9d190c16113f2b080e57", + "value": "10000000000000000", + "receiver": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "sender": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "sourceShard": 0, + "destinationShard": 0, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "identifier": "signalError", + "topics": [ + "XPSryD5QxTCdgH/D9naYh1mh4wEAG8mgJlgE9Cr4Brg=", + "aW52YWxpZCBmdW5jdGlvbiAobm90IGZvdW5kKQ==" + ], + "data": "QDY2NzU2ZTYzNzQ2OTZmNmUyMDZlNmY3NDIwNjY2Zjc1NmU2NA==", + "additionalData": [ + "QDY2NzU2ZTYzNzQ2OTZmNmUyMDZlNmY3NDIwNjY2Zjc1NmU2NA==" + ] + }, + { + "address": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "identifier": "internalVMErrors", + "topics": [ + "AAAAAAAAAAAFAOolmyabMw+rkpjSmMXxFGY1LaMQBrg=", + "bWlzc2luZ0Z1bmN0aW9u" + ], + "data": "CglydW50aW1lLmdvOjgzMSBbaW52YWxpZCBmdW5jdGlvbiAobm90IGZvdW5kKV0gW21pc3NpbmdGdW5jdGlvbl0=", + "additionalData": [ + "CglydW50aW1lLmdvOjgzMSBbaW52YWxpZCBmdW5jdGlvbiAobm90IGZvdW5kKV0gW21pc3NpbmdGdW5jdGlvbl0=" + ] + } + ] + }, + "initiallyPaidFee": "144050000000000" + } + ] + } + ] + } +] diff --git a/server/services/testdata/blocks_with_contract_deployments.json b/server/services/testdata/blocks_with_contract_deployments.json new file mode 100644 index 00000000..ce7acb7a --- /dev/null +++ b/server/services/testdata/blocks_with_contract_deployments.json @@ -0,0 +1,98 @@ +[ + { + "comment": "block with contract deployment, with move balance", + "miniBlocks": [ + { + "transactions": [ + { + "type": "normal", + "processingTypeOnSource": "SCDeployment", + "processingTypeOnDestination": "SCDeployment", + "hash": "2459bb2b9a64c1c920777ecbdaf0fa33d7fe8bcd24d7164562f341b2e4f702da", + "value": "10000000000000000", + "receiver": "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", + "sender": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "logs": { + "address": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqc4vdnqgc48ww26ljxqe2flgl86jewg0nq6uqna2ymj", + "identifier": "SCDeploy", + "topics": [ + "AAAAAAAAAAAFAMVY2YEYqdzla/IwMqT9Hz6llyHzBrg=", + "XPSryD5QxTCdgH/D9naYh1mh4wEAG8mgJlgE9Cr4Brg=", + "v5gJ+IK1KdPGJfGYibrKij1SO0bzAAhfUVsODJ8midg=" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", + "identifier": "writeLog", + "topics": [ + "XPSryD5QxTCdgH/D9naYh1mh4wEAG8mgJlgE9Cr4Brg=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNDU4ODUwMCwgZ2FzIHVzZWQgPSAzMzQ1MDU=" + ], + "data": "QDZmNmI=", + "additionalData": ["QDZmNmI="] + } + ] + }, + "operation": "scDeploy", + "initiallyPaidFee": "457385000000000" + } + ] + } + ] + }, + { + "comment": "block with contract deployment, with move balance, with signal error", + "miniBlocks": [ + { + "transactions": [ + { + "type": "normal", + "processingTypeOnSource": "SCDeployment", + "processingTypeOnDestination": "SCDeployment", + "hash": "52b74f025158f18512353da5f23c2e31c78c49d7b73da7d24f048f86da48b5c5", + "value": "77", + "receiver": "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", + "sender": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "sourceShard": 0, + "destinationShard": 0, + "logs": { + "address": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", + "identifier": "signalError", + "topics": [ + "XPSryD5QxTCdgH/D9naYh1mh4wEAG8mgJlgE9Cr4Brg=", + "ZnVuY3Rpb24gZG9lcyBub3QgYWNjZXB0IEVHTEQgcGF5bWVudA==" + ], + "data": "QDY1Nzg2NTYzNzU3NDY5NmY2ZTIwNjY2MTY5NmM2NTY0", + "additionalData": [ + "QDY1Nzg2NTYzNzU3NDY5NmY2ZTIwNjY2MTY5NmM2NTY0" + ] + }, + { + "address": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "identifier": "internalVMErrors", + "topics": [ + "XPSryD5QxTCdgH/D9naYh1mh4wEAG8mgJlgE9Cr4Brg=", + "X2luaXQ=" + ], + "data": "CglydW50aW1lLmdvOjgzNCBbZXhlY3V0aW9uIGZhaWxlZF0gW10KCXJ1bnRpbWUuZ286ODM0IFtleGVjdXRpb24gZmFpbGVkXSBbXQoJcnVudGltZS5nbzo4MzEgW2Z1bmN0aW9uIGRvZXMgbm90IGFjY2VwdCBFR0xEIHBheW1lbnRd", + "additionalData": [ + "CglydW50aW1lLmdvOjgzNCBbZXhlY3V0aW9uIGZhaWxlZF0gW10KCXJ1bnRpbWUuZ286ODM0IFtleGVjdXRpb24gZmFpbGVkXSBbXQoJcnVudGltZS5nbzo4MzEgW2Z1bmN0aW9uIGRvZXMgbm90IGFjY2VwdCBFR0xEIHBheW1lbnRd" + ] + } + ] + }, + "initiallyPaidFee": "2206715000000000" + } + ] + } + ] + } +] diff --git a/server/services/transactionsFeaturesDetector.go b/server/services/transactionsFeaturesDetector.go index 36d78a18..2eab9538 100644 --- a/server/services/transactionsFeaturesDetector.go +++ b/server/services/transactionsFeaturesDetector.go @@ -74,3 +74,23 @@ func (detector *transactionsFeaturesDetector) isRelayedV1TransactionCompletelyIn isWithSignalError := detector.eventsController.hasAnySignalError(tx) return isWithSignalError } + +func (detector *transactionsFeaturesDetector) isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx *transaction.ApiTransactionResult) bool { + return detector.isContractDeploymentWithSignalError(tx) || (detector.isIntrashard(tx) && detector.isContractCallWithSignalError(tx)) +} + +func (detector *transactionsFeaturesDetector) isContractDeploymentWithSignalError(tx *transaction.ApiTransactionResult) bool { + return tx.ProcessingTypeOnSource == transactionProcessingTypeContractDeployment && + tx.ProcessingTypeOnDestination == transactionProcessingTypeContractDeployment && + detector.eventsController.hasAnySignalError(tx) +} + +func (detector *transactionsFeaturesDetector) isContractCallWithSignalError(tx *transaction.ApiTransactionResult) bool { + return tx.ProcessingTypeOnSource == transactionProcessingTypeContractInvoking && + tx.ProcessingTypeOnDestination == transactionProcessingTypeContractInvoking && + detector.eventsController.hasAnySignalError(tx) +} + +func (detector *transactionsFeaturesDetector) isIntrashard(tx *transaction.ApiTransactionResult) bool { + return tx.SourceShard == tx.DestinationShard +} diff --git a/server/services/transactionsFeaturesDetector_test.go b/server/services/transactionsFeaturesDetector_test.go index c99d71a0..70af7207 100644 --- a/server/services/transactionsFeaturesDetector_test.go +++ b/server/services/transactionsFeaturesDetector_test.go @@ -131,3 +131,107 @@ func TestTransactionsFeaturesDetector_isRelayedV1TransactionCompletelyIntrashard require.True(t, featureDetected) }) } + +func TestTransactionsFeatureDetector_isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(t *testing.T) { + networkProvider := testscommon.NewNetworkProviderMock() + detector := newTransactionsFeaturesDetector(networkProvider) + + t.Run("contract deployment, with signal error", func(t *testing.T) { + tx := &transaction.ApiTransactionResult{ + ProcessingTypeOnSource: transactionProcessingTypeContractDeployment, + ProcessingTypeOnDestination: transactionProcessingTypeContractDeployment, + Logs: &transaction.ApiLogs{ + Events: []*transaction.Events{ + { + Identifier: transactionEventSignalError, + }, + }, + }, + } + + require.True(t, detector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx)) + }) + + t.Run("contract deployment, without signal error", func(t *testing.T) { + tx := &transaction.ApiTransactionResult{ + ProcessingTypeOnSource: transactionProcessingTypeContractDeployment, + ProcessingTypeOnDestination: transactionProcessingTypeContractDeployment, + } + + require.False(t, detector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx)) + }) + + t.Run("contract call, with signal error, intra-shard", func(t *testing.T) { + tx := &transaction.ApiTransactionResult{ + ProcessingTypeOnSource: transactionProcessingTypeContractInvoking, + ProcessingTypeOnDestination: transactionProcessingTypeContractInvoking, + SourceShard: 2, + DestinationShard: 2, + Logs: &transaction.ApiLogs{ + Events: []*transaction.Events{ + { + Identifier: transactionEventSignalError, + }, + }, + }, + } + + require.True(t, detector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx)) + }) + + t.Run("contract call, with signal error, cross-shard", func(t *testing.T) { + tx := &transaction.ApiTransactionResult{ + ProcessingTypeOnSource: transactionProcessingTypeContractInvoking, + ProcessingTypeOnDestination: transactionProcessingTypeContractInvoking, + SourceShard: 0, + DestinationShard: 1, + Logs: &transaction.ApiLogs{ + Events: []*transaction.Events{ + { + Identifier: transactionEventSignalError, + }, + }, + }, + } + + require.False(t, detector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx)) + }) + + t.Run("contract call, without signal error", func(t *testing.T) { + tx := &transaction.ApiTransactionResult{ + ProcessingTypeOnSource: transactionProcessingTypeContractInvoking, + ProcessingTypeOnDestination: transactionProcessingTypeContractInvoking, + } + + require.False(t, detector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx)) + }) + + t.Run("arbitrary transaction", func(t *testing.T) { + tx := &transaction.ApiTransactionResult{ + ProcessingTypeOnSource: transactionProcessingTypeMoveBalance, + ProcessingTypeOnDestination: transactionProcessingTypeMoveBalance, + } + + require.False(t, detector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx)) + }) +} + +func TestTransactionsFeaturesDetector_isIntrashard(t *testing.T) { + networkProvider := testscommon.NewNetworkProviderMock() + detector := newTransactionsFeaturesDetector(networkProvider) + + require.True(t, detector.isIntrashard(&transaction.ApiTransactionResult{ + SourceShard: 0, + DestinationShard: 0, + })) + + require.True(t, detector.isIntrashard(&transaction.ApiTransactionResult{ + SourceShard: 1, + DestinationShard: 1, + })) + + require.False(t, detector.isIntrashard(&transaction.ApiTransactionResult{ + SourceShard: 0, + DestinationShard: 1, + })) +} diff --git a/server/services/transactionsTransformer.go b/server/services/transactionsTransformer.go index a4cee250..749e434a 100644 --- a/server/services/transactionsTransformer.go +++ b/server/services/transactionsTransformer.go @@ -172,10 +172,15 @@ func (transformer *transactionsTransformer) rewardTxToRosettaTx(tx *transaction. } func (transformer *transactionsTransformer) normalTxToRosetta(tx *transaction.ApiTransactionResult) (*types.Transaction, error) { - hasValue := !isZeroAmount(tx.Value) operations := make([]*types.Operation, 0) - if hasValue { + // Special handling of: + // - intra-shard contract calls, bearing value, which fail with signal error + // - direct contract deployments, bearing value, which fail with signal error + // For these, the protocol does not generate an explicit SCR with the value refund (before Sirius, in some circumstances, it did). + // However, since the value remains at the sender, we don't emit any operations in these circumstances. + transfersValue := isNonZeroAmount(tx.Value) && !transformer.featuresDetector.isContractDeploymentWithSignalErrorOrIntrashardContractCallWithSignalError(tx) + if transfersValue { operations = append(operations, &types.Operation{ Type: opTransfer, Account: addressToAccountIdentifier(tx.Sender), @@ -200,6 +205,10 @@ func (transformer *transactionsTransformer) normalTxToRosetta(tx *transaction.Ap return nil, err } + if len(innerTxOperationsIfRelayedCompletelyIntrashardWithSignalError) > 0 { + log.Info("normalTxToRosetta(): innerTxOperationsIfRelayedCompletelyIntrashardWithSignalError", "tx", tx.Hash, "block", tx.BlockNonce) + } + operations = append(operations, innerTxOperationsIfRelayedCompletelyIntrashardWithSignalError...) return &types.Transaction{ @@ -364,7 +373,7 @@ func (transformer *transactionsTransformer) addOperationsGivenTransactionEvents( } for _, event := range eventsSCDeploy { - // Handle direct deployments with transfer of value (indirect deployments are currently excluded to prevent any potential misinterpretations).. + // Handle direct deployments with transfer of value (indirect deployments are currently excluded to prevent any potential misinterpretations). if tx.Receiver == systemContractDeployAddress { operations := []*types.Operation{ // Deployer's balance change is already captured in operations recovered not from logs / events, but from the transaction itself. diff --git a/server/services/transactionsTransformer_test.go b/server/services/transactionsTransformer_test.go index e2b9889d..0cb859f3 100644 --- a/server/services/transactionsTransformer_test.go +++ b/server/services/transactionsTransformer_test.go @@ -277,64 +277,123 @@ func TestTransactionsTransformer_InvalidTxToRosettaTx(t *testing.T) { require.Equal(t, expectedTx, rosettaTx) } -func TestTransactionsTransformer_TransformBlockTxsHavingDirectSCDeployWithValue(t *testing.T) { +func TestTransactionsTransformer_TransformBlockTxsHavingContractDeployments(t *testing.T) { networkProvider := testscommon.NewNetworkProviderMock() networkProvider.MockObservedActualShard = 0 extension := newNetworkProviderExtension(networkProvider) transformer := newTransactionsTransformer(networkProvider) - blocks, err := readTestBlocks("testdata/blocks_with_direct_sc_deploy_with_value.json") + blocks, err := readTestBlocks("testdata/blocks_with_contract_deployments.json") require.Nil(t, err) - txs, err := transformer.transformBlockTxs(blocks[0]) - require.Nil(t, err) - require.Len(t, txs, 1) - require.Len(t, txs[0].Operations, 5) + t.Run("direct contract deployment, with value", func(t *testing.T) { + txs, err := transformer.transformBlockTxs(blocks[0]) + require.Nil(t, err) + require.Len(t, txs, 1) + require.Len(t, txs[0].Operations, 5) - expectedTx := &types.Transaction{ - TransactionIdentifier: hashToTransactionIdentifier("2459bb2b9a64c1c920777ecbdaf0fa33d7fe8bcd24d7164562f341b2e4f702da"), - Operations: []*types.Operation{ - { - Type: opTransfer, - OperationIdentifier: indexToOperationIdentifier(0), - Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), - Amount: extension.valueToNativeAmount("-10000000000000000"), - Status: &opStatusSuccess, - }, - { - Type: opTransfer, - OperationIdentifier: indexToOperationIdentifier(1), - Account: addressToAccountIdentifier("erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"), - Amount: extension.valueToNativeAmount("10000000000000000"), - Status: &opStatusSuccess, - }, - { - Type: opFee, - OperationIdentifier: indexToOperationIdentifier(2), - Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), - Amount: extension.valueToNativeAmount("-457385000000000"), - Status: &opStatusSuccess, + expectedTx := &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier("2459bb2b9a64c1c920777ecbdaf0fa33d7fe8bcd24d7164562f341b2e4f702da"), + Operations: []*types.Operation{ + { + Type: opTransfer, + OperationIdentifier: indexToOperationIdentifier(0), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("-10000000000000000"), + Status: &opStatusSuccess, + }, + { + Type: opTransfer, + OperationIdentifier: indexToOperationIdentifier(1), + Account: addressToAccountIdentifier("erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"), + Amount: extension.valueToNativeAmount("10000000000000000"), + Status: &opStatusSuccess, + }, + { + Type: opFee, + OperationIdentifier: indexToOperationIdentifier(2), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("-457385000000000"), + Status: &opStatusSuccess, + }, + { + Type: opTransfer, + OperationIdentifier: indexToOperationIdentifier(3), + Account: addressToAccountIdentifier("erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"), + Amount: extension.valueToNativeAmount("-10000000000000000"), + Status: &opStatusSuccess, + }, + { + Type: opTransfer, + OperationIdentifier: indexToOperationIdentifier(4), + Account: addressToAccountIdentifier("erd1qqqqqqqqqqqqqpgqc4vdnqgc48ww26ljxqe2flgl86jewg0nq6uqna2ymj"), + Amount: extension.valueToNativeAmount("10000000000000000"), + Status: &opStatusSuccess, + }, }, - { - Type: opTransfer, - OperationIdentifier: indexToOperationIdentifier(3), - Account: addressToAccountIdentifier("erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu"), - Amount: extension.valueToNativeAmount("-10000000000000000"), - Status: &opStatusSuccess, + Metadata: extractTransactionMetadata(blocks[0].MiniBlocks[0].Transactions[0]), + } + + require.Equal(t, expectedTx, txs[0]) + }) + + t.Run("direct contract deployment, with value, with signal error", func(t *testing.T) { + txs, err := transformer.transformBlockTxs(blocks[1]) + require.Nil(t, err) + require.Len(t, txs, 1) + require.Len(t, txs[0].Operations, 1) + + expectedTx := &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier("52b74f025158f18512353da5f23c2e31c78c49d7b73da7d24f048f86da48b5c5"), + Operations: []*types.Operation{ + { + Type: opFee, + OperationIdentifier: indexToOperationIdentifier(0), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("-2206715000000000"), + Status: &opStatusSuccess, + }, }, - { - Type: opTransfer, - OperationIdentifier: indexToOperationIdentifier(4), - Account: addressToAccountIdentifier("erd1qqqqqqqqqqqqqpgqc4vdnqgc48ww26ljxqe2flgl86jewg0nq6uqna2ymj"), - Amount: extension.valueToNativeAmount("10000000000000000"), - Status: &opStatusSuccess, + Metadata: extractTransactionMetadata(blocks[1].MiniBlocks[0].Transactions[0]), + } + + require.Equal(t, expectedTx, txs[0]) + }) +} + +func TestTransactionsTransformer_TransformBlockTxsHavingContractCalls(t *testing.T) { + networkProvider := testscommon.NewNetworkProviderMock() + networkProvider.MockObservedActualShard = 0 + + extension := newNetworkProviderExtension(networkProvider) + transformer := newTransactionsTransformer(networkProvider) + + blocks, err := readTestBlocks("testdata/blocks_with_contract_calls.json") + require.Nil(t, err) + + t.Run("direct contract call, with value, with signal error", func(t *testing.T) { + txs, err := transformer.transformBlockTxs(blocks[0]) + require.Nil(t, err) + require.Len(t, txs, 1) + require.Len(t, txs[0].Operations, 1) + + expectedTx := &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier("9851ab6cb221bce5800030f9db2a5fbd8ed4a9db4c6f9d190c16113f2b080e57"), + Operations: []*types.Operation{ + { + Type: opFee, + OperationIdentifier: indexToOperationIdentifier(0), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("-144050000000000"), + Status: &opStatusSuccess, + }, }, - }, - Metadata: extractTransactionMetadata(blocks[0].MiniBlocks[0].Transactions[0]), - } + Metadata: extractTransactionMetadata(blocks[0].MiniBlocks[0].Transactions[0]), + } - require.Equal(t, expectedTx, txs[0]) + require.Equal(t, expectedTx, txs[0]) + }) } func TestTransactionsTransformer_TransformBlockTxsHavingESDTIssue(t *testing.T) { diff --git a/systemtests/check_with_mesh_cli.py b/systemtests/check_with_mesh_cli.py index de3354be..d4272c79 100644 --- a/systemtests/check_with_mesh_cli.py +++ b/systemtests/check_with_mesh_cli.py @@ -57,11 +57,12 @@ def run_rosetta(configuration: Configuration): """ current_epoch = get_current_epoch(configuration) + observer_url = configuration.observer_url or constants.URL_OBSERVER_SURROGATE command = [ str(constants.PATH_ROSETTA), f"--port={constants.PORT_ROSETTA}", - f"--observer-http-url={constants.URL_OBSERVER_SURROGATE}", + f"--observer-http-url={observer_url}", f"--observer-actual-shard={configuration.network_shard}", f"--network-id={configuration.network_id}", f"--network-name={configuration.network_name}",