From 13d3947f62267053eda004d56c748b808ab89c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 21 Aug 2024 16:41:10 +0300 Subject: [PATCH 1/3] Improve handling of claim developer rewards. --- cmd/rosetta/cli.go | 12 +++ cmd/rosetta/main.go | 1 + server/factory/interface.go | 1 + server/factory/provider.go | 2 + server/provider/networkProvider.go | 10 ++- server/services/constants.go | 1 + server/services/interface.go | 1 + server/services/operations.go | 2 + .../blocks_with_claim_developer_rewards.json | 77 +++++++++++++++++++ .../services/transactionEventsController.go | 25 ++++++ .../transactionEventsController_test.go | 25 ++++++ .../services/transactionsFeaturesDetector.go | 34 +++++--- server/services/transactionsTransformer.go | 44 ++++++++--- .../services/transactionsTransformer_test.go | 68 ++++++++++++++++ testscommon/networkProviderMock.go | 6 ++ 15 files changed, 288 insertions(+), 21 deletions(-) create mode 100644 server/services/testdata/blocks_with_claim_developer_rewards.json diff --git a/cmd/rosetta/cli.go b/cmd/rosetta/cli.go index a10c6982..9c4cbcb9 100644 --- a/cmd/rosetta/cli.go +++ b/cmd/rosetta/cli.go @@ -1,6 +1,8 @@ package main import ( + "math" + logger "github.com/multiversx/mx-chain-logger-go" "github.com/urfave/cli" ) @@ -166,6 +168,13 @@ VERSION: Usage: "Specifies the configuration file for custom currencies.", Required: false, } + + cliFlagActivationEpochSpica = cli.UintFlag{ + Name: "activation-epoch-spica", + Usage: "Specifies the activation epoch for Spica release.", + Required: false, + Value: math.MaxUint32, + } ) func getAllCliFlags() []cli.Flag { @@ -194,6 +203,7 @@ func getAllCliFlags() []cli.Flag { cliFlagNumHistoricalEpochs, cliFlagShouldHandleContracts, cliFlagConfigFileCustomCurrencies, + cliFlagActivationEpochSpica, } } @@ -223,6 +233,7 @@ type parsedCliFlags struct { numHistoricalEpochs uint32 shouldHandleContracts bool configFileCustomCurrencies string + activationEpochSpica uint32 } func getParsedCliFlags(ctx *cli.Context) parsedCliFlags { @@ -252,5 +263,6 @@ func getParsedCliFlags(ctx *cli.Context) parsedCliFlags { numHistoricalEpochs: uint32(ctx.GlobalUint(cliFlagNumHistoricalEpochs.Name)), shouldHandleContracts: ctx.GlobalBool(cliFlagShouldHandleContracts.Name), configFileCustomCurrencies: ctx.GlobalString(cliFlagConfigFileCustomCurrencies.Name), + activationEpochSpica: uint32(ctx.GlobalUint(cliFlagActivationEpochSpica.Name)), } } diff --git a/cmd/rosetta/main.go b/cmd/rosetta/main.go index fc51576c..dbb2d423 100644 --- a/cmd/rosetta/main.go +++ b/cmd/rosetta/main.go @@ -82,6 +82,7 @@ func startRosetta(ctx *cli.Context) error { FirstHistoricalEpoch: cliFlags.firstHistoricalEpoch, NumHistoricalEpochs: cliFlags.numHistoricalEpochs, ShouldHandleContracts: cliFlags.shouldHandleContracts, + ActivationEpochSpica: cliFlags.activationEpochSpica, }) if err != nil { return err diff --git a/server/factory/interface.go b/server/factory/interface.go index 916da7fd..861af975 100644 --- a/server/factory/interface.go +++ b/server/factory/interface.go @@ -35,5 +35,6 @@ type NetworkProvider interface { ComputeReceiptHash(apiReceipt *transaction.ApiReceipt) (string, error) ComputeTransactionFeeForMoveBalance(tx *transaction.ApiTransactionResult) *big.Int GetMempoolTransactionByHash(hash string) (*transaction.ApiTransactionResult, error) + IsReleaseSpicaActive(epoch uint32) bool LogDescription() } diff --git a/server/factory/provider.go b/server/factory/provider.go index b945ed46..b3acc26d 100644 --- a/server/factory/provider.go +++ b/server/factory/provider.go @@ -49,6 +49,7 @@ type ArgsCreateNetworkProvider struct { FirstHistoricalEpoch uint32 NumHistoricalEpochs uint32 ShouldHandleContracts bool + ActivationEpochSpica uint32 } // CreateNetworkProvider creates a network provider @@ -140,6 +141,7 @@ func CreateNetworkProvider(args ArgsCreateNetworkProvider) (NetworkProvider, err FirstHistoricalEpoch: args.FirstHistoricalEpoch, NumHistoricalEpochs: args.NumHistoricalEpochs, ShouldHandleContracts: args.ShouldHandleContracts, + ActivationEpochSpica: args.ActivationEpochSpica, ObserverFacade: &components.ObserverFacade{ Processor: baseProcessor, diff --git a/server/provider/networkProvider.go b/server/provider/networkProvider.go index c30ca96d..27c4a5d3 100644 --- a/server/provider/networkProvider.go +++ b/server/provider/networkProvider.go @@ -42,6 +42,7 @@ type ArgsNewNetworkProvider struct { FirstHistoricalEpoch uint32 NumHistoricalEpochs uint32 ShouldHandleContracts bool + ActivationEpochSpica uint32 ObserverFacade observerFacade @@ -64,6 +65,7 @@ type networkProvider struct { firstHistoricalEpoch uint32 numHistoricalEpochs uint32 shouldHandleContracts bool + activationEpochSpica uint32 observerFacade observerFacade @@ -104,6 +106,7 @@ func NewNetworkProvider(args ArgsNewNetworkProvider) (*networkProvider, error) { firstHistoricalEpoch: args.FirstHistoricalEpoch, numHistoricalEpochs: args.NumHistoricalEpochs, shouldHandleContracts: args.ShouldHandleContracts, + activationEpochSpica: args.ActivationEpochSpica, observerFacade: args.ObserverFacade, @@ -413,7 +416,7 @@ func (provider *networkProvider) GetMempoolTransactionByHash(hash string) (*tran return nil, nil } -// ComputeTransactionFeeForMoveBalance computes the fee for a move-balance transaction. +// ComputeTransactionFeeForMoveBalance computes the fee for a move-balance transaction func (provider *networkProvider) ComputeTransactionFeeForMoveBalance(tx *transaction.ApiTransactionResult) *big.Int { minGasLimit := provider.networkConfig.MinGasLimit extraGasLimitGuardedTx := provider.networkConfig.ExtraGasLimitGuardedTx @@ -429,6 +432,11 @@ func (provider *networkProvider) ComputeTransactionFeeForMoveBalance(tx *transac return fee } +// IsReleaseSpicaActive returns whether the Spica release is active in the provided epoch +func (provider *networkProvider) IsReleaseSpicaActive(epoch uint32) bool { + return epoch >= provider.activationEpochSpica +} + // LogDescription writes a description of the network provider in the log output func (provider *networkProvider) LogDescription() { log.Info("Description of network provider", diff --git a/server/services/constants.go b/server/services/constants.go index 6bd87b95..f7aec9bf 100644 --- a/server/services/constants.go +++ b/server/services/constants.go @@ -55,4 +55,5 @@ var ( numTopicsOfEventESDTNFTBurn = 3 numTopicsOfEventESDTNFTAddQuantity = 3 numTopicsOfEventSCDeployBeforeSirius = 2 + numTopicsOfEventClaimDeveloperRewards = 2 ) diff --git a/server/services/interface.go b/server/services/interface.go index 271c46ad..ca9630dc 100644 --- a/server/services/interface.go +++ b/server/services/interface.go @@ -34,4 +34,5 @@ type NetworkProvider interface { ComputeReceiptHash(apiReceipt *transaction.ApiReceipt) (string, error) ComputeTransactionFeeForMoveBalance(tx *transaction.ApiTransactionResult) *big.Int GetMempoolTransactionByHash(hash string) (*transaction.ApiTransactionResult, error) + IsReleaseSpicaActive(epoch uint32) bool } diff --git a/server/services/operations.go b/server/services/operations.go index 91a39674..11c4fe44 100644 --- a/server/services/operations.go +++ b/server/services/operations.go @@ -12,6 +12,7 @@ const ( opScResult = "SmartContractResult" opFeeRefundAsScResult = "FeeRefundAsSmartContractResult" opDeveloperRewardsAsScResult = "DeveloperRewardsAsSmartContractResult" + opDeveloperRewards = "DeveloperRewards" opFeeOfInvalidTx = "FeeOfInvalidTransaction" opFeeRefund = "FeeRefund" opCustomTransfer = "CustomTransfer" @@ -27,6 +28,7 @@ var ( opScResult, opFeeRefundAsScResult, opDeveloperRewardsAsScResult, + opDeveloperRewards, opFeeOfInvalidTx, opFeeRefund, opCustomTransfer, diff --git a/server/services/testdata/blocks_with_claim_developer_rewards.json b/server/services/testdata/blocks_with_claim_developer_rewards.json new file mode 100644 index 00000000..1ed7360c --- /dev/null +++ b/server/services/testdata/blocks_with_claim_developer_rewards.json @@ -0,0 +1,77 @@ +[ + { + "comment": "block with claim developer rewards", + "miniBlocks": [ + { + "transactions": [ + { + "type": "normal", + "processingTypeOnSource": "BuiltInFunctionCall", + "processingTypeOnDestination": "BuiltInFunctionCall", + "hash": "96b1a0533ff17df3d1777889117023d0b178cc80fa72535d1b8ec1a13bcf3a75", + "epoch": 20, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "sender": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "data": "Q2xhaW1EZXZlbG9wZXJSZXdhcmRz", + "signature": "132aa54ec093c21e2d0d447bf9a9b1da5c33d4120da66fb53dbc78d1d3d007e2314fa06348302f503e96a91b697dd943189df0ad4c3750416a704de2ac007e06", + "sourceShard": 0, + "destinationShard": 0, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "identifier": "completedTxEvent", + "topics": [ + "lrGgUz/xffPRd3iJEXAj0LF4zID6clNdG47BoTvPOnU=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "ClaimDeveloperRewards", + "initiallyPaidFee": "160685000000000" + } + ] + }, + { + "transactions": [ + { + "type": "unsigned", + "processingTypeOnSource": "MoveBalance", + "processingTypeOnDestination": "MoveBalance", + "hash": "d05c5f65f564d740aa1e81f7a96581d739783a43c232a6c86112afa1e6c318c4", + "epoch": 20, + "value": "1774725000000", + "receiver": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "sender": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "previousTransactionHash": "96b1a0533ff17df3d1777889117023d0b178cc80fa72535d1b8ec1a13bcf3a75", + "originalTransactionHash": "96b1a0533ff17df3d1777889117023d0b178cc80fa72535d1b8ec1a13bcf3a75", + "originalSender": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "sourceShard": 0, + "destinationShard": 0 + }, + { + "type": "unsigned", + "processingTypeOnSource": "MoveBalance", + "processingTypeOnDestination": "MoveBalance", + "hash": "bc89442d5e77113f0b4e7383e5d078776fc6724690ba9f98d1704202c324e090", + "epoch": 20, + "value": "29185000000000", + "receiver": "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", + "sender": "erd1qqqqqqqqqqqqqpgqagjekf5mxv86hy5c62vvtug5vc6jmgcsq6uq8reras", + "previousTransactionHash": "96b1a0533ff17df3d1777889117023d0b178cc80fa72535d1b8ec1a13bcf3a75", + "originalTransactionHash": "96b1a0533ff17df3d1777889117023d0b178cc80fa72535d1b8ec1a13bcf3a75", + "sourceShard": 0, + "destinationShard": 0, + "nonce": 29, + "data": "QDZmNmI=", + "isRefund": true + } + ] + } + ] + } +] diff --git a/server/services/transactionEventsController.go b/server/services/transactionEventsController.go index 8be0c9fa..57bf6807 100644 --- a/server/services/transactionEventsController.go +++ b/server/services/transactionEventsController.go @@ -263,6 +263,31 @@ func (controller *transactionEventsController) extractEventsESDTNFTAddQuantity(t return typedEvents, nil } +func (controller *transactionEventsController) extractEventsClaimDeveloperRewards(tx *transaction.ApiTransactionResult) ([]*eventClaimDeveloperRewards, error) { + rawEvents := controller.findManyEventsByIdentifier(tx, transactionEventClaimDeveloperRewards) + typedEvents := make([]*eventClaimDeveloperRewards, 0, len(rawEvents)) + + for _, event := range rawEvents { + numTopics := len(event.Topics) + if numTopics != numTopicsOfEventClaimDeveloperRewards { + return nil, fmt.Errorf("%w: bad number of topics for %s event = %d", errCannotRecognizeEvent, transactionEventClaimDeveloperRewards, numTopics) + } + + valueBytes := event.Topics[0] + receiverPubkey := event.Topics[1] + + value := big.NewInt(0).SetBytes(valueBytes) + receiver := controller.provider.ConvertPubKeyToAddress(receiverPubkey) + + typedEvents = append(typedEvents, &eventClaimDeveloperRewards{ + value: value.String(), + receiverAddress: receiver, + }) + } + + return typedEvents, nil +} + func (controller *transactionEventsController) findManyEventsByIdentifier(tx *transaction.ApiTransactionResult, identifier string) []*transaction.Events { events := make([]*transaction.Events, 0) diff --git a/server/services/transactionEventsController_test.go b/server/services/transactionEventsController_test.go index b977ad98..e4aa6b8e 100644 --- a/server/services/transactionEventsController_test.go +++ b/server/services/transactionEventsController_test.go @@ -281,4 +281,29 @@ func TestTransactionEventsController_ExtractEvents(t *testing.T) { require.Equal(t, []byte{0x2a}, events[0].nonceAsBytes) require.Equal(t, "100", events[0].value) }) + + t.Run("ClaimDeveloperRewards", func(t *testing.T) { + topic0 := []byte{0x64} + topic1, _ := hex.DecodeString("5cf4abc83e50c5309d807fc3f676988759a1e301001bc9a0265804f42af806b8") + + tx := &transaction.ApiTransactionResult{ + Logs: &transaction.ApiLogs{ + Events: []*transaction.Events{ + { + Identifier: "ClaimDeveloperRewards", + Topics: [][]byte{ + topic0, + topic1, + }, + }, + }, + }, + } + + events, err := controller.extractEventsClaimDeveloperRewards(tx) + require.NoError(t, err) + require.Len(t, events, 1) + require.Equal(t, "100", events[0].value) + require.Equal(t, "erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6", events[0].receiverAddress) + }) } diff --git a/server/services/transactionsFeaturesDetector.go b/server/services/transactionsFeaturesDetector.go index 2eab9538..3c33d5bc 100644 --- a/server/services/transactionsFeaturesDetector.go +++ b/server/services/transactionsFeaturesDetector.go @@ -1,8 +1,6 @@ package services import ( - "bytes" - "github.com/multiversx/mx-chain-core-go/data/transaction" ) @@ -23,23 +21,37 @@ func (detector *transactionsFeaturesDetector) doesContractResultHoldRewardsOfCla contractResult *transaction.ApiTransactionResult, allTransactionsInBlock []*transaction.ApiTransactionResult, ) bool { - claimDeveloperRewardsTxs := make(map[string]struct{}) + hasData := len(contractResult.Data) > 0 + hasNonZeroNonce := contractResult.Nonce > 0 + if hasData || hasNonZeroNonce { + return false + } for _, tx := range allTransactionsInBlock { matchesTypeOnSource := tx.ProcessingTypeOnSource == transactionProcessingTypeBuiltInFunctionCall + if !matchesTypeOnSource { + continue + } + matchesTypeOnDestination := tx.ProcessingTypeOnDestination == transactionProcessingTypeBuiltInFunctionCall - matchesData := bytes.Equal(tx.Data, []byte(builtInFunctionClaimDeveloperRewards)) + if !matchesTypeOnDestination { + continue + } - if matchesTypeOnSource && matchesTypeOnDestination && matchesData { - claimDeveloperRewardsTxs[tx.Hash] = struct{}{} + matchesOperation := tx.Operation == builtInFunctionClaimDeveloperRewards + if !matchesOperation { + continue } - } - _, isResultOfClaimDeveloperRewards := claimDeveloperRewardsTxs[contractResult.OriginalTransactionHash] - hasNoData := len(contractResult.Data) == 0 - hasZeroNonce := contractResult.Nonce == 0 + matchesOriginalTransactionHash := tx.Hash == contractResult.OriginalTransactionHash + if !matchesOriginalTransactionHash { + continue + } + + return true + } - return isResultOfClaimDeveloperRewards && hasNoData && hasZeroNonce + return false } // isInvalidTransactionOfTypeMoveBalanceThatOnlyConsumesDataMovementGas detects (intra-shard) invalid transactions diff --git a/server/services/transactionsTransformer.go b/server/services/transactionsTransformer.go index 5cac3faa..ae895e60 100644 --- a/server/services/transactionsTransformer.go +++ b/server/services/transactionsTransformer.go @@ -127,16 +127,19 @@ func (transformer *transactionsTransformer) unsignedTxToRosettaTx( } } - if transformer.featuresDetector.doesContractResultHoldRewardsOfClaimDeveloperRewards(scr, txsInBlock) { - return &types.Transaction{ - TransactionIdentifier: hashToTransactionIdentifier(scr.Hash), - Operations: []*types.Operation{ - { - Type: opDeveloperRewardsAsScResult, - Account: addressToAccountIdentifier(scr.Receiver), - Amount: transformer.extension.valueToNativeAmount(scr.Value), + if !transformer.areClaimDeveloperRewardsEventsEnabled(scr.Epoch) { + // Handle developer rewards in a legacy manner (without looking at events / logs) + if transformer.featuresDetector.doesContractResultHoldRewardsOfClaimDeveloperRewards(scr, txsInBlock) { + return &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier(scr.Hash), + Operations: []*types.Operation{ + { + Type: opDeveloperRewardsAsScResult, + Account: addressToAccountIdentifier(scr.Receiver), + Amount: transformer.extension.valueToNativeAmount(scr.Value), + }, }, - }, + } } } @@ -372,6 +375,11 @@ func (transformer *transactionsTransformer) addOperationsGivenTransactionEvents( return err } + eventsClaimDeveloperRewards, err := transformer.eventsController.extractEventsClaimDeveloperRewards(tx) + if err != nil { + return err + } + for _, event := range eventsSCDeploy { // Handle direct deployments with transfer of value (indirect deployments are currently excluded to prevent any potential misinterpretations). if tx.Receiver == systemContractDeployAddress { @@ -501,6 +509,20 @@ func (transformer *transactionsTransformer) addOperationsGivenTransactionEvents( rosettaTx.Operations = append(rosettaTx.Operations, operations...) } + if transformer.areClaimDeveloperRewardsEventsEnabled(tx.Epoch) { + for _, event := range eventsClaimDeveloperRewards { + operations := []*types.Operation{ + { + Type: opDeveloperRewards, + Account: addressToAccountIdentifier(event.receiverAddress), + Amount: transformer.extension.valueToNativeAmount(event.value), + }, + } + + rosettaTx.Operations = append(rosettaTx.Operations, operations...) + } + } + return nil } @@ -538,3 +560,7 @@ func (transformer *transactionsTransformer) extractOperationsFromEventESDT(event return make([]*types.Operation, 0) } + +func (transformer *transactionsTransformer) areClaimDeveloperRewardsEventsEnabled(epoch uint32) bool { + return transformer.provider.IsReleaseSpicaActive(epoch) +} diff --git a/server/services/transactionsTransformer_test.go b/server/services/transactionsTransformer_test.go index 0cb859f3..55c5b740 100644 --- a/server/services/transactionsTransformer_test.go +++ b/server/services/transactionsTransformer_test.go @@ -988,6 +988,74 @@ func TestTransactionsTransformer_TransformBlockTxsHavingNFTBurn(t *testing.T) { require.Equal(t, expectedNftBurnTx, txs[0]) } +func TestTransactionsTransformer_TransformBlockTxsHavingClaimDeveloperRewards(t *testing.T) { + networkProvider := testscommon.NewNetworkProviderMock() + networkProvider.MockObservedActualShard = 0 + networkProvider.MockActivationEpochSpica = 42 + + extension := newNetworkProviderExtension(networkProvider) + transformer := newTransactionsTransformer(networkProvider) + + blocks, err := readTestBlocks("testdata/blocks_with_claim_developer_rewards.json") + require.Nil(t, err) + + t.Run("recover operations in legacy manner (without using events)", func(t *testing.T) { + txs, err := transformer.transformBlockTxs(blocks[0]) + require.Nil(t, err) + require.Len(t, txs, 3) + require.Len(t, txs[0].Operations, 1) + require.Len(t, txs[1].Operations, 1) + require.Len(t, txs[2].Operations, 1) + + expectedTx0 := &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier("96b1a0533ff17df3d1777889117023d0b178cc80fa72535d1b8ec1a13bcf3a75"), + Operations: []*types.Operation{ + { + Type: opFee, + OperationIdentifier: indexToOperationIdentifier(0), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("-160685000000000"), + Status: &opStatusSuccess, + }, + }, + Metadata: extractTransactionMetadata(blocks[0].MiniBlocks[0].Transactions[0]), + } + + require.Equal(t, expectedTx0, txs[0]) + + expectedTx1 := &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier("d05c5f65f564d740aa1e81f7a96581d739783a43c232a6c86112afa1e6c318c4"), + Operations: []*types.Operation{ + { + Type: opDeveloperRewardsAsScResult, + OperationIdentifier: indexToOperationIdentifier(0), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("1774725000000"), + Status: &opStatusSuccess, + }, + }, + } + + require.Equal(t, expectedTx1, txs[1]) + + // Fee refund + expectedTx2 := &types.Transaction{ + TransactionIdentifier: hashToTransactionIdentifier("bc89442d5e77113f0b4e7383e5d078776fc6724690ba9f98d1704202c324e090"), + Operations: []*types.Operation{ + { + Type: opFeeRefundAsScResult, + OperationIdentifier: indexToOperationIdentifier(0), + Account: addressToAccountIdentifier("erd1tn62hjp72rznp8vq0lplva5csav6rccpqqdungpxtqz0g2hcq6uq9k4cc6"), + Amount: extension.valueToNativeAmount("29185000000000"), + Status: &opStatusSuccess, + }, + }, + } + + require.Equal(t, expectedTx2, txs[2]) + }) +} + func readTestBlocks(filePath string) ([]*api.Block, error) { var blocks []*api.Block diff --git a/testscommon/networkProviderMock.go b/testscommon/networkProviderMock.go index 9d185f9a..38c5606e 100644 --- a/testscommon/networkProviderMock.go +++ b/testscommon/networkProviderMock.go @@ -31,6 +31,7 @@ type networkProviderMock struct { MockCustomCurrencies []resources.Currency MockGenesisBlockHash string MockGenesisTimestamp int64 + MockActivationEpochSpica uint32 MockNetworkConfig *resources.NetworkConfig MockGenesisBalances []*resources.GenesisBalance MockNodeStatus *resources.AggregatedNodeStatus @@ -362,3 +363,8 @@ func (mock *networkProviderMock) GetMempoolTransactionByHash(hash string) (*tran return nil, nil } + +// IsReleaseSpicaActive - +func (mock *networkProviderMock) IsReleaseSpicaActive(epoch uint32) bool { + return epoch >= mock.MockActivationEpochSpica +} From b1a6ab55403c68e88bad0619157d4cf7845ba024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 21 Aug 2024 16:47:30 +0300 Subject: [PATCH 2/3] Fix import. --- server/services/transactionEventsController.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/services/transactionEventsController.go b/server/services/transactionEventsController.go index 57bf6807..c8045d87 100644 --- a/server/services/transactionEventsController.go +++ b/server/services/transactionEventsController.go @@ -2,6 +2,7 @@ package services import ( "fmt" + "math/big" "strings" "github.com/multiversx/mx-chain-core-go/data/transaction" From 9bcda271b5a07ddaf7dd77d8929acdf41fa6f950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 21 Aug 2024 16:54:54 +0300 Subject: [PATCH 3/3] Add some test contracts. --- systemtests/contracts/adder.wasm | Bin 0 -> 697 bytes systemtests/contracts/developer_rewards.wasm | Bin 0 -> 973 bytes systemtests/contracts/dummy.wasm | Bin 0 -> 115 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 systemtests/contracts/adder.wasm create mode 100755 systemtests/contracts/developer_rewards.wasm create mode 100755 systemtests/contracts/dummy.wasm diff --git a/systemtests/contracts/adder.wasm b/systemtests/contracts/adder.wasm new file mode 100644 index 0000000000000000000000000000000000000000..67af5e5cf2fa468f4fbbb1476d191b4ad48eae8b GIT binary patch literal 697 zcmZuvO^?$s5S_8JZ8l~b@3sPU#UbPbCvJ!%sYDSHTCKEjPTa;#t2W8XNkBcNKY=R} z2YwHKs*IBs35i2I_Iq#Md?=u*9034dxd}i5*e0xP`x6puA>nQJw!s3}vhPfAU3{G` zHrdCb{-EnGMYYKaokk{Wa$VHGE$?T#zH9O`SOHp8SgG2*H>NbbZko@U)k>SWDf3xp zdG-TlGsY+Wp)QTev< zGk^sr{fzTXv8mR7+j1;**;7%P!hj18(cwe8NpeHr1D~}J{W`ef6o&WiAlG?m_6!`d ztKoV;3wmgBxZ#RS#_m$>b~Cly!erPyW=5qNuDv);Rjp!Oq#Q&XueExN7pl@6z2E4K z5ZegklMo~XAg1>D^WfU=C4&gJA-rLhnSjIq=FU4`L7)_T|nyX(ky5=BUB13^j( zBtC(PDj$&#;3Mey3GUdt5d{qeV~y^eGxu@s(HN3q$pC=$y%Db}7%|%Zx@s4zMz-g|$2?XHpT}!Xd+_$sUte66rLp0IlaG=sO*F^!$K=)F8vdAu8Zj7#86Mp0&YGSNda8Y}~e4fHZgQm_ru8Rt4FwJI)F<3X}mfMa=XyBv!FcYRhd z_3hdg-qdrKdYR=H9Bd+1g6o~0O!6ev;E6OFW=ma8XR8VLq9rz%&K4;I9b(?NTk_$< z@gkWmpX)Qd$WC$d7m=9dzOkrlbPtqI<+In;;K8 z>7#!mgElNQ#+O3X*M?4{>LzT5vUW)!gLO7G#sDJ>aR&wNVh7{+qp5$ttKe`x%5qwxW0O!__p857}% zlr_4xpCEldZK@@$IWLYg;$$>R!^ujw)OgM;Xp60|<5z-Be> JmuAnw{sGKc6}kWb literal 0 HcmV?d00001