From b10a821e9db7447eec6a868e219976c32316854b Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 15 Jun 2026 17:55:24 +0300 Subject: [PATCH 01/12] fixed some todos --- epochStart/metachain/epochStartData.go | 1 - factory/api/apiResolverFactory.go | 1 + .../testProcessorNodeWithTestWebServer.go | 1 + .../external/transactionAPI/apiTransactionArgs.go | 2 ++ .../transactionAPI/apiTransactionProcessor.go | 14 +++++++++----- .../apiTransactionProcessor_test.go | 15 +++++++++++++++ node/external/transactionAPI/check.go | 3 +++ process/block/metablockProposal.go | 1 - process/block/shardblockProposal.go | 5 ++++- process/block/shardblockProposal_test.go | 7 ++++++- 10 files changed, 41 insertions(+), 9 deletions(-) diff --git a/epochStart/metachain/epochStartData.go b/epochStart/metachain/epochStartData.go index dfff4361e7a..2004f225495 100644 --- a/epochStart/metachain/epochStartData.go +++ b/epochStart/metachain/epochStartData.go @@ -418,7 +418,6 @@ func (e *epochStartData) computePendingMiniBlockList( epochStartIdentifier := core.EpochStartIdentifier(prevEpoch) - // TODO: analyse error handling here previousEpochStartMeta, _ := process.GetMetaHeaderFromStorage([]byte(epochStartIdentifier), e.marshalizer, e.store) allPending := make([]block.MiniBlockHeader, 0) diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index 170d05ac839..e8481cac46b 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -250,6 +250,7 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { EnableEpochsHandler: args.CoreComponents.EnableEpochsHandler(), EnableRoundsHandler: args.CoreComponents.EnableRoundsHandler(), TxVersionChecker: args.CoreComponents.TxVersionChecker(), + ChainHandler: args.DataComponents.Blockchain(), } apiTransactionProcessor, err := transactionAPI.NewAPITransactionProcessor(argsAPITransactionProc) if err != nil { diff --git a/integrationTests/testProcessorNodeWithTestWebServer.go b/integrationTests/testProcessorNodeWithTestWebServer.go index e7624d7bba2..95a3eb79fba 100644 --- a/integrationTests/testProcessorNodeWithTestWebServer.go +++ b/integrationTests/testProcessorNodeWithTestWebServer.go @@ -245,6 +245,7 @@ func createFacadeComponents(tpn *TestProcessorNode) nodeFacade.ApiResolver { EnableEpochsHandler: tpn.EnableEpochsHandler, EnableRoundsHandler: tpn.EnableRoundsHandler, TxVersionChecker: versioning.NewTxVersionChecker(tpn.MinTransactionVersion), + ChainHandler: tpn.BlockChain, } apiTransactionHandler, err := transactionAPI.NewAPITransactionProcessor(argsApiTransactionProc) log.LogIfError(err) diff --git a/node/external/transactionAPI/apiTransactionArgs.go b/node/external/transactionAPI/apiTransactionArgs.go index f274fc07a51..71c1ac16f97 100644 --- a/node/external/transactionAPI/apiTransactionArgs.go +++ b/node/external/transactionAPI/apiTransactionArgs.go @@ -4,6 +4,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/typeConverters" "github.com/multiversx/mx-chain-core-go/marshal" @@ -33,4 +34,5 @@ type ArgAPITransactionProcessor struct { EnableEpochsHandler common.EnableEpochsHandler EnableRoundsHandler common.EnableRoundsHandler TxVersionChecker process.TxVersionCheckerHandler + ChainHandler data.ChainHandler } diff --git a/node/external/transactionAPI/apiTransactionProcessor.go b/node/external/transactionAPI/apiTransactionProcessor.go index 6b3f31815e6..be66d2dfd53 100644 --- a/node/external/transactionAPI/apiTransactionProcessor.go +++ b/node/external/transactionAPI/apiTransactionProcessor.go @@ -10,6 +10,7 @@ import ( "time" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" rewardTxData "github.com/multiversx/mx-chain-core-go/data/rewardTx" @@ -54,6 +55,7 @@ type apiTransactionProcessor struct { enableEpochsHandler common.EnableEpochsHandler enableRoundsHandler common.EnableRoundsHandler txVersionChecker process.TxVersionCheckerHandler + chainHandler data.ChainHandler } // NewAPITransactionProcessor will create a new instance of apiTransactionProcessor @@ -110,6 +112,7 @@ func NewAPITransactionProcessor(args *ArgAPITransactionProcessor) (*apiTransacti enableEpochsHandler: args.EnableEpochsHandler, enableRoundsHandler: args.EnableRoundsHandler, txVersionChecker: args.TxVersionChecker, + chainHandler: args.ChainHandler, }, nil } @@ -625,11 +628,12 @@ func (atp *apiTransactionProcessor) getVirtualNonceWithBlockInfo( // the SelectionSession is used in this flow for fallbacks (e.g. the account does not exist in the proposed blocks, unexpected errors etc.) - // TODO use the right information below - // these variables will also be used for the response - // NOTE: should not remain like this - var latestCommittedBlockHash []byte - var currentNonce uint64 + latestCommittedBlockHash := atp.chainHandler.GetCurrentBlockHeaderHash() + currentHeader := atp.chainHandler.GetCurrentBlockHeader() + currentNonce := uint64(0) + if !check.IfNil(currentHeader) { + currentNonce = currentHeader.GetNonce() + } virtualNonce, rootHash, err := txCache.GetVirtualNonceAndRootHash(address) if err != nil { diff --git a/node/external/transactionAPI/apiTransactionProcessor_test.go b/node/external/transactionAPI/apiTransactionProcessor_test.go index c76fd90c648..bea3165c882 100644 --- a/node/external/transactionAPI/apiTransactionProcessor_test.go +++ b/node/external/transactionAPI/apiTransactionProcessor_test.go @@ -82,6 +82,7 @@ func createMockArgAPITransactionProcessor() *ArgAPITransactionProcessor { EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(), EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + ChainHandler: &testscommon.ChainHandlerMock{}, } } @@ -240,6 +241,15 @@ func TestNewAPITransactionProcessor(t *testing.T) { _, err := NewAPITransactionProcessor(arguments) require.Equal(t, process.ErrNilTransactionVersionChecker, err) }) + t.Run("NilChainHandler", func(t *testing.T) { + t.Parallel() + + arguments := createMockArgAPITransactionProcessor() + arguments.ChainHandler = nil + + _, err := NewAPITransactionProcessor(arguments) + require.Equal(t, process.ErrNilBlockChain, err) + }) } func TestNode_GetTransactionInvalidHashShouldErr(t *testing.T) { @@ -415,6 +425,7 @@ func TestNode_GetSCRs(t *testing.T) { TxMarshaller: &mock.MarshalizerFake{}, EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + ChainHandler: &testscommon.ChainHandlerMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -633,6 +644,7 @@ func TestNode_GetTransactionCheckExecutionResults(t *testing.T) { }, }, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + ChainHandler: &testscommon.ChainHandlerMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -718,6 +730,7 @@ func TestNode_GetTransactionCheckExecutionResults(t *testing.T) { }, }, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + ChainHandler: &testscommon.ChainHandlerMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -811,6 +824,7 @@ func TestNode_GetTransactionWithResultsFromStorage(t *testing.T) { EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(), EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + ChainHandler: &testscommon.ChainHandlerMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -1849,6 +1863,7 @@ func createAPITransactionProc(t *testing.T, epoch uint32, withDbLookupExt bool) }, EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, + ChainHandler: &testscommon.ChainHandlerMock{}, } apiTransactionProc, err := NewAPITransactionProcessor(args) require.Nil(t, err) diff --git a/node/external/transactionAPI/check.go b/node/external/transactionAPI/check.go index 23066a6294e..b4dcc307757 100644 --- a/node/external/transactionAPI/check.go +++ b/node/external/transactionAPI/check.go @@ -57,6 +57,9 @@ func checkNilArgs(arg *ArgAPITransactionProcessor) error { if check.IfNil(arg.TxVersionChecker) { return process.ErrNilTransactionVersionChecker } + if check.IfNil(arg.ChainHandler) { + return process.ErrNilBlockChain + } return nil } diff --git a/process/block/metablockProposal.go b/process/block/metablockProposal.go index af9317e7e63..6eda6c73f2a 100644 --- a/process/block/metablockProposal.go +++ b/process/block/metablockProposal.go @@ -26,7 +26,6 @@ type usedShardHeadersInfo struct { // CreateNewHeaderProposal creates a new header func (mp *metaProcessor) CreateNewHeaderProposal(round uint64, nonce uint64) (data.HeaderHandler, error) { - // TODO: the trigger would need to be changed upon commit of a block with the epoch start results epoch := mp.epochStartTrigger.Epoch() header := mp.versionedHeaderFactory.Create(epoch, round) diff --git a/process/block/shardblockProposal.go b/process/block/shardblockProposal.go index 6e9618b061f..98014ea19a2 100644 --- a/process/block/shardblockProposal.go +++ b/process/block/shardblockProposal.go @@ -112,7 +112,10 @@ func (sp *shardProcessor) CreateBlockProposal( return nil, nil, err } - // TODO: sanity check use the verify execution results method + err = sp.executionResultsVerifier.VerifyHeaderExecutionResults(shardHdr) + if err != nil { + return nil, nil, err + } body := &block.Body{MiniBlocks: miniBlocks} diff --git a/process/block/shardblockProposal_test.go b/process/block/shardblockProposal_test.go index d91f516f471..825dc7b01bb 100644 --- a/process/block/shardblockProposal_test.go +++ b/process/block/shardblockProposal_test.go @@ -429,7 +429,12 @@ func TestShardProcessor_CreateBlockProposal(t *testing.T) { coreComponents, dataComponents, bootstrapComponents, statusComponents := createComponentHolderMocks() dataComponents.BlockChain = &testscommon.ChainHandlerStub{ GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.HeaderV2{} // using V2 for simplicity + return &block.HeaderV3{ + PrevHash: []byte("prev hash"), + LastExecutionResult: &block.ExecutionResultInfo{ + ExecutionResult: &block.BaseExecutionResult{}, + }, + } }, GetCurrentBlockHeaderHashCalled: func() []byte { return []byte("hash") From 8086e78702d01c5e20d87db228013b2c5cd18a80 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 16 Jun 2026 09:34:27 +0300 Subject: [PATCH 02/12] removed one more todo --- process/block/shardblock.go | 1 - 1 file changed, 1 deletion(-) diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 924189c4c26..c9c3814ba24 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -1268,7 +1268,6 @@ func (sp *shardProcessor) updateState(headers []data.HeaderHandler, currentHeade return } - // TODO: set proper finalized header in outport sp.setFinalizedHeaderHashInIndexer(currentHeaderHash) scheduledHeaderRootHash, _ := sp.scheduledTxsExecutionHandler.GetScheduledRootHashForHeader(currentHeaderHash) From e475fb93bf6a5f137649b2796ff987e389589d01 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Tue, 16 Jun 2026 13:06:53 +0300 Subject: [PATCH 03/12] removed one more todo --- process/block/shardblock.go | 1 - 1 file changed, 1 deletion(-) diff --git a/process/block/shardblock.go b/process/block/shardblock.go index c9c3814ba24..d5af7b375f1 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -1484,7 +1484,6 @@ func (sp *shardProcessor) setFinalBlockInfo( finalRootHash = header.GetRootHash() } - // TODO: maybe rename this to reflect last execution results sp.blockChain.SetFinalBlockInfo(header.GetNonce(), headerHash, finalRootHash) } From 75a50dcef8afb1d84d03cdb5180441b272de6a60 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 17 Jun 2026 13:56:46 +0300 Subject: [PATCH 04/12] todo: extract the epoch change proposal execution result here --- consensus/broadcast/shardChainMessenger.go | 1 - epochStart/metachain/economics.go | 33 ++++++++++++++---- epochStart/metachain/economics_test.go | 37 +++++++++++++++++++++ factory/processing/blockProcessorCreator.go | 1 + integrationTests/testFullNode.go | 1 + integrationTests/testProcessorNode.go | 1 + 6 files changed, 66 insertions(+), 8 deletions(-) diff --git a/consensus/broadcast/shardChainMessenger.go b/consensus/broadcast/shardChainMessenger.go index d7bbb8afd76..233055bc9f8 100644 --- a/consensus/broadcast/shardChainMessenger.go +++ b/consensus/broadcast/shardChainMessenger.go @@ -180,7 +180,6 @@ func (scm *shardChainMessenger) prepareDataToBroadcast( return nil, err } - // TODO: check if miniblocks and txs are set in a deterministic way (check if there are map iterations that can generate non-deterministic results) metaMiniBlocks, metaTransactions := scm.extractMetaMiniBlocksAndTransactions(miniBlocks, transactions) dtb := &dataToBroadcast{ diff --git a/epochStart/metachain/economics.go b/epochStart/metachain/economics.go index e65cefd924b..12dfc8bbbb1 100644 --- a/epochStart/metachain/economics.go +++ b/epochStart/metachain/economics.go @@ -42,6 +42,7 @@ type economics struct { marshalizer marshal.Marshalizer hasher hashing.Hasher store dataRetriever.StorageService + headers dataRetriever.HeadersPool shardCoordinator sharding.Coordinator rewardsHandler process.RewardsHandler roundTime process.RoundTimeDurationHandler @@ -60,6 +61,7 @@ type ArgsNewEpochEconomics struct { Marshalizer marshal.Marshalizer Hasher hashing.Hasher Store dataRetriever.StorageService + Headers dataRetriever.HeadersPool ShardCoordinator sharding.Coordinator RewardsHandler process.RewardsHandler RoundTime process.RoundTimeDurationHandler @@ -84,6 +86,9 @@ func NewEndOfEpochEconomicsDataCreator(args ArgsNewEpochEconomics) (*economics, if check.IfNil(args.Store) { return nil, epochStart.ErrNilStorage } + if check.IfNil(args.Headers) { + return nil, epochStart.ErrNilHeadersDataPool + } if check.IfNil(args.ShardCoordinator) { return nil, epochStart.ErrNilShardCoordinator } @@ -110,6 +115,7 @@ func NewEndOfEpochEconomicsDataCreator(args ArgsNewEpochEconomics) (*economics, marshalizer: args.Marshalizer, hasher: args.Hasher, store: args.Store, + headers: args.Headers, shardCoordinator: args.ShardCoordinator, rewardsHandler: args.RewardsHandler, roundTime: args.RoundTime, @@ -655,7 +661,7 @@ func (e *economics) startNoncePerShardFromEpochStart(epoch uint32) (map[uint32]u return mapShardIdNonce, previousEpochStartMeta, nil } - prevEpochMetaNonce, err := getPrevEpochMetaStartNonceForEconomics(previousEpochStartMeta) + prevEpochMetaNonce, err := e.getPrevEpochMetaStartNonceForEconomics(previousEpochStartMeta) if err != nil { return nil, nil, err } @@ -667,17 +673,30 @@ func (e *economics) startNoncePerShardFromEpochStart(epoch uint32) (map[uint32]u return mapShardIdNonce, previousEpochStartMeta, nil } -func getPrevEpochMetaStartNonceForEconomics(previousEpochStartMeta data.MetaHeaderHandler) (uint64, error) { +func (e *economics) getPrevEpochMetaStartNonceForEconomics(previousEpochStartMeta data.MetaHeaderHandler) (uint64, error) { if !previousEpochStartMeta.IsHeaderV3() { return previousEpochStartMeta.GetNonce(), nil } - // todo: extract the epoch change proposal execution result here - lastNotarizedResult, err := common.GetLastBaseExecutionResultHandler(previousEpochStartMeta) - if err != nil { - return 0, err + + for _, execResult := range previousEpochStartMeta.GetExecutionResultsHandlers() { + hdr, err := process.GetMetaHeader( + execResult.GetHeaderHash(), + e.headers, + e.marshalizer, + e.store, + ) + if err != nil { + return 0, err + } + + if hdr.IsEpochChangeProposed() { + return hdr.GetNonce(), nil + } } - return lastNotarizedResult.GetHeaderNonce(), nil + log.Debug("getPrevEpochMetaStartNonceForEconomics could not find epoch change proposed header") + + return 0, epochStart.ErrMissingHeader } func (e *economics) maxPossibleNotarizedBlocks(currentRound uint64, prev data.MetaHeaderHandler) uint64 { diff --git a/epochStart/metachain/economics_test.go b/epochStart/metachain/economics_test.go index 3e8242c0f0a..0462853d403 100644 --- a/epochStart/metachain/economics_test.go +++ b/epochStart/metachain/economics_test.go @@ -12,6 +12,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/testscommon/pool" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,6 +40,7 @@ func createMockEpochEconomicsArguments() ArgsNewEpochEconomics { Hasher: &hashingMocks.HasherMock{}, Marshalizer: &mock.MarshalizerMock{}, Store: createMetaStore(), + Headers: &pool.HeadersPoolStub{}, ShardCoordinator: shardCoordinator, RewardsHandler: &mock.RewardsHandlerStub{}, RoundTime: &mock.RoundTimeDurationHandler{}, @@ -83,6 +85,17 @@ func TestEpochEconomics_NewEndOfEpochEconomicsDataCreatorNilStore(t *testing.T) require.Equal(t, epochStart.ErrNilStorage, err) } +func TestEpochEconomics_NewEndOfEpochEconomicsDataCreatorNilHeadersPool(t *testing.T) { + t.Parallel() + + arguments := createMockEpochEconomicsArguments() + arguments.Headers = nil + + esd, err := NewEndOfEpochEconomicsDataCreator(arguments) + require.Nil(t, esd) + require.Equal(t, epochStart.ErrNilHeadersDataPool, err) +} + func TestEpochEconomics_NewEndOfEpochEconomicsDataCreatorNilShardCoordinator(t *testing.T) { t.Parallel() @@ -2459,6 +2472,21 @@ func TestEconomics_createEconomicsV3Args(t *testing.T) { DevFeesInEpoch: big.NewInt(300), }, }, + ExecutionResults: []*block.MetaExecutionResult{ + { + ExecutionResult: &block.BaseMetaExecutionResult{ + BaseExecutionResult: &block.BaseExecutionResult{ + HeaderHash: []byte("some hash"), + HeaderEpoch: 2, + HeaderNonce: 3, + RootHash: []byte("some root hash"), + }, + ValidatorStatsRootHash: []byte("validator stats root hash"), + AccumulatedFeesInEpoch: big.NewInt(1000), + DevFeesInEpoch: big.NewInt(300), + }, + }, + }, } t.Run("nil meta block", func(t *testing.T) { @@ -2561,6 +2589,14 @@ func TestEconomics_createEconomicsV3Args(t *testing.T) { }, }, } + arguments.Headers = &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return &block.MetaBlockV3{ + EpochChangeProposed: true, + Nonce: metaBlockCopy.ExecutionResults[0].GetHeaderNonce(), + }, nil + }, + } economicsCreator, _ := NewEndOfEpochEconomicsDataCreator(arguments) res, err := economicsCreator.createEconomicsV3Args(&metaBlockCopy, metaExecRes, epochStartDta) @@ -3048,6 +3084,7 @@ func getArguments() ArgsNewEpochEconomics { Marshalizer: &mock.MarshalizerMock{}, Hasher: &hashingMocks.HasherMock{}, Store: &storageStubs.ChainStorerStub{}, + Headers: &pool.HeadersPoolStub{}, ShardCoordinator: mock.NewMultipleShardsCoordinatorMock(), RewardsHandler: &mock.RewardsHandlerStub{}, RoundTime: &mock.RoundTimeDurationHandler{}, diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 3e6b4232c82..d2137feb39b 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -1042,6 +1042,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( Marshalizer: pcf.coreData.InternalMarshalizer(), Hasher: pcf.coreData.Hasher(), Store: pcf.data.StorageService(), + Headers: pcf.data.Datapool().Headers(), ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), RewardsHandler: pcf.coreData.EconomicsData(), RoundTime: pcf.coreData.RoundHandler(), diff --git a/integrationTests/testFullNode.go b/integrationTests/testFullNode.go index ae6f2f9d362..db12e6d8870 100644 --- a/integrationTests/testFullNode.go +++ b/integrationTests/testFullNode.go @@ -1111,6 +1111,7 @@ func (tpn *TestFullNode) initBlockProcessor( Marshalizer: TestMarshalizer, Hasher: TestHasher, Store: tpn.Storage, + Headers: tpn.DataPool.Headers(), ShardCoordinator: tpn.ShardCoordinator, RewardsHandler: tpn.EconomicsData, RoundTime: roundHandler, diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 24dd8c40045..d5413c7ffe5 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2724,6 +2724,7 @@ func (tpn *TestProcessorNode) initBlockProcessor() { Marshalizer: TestMarshalizer, Hasher: TestHasher, Store: tpn.Storage, + Headers: tpn.DataPool.Headers(), ShardCoordinator: tpn.ShardCoordinator, RewardsHandler: tpn.EconomicsData, RoundTime: tpn.RoundHandler, From 2541c64bcdb1a2e0529a3ce726bcd94164fb4096 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 17 Jun 2026 14:37:30 +0300 Subject: [PATCH 05/12] TODO use the right object, not a disabled one --- errors/errors.go | 3 +++ factory/api/apiResolverFactory.go | 1 + factory/interface.go | 1 + factory/mock/processComponentsStub.go | 6 ++++++ factory/processing/blockProcessorCreator.go | 3 +++ factory/processing/processComponents.go | 2 ++ factory/processing/processComponentsHandler.go | 15 +++++++++++++++ integrationTests/mock/processComponentsStub.go | 6 ++++++ .../testProcessorNodeWithTestWebServer.go | 1 + .../components/processComponents.go | 7 +++++++ .../external/transactionAPI/apiTransactionArgs.go | 1 + .../transactionAPI/apiTransactionProcessor.go | 7 +++---- .../apiTransactionProcessor_test.go | 6 ++++++ node/external/transactionAPI/check.go | 3 +++ 14 files changed, 58 insertions(+), 4 deletions(-) diff --git a/errors/errors.go b/errors/errors.go index 7f9b5e85438..aafbe35977e 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -616,3 +616,6 @@ var ErrNilTrieLeavesRetriever = errors.New("nil trie leaves retriever") // ErrNilAOTSelector signals that a nil AOT selector has been provided var ErrNilAOTSelector = errors.New("nil AOT selector") + +// ErrNilTransactionProcessor signals that a nil transaction processor has been provided +var ErrNilTransactionProcessor = errors.New("nil transaction processor") diff --git a/factory/api/apiResolverFactory.go b/factory/api/apiResolverFactory.go index e8481cac46b..cdd44f66006 100644 --- a/factory/api/apiResolverFactory.go +++ b/factory/api/apiResolverFactory.go @@ -251,6 +251,7 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { EnableRoundsHandler: args.CoreComponents.EnableRoundsHandler(), TxVersionChecker: args.CoreComponents.TxVersionChecker(), ChainHandler: args.DataComponents.Blockchain(), + TxProcessor: args.ProcessComponents.TransactionProcessor(), } apiTransactionProcessor, err := transactionAPI.NewAPITransactionProcessor(argsAPITransactionProc) if err != nil { diff --git a/factory/interface.go b/factory/interface.go index b594b3842e4..5163905224f 100644 --- a/factory/interface.go +++ b/factory/interface.go @@ -329,6 +329,7 @@ type ProcessComponentsHolder interface { EpochSystemSCProcessor() process.EpochStartSystemSCProcessor BlockchainHook() process.BlockChainHookWithAccountsAdapter AOTSelector() process.AOTTransactionSelector + TransactionProcessor() process.TransactionProcessor IsInterfaceNil() bool } diff --git a/factory/mock/processComponentsStub.go b/factory/mock/processComponentsStub.go index 04bce4408be..e1bc3f1dc24 100644 --- a/factory/mock/processComponentsStub.go +++ b/factory/mock/processComponentsStub.go @@ -62,6 +62,7 @@ type ProcessComponentsMock struct { EpochSystemSCProcessorInternal process.EpochStartSystemSCProcessor BlockchainHookField process.BlockChainHookWithAccountsAdapter AOTSelectorField process.AOTTransactionSelector + TransactionProcessorField process.TransactionProcessor } // Create - @@ -309,6 +310,11 @@ func (pcm *ProcessComponentsMock) AOTSelector() process.AOTTransactionSelector { return pcm.AOTSelectorField } +// TransactionProcessor - +func (pcm *ProcessComponentsMock) TransactionProcessor() process.TransactionProcessor { + return pcm.TransactionProcessorField +} + // IsInterfaceNil - func (pcm *ProcessComponentsMock) IsInterfaceNil() bool { return pcm == nil diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index d2137feb39b..e42133d0be7 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -59,6 +59,7 @@ type blockProcessorAndVmFactories struct { vmFactoryForProcessing process.VirtualMachinesContainerFactory epochSystemSCProcessor process.EpochStartSystemSCProcessor aotSelector process.AOTTransactionSelector + transactionProcessor process.TransactionProcessor } func (pcf *processComponentsFactory) newBlockProcessor( @@ -688,6 +689,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( vmFactoryForProcessing: vmFactory, epochSystemSCProcessor: factoryDisabled.NewDisabledEpochStartSystemSC(), aotSelector: aotSelector, + transactionProcessor: transactionProcessor, } pcf.stakingDataProviderAPI = factoryDisabled.NewDisabledStakingDataProvider() @@ -1380,6 +1382,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( vmFactoryForProcessing: vmFactory, epochSystemSCProcessor: epochStartSystemSCProcessor, aotSelector: aotSelector, + transactionProcessor: transactionProcessor, } return blockProcessorComponents, nil diff --git a/factory/processing/processComponents.go b/factory/processing/processComponents.go index 40959d170c9..3f7d4137b48 100644 --- a/factory/processing/processComponents.go +++ b/factory/processing/processComponents.go @@ -144,6 +144,7 @@ type processComponents struct { interceptedDataVerifierFactory process.InterceptedDataVerifierFactory epochStartTriggerHanlder epochStart.TriggerHandler aotSelector process.AOTTransactionSelector + transactionProcessor process.TransactionProcessor } // ProcessComponentsFactoryArgs holds the arguments needed to create a process components factory @@ -840,6 +841,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) { interceptedDataVerifierFactory: pcf.interceptedDataVerifierFactory, epochStartTriggerHanlder: epochStartTrigger, aotSelector: blockProcessorComponents.aotSelector, + transactionProcessor: blockProcessorComponents.transactionProcessor, }, nil } diff --git a/factory/processing/processComponentsHandler.go b/factory/processing/processComponentsHandler.go index abf70cd1eb9..9fe122a4dad 100644 --- a/factory/processing/processComponentsHandler.go +++ b/factory/processing/processComponentsHandler.go @@ -187,6 +187,9 @@ func (m *managedProcessComponents) CheckSubcomponents() error { if check.IfNil(m.processComponents.aotSelector) { return errors.ErrNilAOTSelector } + if check.IfNil(m.processComponents.transactionProcessor) { + return errors.ErrNilTransactionProcessor + } return nil } @@ -735,6 +738,18 @@ func (m *managedProcessComponents) AOTSelector() process.AOTTransactionSelector return m.processComponents.aotSelector } +// TransactionProcessor returns the transaction processor +func (m *managedProcessComponents) TransactionProcessor() process.TransactionProcessor { + m.mutProcessComponents.RLock() + defer m.mutProcessComponents.RUnlock() + + if m.processComponents == nil { + return nil + } + + return m.processComponents.transactionProcessor +} + // IsInterfaceNil returns true if the interface is nil func (m *managedProcessComponents) IsInterfaceNil() bool { return m == nil diff --git a/integrationTests/mock/processComponentsStub.go b/integrationTests/mock/processComponentsStub.go index fe21fee154a..b4498f4f11a 100644 --- a/integrationTests/mock/processComponentsStub.go +++ b/integrationTests/mock/processComponentsStub.go @@ -65,6 +65,7 @@ type ProcessComponentsStub struct { EpochSystemSCProcessorInternal process.EpochStartSystemSCProcessor BlockchainHookField process.BlockChainHookWithAccountsAdapter AOTSelectorField process.AOTTransactionSelector + TransactionProcessorField process.TransactionProcessor } // Create - @@ -321,6 +322,11 @@ func (pcs *ProcessComponentsStub) AOTSelector() process.AOTTransactionSelector { return pcs.AOTSelectorField } +// TransactionProcessor - +func (pcs *ProcessComponentsStub) TransactionProcessor() process.TransactionProcessor { + return pcs.TransactionProcessorField +} + // IsInterfaceNil - func (pcs *ProcessComponentsStub) IsInterfaceNil() bool { return pcs == nil diff --git a/integrationTests/testProcessorNodeWithTestWebServer.go b/integrationTests/testProcessorNodeWithTestWebServer.go index 95a3eb79fba..20beeb35eba 100644 --- a/integrationTests/testProcessorNodeWithTestWebServer.go +++ b/integrationTests/testProcessorNodeWithTestWebServer.go @@ -246,6 +246,7 @@ func createFacadeComponents(tpn *TestProcessorNode) nodeFacade.ApiResolver { EnableRoundsHandler: tpn.EnableRoundsHandler, TxVersionChecker: versioning.NewTxVersionChecker(tpn.MinTransactionVersion), ChainHandler: tpn.BlockChain, + TxProcessor: tpn.TxProcessor, } apiTransactionHandler, err := transactionAPI.NewAPITransactionProcessor(argsApiTransactionProc) log.LogIfError(err) diff --git a/node/chainSimulator/components/processComponents.go b/node/chainSimulator/components/processComponents.go index 4c82f1d9118..c863a62e366 100644 --- a/node/chainSimulator/components/processComponents.go +++ b/node/chainSimulator/components/processComponents.go @@ -104,6 +104,7 @@ type processComponentsHolder struct { epochStartSystemSCProcessor process.EpochStartSystemSCProcessor blockchainHook process.BlockChainHookWithAccountsAdapter aotSelector process.AOTTransactionSelector + transactionProcessor process.TransactionProcessor managedProcessComponentsCloser io.Closer } @@ -290,6 +291,7 @@ func CreateProcessComponents(args ArgsProcessComponentsHolder) (*processComponen epochStartSystemSCProcessor: managedProcessComponents.EpochSystemSCProcessor(), blockchainHook: managedProcessComponents.BlockchainHook(), aotSelector: managedProcessComponents.AOTSelector(), + transactionProcessor: managedProcessComponents.TransactionProcessor(), executionManager: managedProcessComponents.ExecutionManager(), managedProcessComponentsCloser: managedProcessComponents, } @@ -546,6 +548,11 @@ func (p *processComponentsHolder) AOTSelector() process.AOTTransactionSelector { return p.aotSelector } +// TransactionProcessor returns the transaction processor +func (p *processComponentsHolder) TransactionProcessor() process.TransactionProcessor { + return p.transactionProcessor +} + // Close will call the Close methods on all inner components func (p *processComponentsHolder) Close() error { return p.managedProcessComponentsCloser.Close() diff --git a/node/external/transactionAPI/apiTransactionArgs.go b/node/external/transactionAPI/apiTransactionArgs.go index 71c1ac16f97..ed13ba61070 100644 --- a/node/external/transactionAPI/apiTransactionArgs.go +++ b/node/external/transactionAPI/apiTransactionArgs.go @@ -35,4 +35,5 @@ type ArgAPITransactionProcessor struct { EnableRoundsHandler common.EnableRoundsHandler TxVersionChecker process.TxVersionCheckerHandler ChainHandler data.ChainHandler + TxProcessor process.TransactionProcessor } diff --git a/node/external/transactionAPI/apiTransactionProcessor.go b/node/external/transactionAPI/apiTransactionProcessor.go index be66d2dfd53..a1a2b29607a 100644 --- a/node/external/transactionAPI/apiTransactionProcessor.go +++ b/node/external/transactionAPI/apiTransactionProcessor.go @@ -24,7 +24,6 @@ import ( "github.com/multiversx/mx-chain-go/common/holders" "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/dblookupext" - "github.com/multiversx/mx-chain-go/factory/disabled" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/preprocess" "github.com/multiversx/mx-chain-go/process/smartContract" @@ -56,6 +55,7 @@ type apiTransactionProcessor struct { enableRoundsHandler common.EnableRoundsHandler txVersionChecker process.TxVersionCheckerHandler chainHandler data.ChainHandler + txProcessor process.TransactionProcessor } // NewAPITransactionProcessor will create a new instance of apiTransactionProcessor @@ -113,6 +113,7 @@ func NewAPITransactionProcessor(args *ArgAPITransactionProcessor) (*apiTransacti enableRoundsHandler: args.EnableRoundsHandler, txVersionChecker: args.TxVersionChecker, chainHandler: args.ChainHandler, + txProcessor: args.TxProcessor, }, nil } @@ -580,11 +581,9 @@ func (atp *apiTransactionProcessor) selectTransactions(accountsAdapter state.Acc return nil, ErrCouldNotCastToTxCache } - // TODO use the right object, not a disabled one - txProcessor := disabled.TxProcessor{} argsSelectionSession := preprocess.ArgsSelectionSession{ AccountsAdapter: accountsAdapter, - TransactionsProcessor: &txProcessor, + TransactionsProcessor: atp.txProcessor, TxVersionCheckerHandler: atp.txVersionChecker, } diff --git a/node/external/transactionAPI/apiTransactionProcessor_test.go b/node/external/transactionAPI/apiTransactionProcessor_test.go index bea3165c882..786cd3274fb 100644 --- a/node/external/transactionAPI/apiTransactionProcessor_test.go +++ b/node/external/transactionAPI/apiTransactionProcessor_test.go @@ -83,6 +83,7 @@ func createMockArgAPITransactionProcessor() *ArgAPITransactionProcessor { EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, ChainHandler: &testscommon.ChainHandlerMock{}, + TxProcessor: &testscommon.TxProcessorMock{}, } } @@ -426,6 +427,7 @@ func TestNode_GetSCRs(t *testing.T) { EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, ChainHandler: &testscommon.ChainHandlerMock{}, + TxProcessor: &testscommon.TxProcessorMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -645,6 +647,7 @@ func TestNode_GetTransactionCheckExecutionResults(t *testing.T) { }, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, ChainHandler: &testscommon.ChainHandlerMock{}, + TxProcessor: &testscommon.TxProcessorMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -731,6 +734,7 @@ func TestNode_GetTransactionCheckExecutionResults(t *testing.T) { }, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, ChainHandler: &testscommon.ChainHandlerMock{}, + TxProcessor: &testscommon.TxProcessorMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -825,6 +829,7 @@ func TestNode_GetTransactionWithResultsFromStorage(t *testing.T) { EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, ChainHandler: &testscommon.ChainHandlerMock{}, + TxProcessor: &testscommon.TxProcessorMock{}, } apiTransactionProc, _ := NewAPITransactionProcessor(args) @@ -1864,6 +1869,7 @@ func createAPITransactionProc(t *testing.T, epoch uint32, withDbLookupExt bool) EnableRoundsHandler: &testscommon.EnableRoundsHandlerStub{}, TxVersionChecker: &testscommon.TxVersionCheckerStub{}, ChainHandler: &testscommon.ChainHandlerMock{}, + TxProcessor: &testscommon.TxProcessorMock{}, } apiTransactionProc, err := NewAPITransactionProcessor(args) require.Nil(t, err) diff --git a/node/external/transactionAPI/check.go b/node/external/transactionAPI/check.go index b4dcc307757..ee01c70a94d 100644 --- a/node/external/transactionAPI/check.go +++ b/node/external/transactionAPI/check.go @@ -60,6 +60,9 @@ func checkNilArgs(arg *ArgAPITransactionProcessor) error { if check.IfNil(arg.ChainHandler) { return process.ErrNilBlockChain } + if check.IfNil(arg.TxProcessor) { + return process.ErrNilTxProcessor + } return nil } From ed8104929c70ffaaba402d3230d39330b89c6753 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 17 Jun 2026 14:57:41 +0300 Subject: [PATCH 06/12] removed one todo --- process/block/shardblockProposal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/block/shardblockProposal.go b/process/block/shardblockProposal.go index 98014ea19a2..860c8e0f9bf 100644 --- a/process/block/shardblockProposal.go +++ b/process/block/shardblockProposal.go @@ -79,7 +79,7 @@ func (sp *shardProcessor) CreateBlockProposal( } miniBlockHeaderHandlers := sp.miniBlocksSelectionSession.GetMiniBlockHeaderHandlers() - // todo: check empty mini blocks vs nil. Same for block.Body.MiniBlocks + err = shardHdr.SetMiniBlockHeaderHandlers(miniBlockHeaderHandlers) if err != nil { return nil, nil, err From c77cdc0cbb1348d226777f098c0a96d1817571d0 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 17 Jun 2026 15:09:01 +0300 Subject: [PATCH 07/12] removed // TODO adjust this method if needed for Supernova --- process/block/metablock.go | 1 - process/block/shardblock.go | 1 - 2 files changed, 2 deletions(-) diff --git a/process/block/metablock.go b/process/block/metablock.go index 618817b7d67..ea2a8762427 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -1495,7 +1495,6 @@ func (mp *metaProcessor) CommitBlock( highestFinalBlockNonce: highestFinalBlockNonce, } - // TODO adjust this method if needed for Supernova mp.prepareDataForBootStorer(args) mp.blockSizeThrottler.Succeed(header.GetRound()) diff --git a/process/block/shardblock.go b/process/block/shardblock.go index d5af7b375f1..c0253e9a962 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -1162,7 +1162,6 @@ func (sp *shardProcessor) CommitBlock( epochStartTriggerConfigKey: epochStartKey, } - // TODO adjust this method if needed for Supernova sp.prepareDataForBootStorer(args) // write data to log From 50a080dbe061443e6b8f6c4cfbf451f46d1d758d Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 17 Jun 2026 17:28:34 +0300 Subject: [PATCH 08/12] TODO add also max estimated block gas capacity - used gas must be lower than this --- config/config.go | 1 - factory/processing/blockProcessorCreator.go | 8 +++ integrationTests/testFullNode.go | 2 + integrationTests/testProcessorNode.go | 1 + integrationTests/testSyncNode.go | 3 +- .../vm/staking/metaBlockProcessorCreator.go | 3 +- process/block/baseProcess_test.go | 1 + process/block/export_test.go | 1 + process/block/metablock_test.go | 1 + process/block/shardblockProposal_test.go | 4 +- .../executionResultInclusionEstimator.go | 27 ++++++-- .../executionResultInclusionEstimator_test.go | 65 ++++++++++++------- 12 files changed, 86 insertions(+), 31 deletions(-) diff --git a/config/config.go b/config/config.go index e379d3512ac..cc68f7980bb 100644 --- a/config/config.go +++ b/config/config.go @@ -49,7 +49,6 @@ type ProofsPoolConfig struct { } // ExecutionResultInclusionEstimatorConfig will map the EIE configuration - supplied at construction, read-only thereafter. -// TODO add also max estimated block gas capacity type ExecutionResultInclusionEstimatorConfig struct { SafetyMargin uint64 MaxResultsPerBlock uint64 diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index e42133d0be7..3a38c14460f 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -605,10 +605,14 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( return nil, err } + maxBlockGasCapacity := pcf.coreData.EconomicsData().MaxGasLimitPerBlock(pcf.bootstrapComponents.ShardCoordinator().SelfId()) + overestimationFactor := pcf.coreData.EconomicsData().BlockCapacityOverestimationFactor() + maxBlockGasCapacity = maxBlockGasCapacity * overestimationFactor / 100 inclusionEstimator, err := estimator.NewExecutionResultInclusionEstimator( pcf.config.ExecutionResultInclusionEstimator, pcf.coreData.RoundHandler(), execResSizeComputationHandler, + maxBlockGasCapacity, ) if err != nil { return nil, err @@ -1189,10 +1193,14 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } + maxBlockGasCapacity := pcf.coreData.EconomicsData().MaxGasLimitPerBlock(pcf.bootstrapComponents.ShardCoordinator().SelfId()) + overestimationFactor := pcf.coreData.EconomicsData().BlockCapacityOverestimationFactor() + maxBlockGasCapacity = maxBlockGasCapacity * overestimationFactor / 100 inclusionEstimator, err := estimator.NewExecutionResultInclusionEstimator( pcf.config.ExecutionResultInclusionEstimator, pcf.coreData.RoundHandler(), execResSizeComputationHandler, + maxBlockGasCapacity, ) if err != nil { return nil, err diff --git a/integrationTests/testFullNode.go b/integrationTests/testFullNode.go index db12e6d8870..7967c49fdc0 100644 --- a/integrationTests/testFullNode.go +++ b/integrationTests/testFullNode.go @@ -995,6 +995,7 @@ func (tpn *TestFullNode) initBlockProcessor( }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, + 0, ) if err != nil { log.LogIfError(err) @@ -1381,6 +1382,7 @@ func (tpn *TestFullNode) initBlockProcessorWithSync( }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, + 0, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index d5413c7ffe5..870c98be7d4 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2594,6 +2594,7 @@ func (tpn *TestProcessorNode) initBlockProcessor() { }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, + 0, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index f53374775c5..9506bdfe263 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -162,6 +162,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, + 0, ) if err != nil { log.LogIfError(err) @@ -213,7 +214,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { }, }, BlockTracker: tpn.BlockTracker, - MiniBlockTracker: &testscommon.MiniBlockTrackerStub{}, + MiniBlockTracker: &testscommon.MiniBlockTrackerStub{}, BlockSizeThrottler: TestBlockSizeThrottler, HistoryRepository: tpn.HistoryRepository, GasHandler: tpn.GasHandler, diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index eb59ce9b6e5..2ad31cb3260 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -137,6 +137,7 @@ func createMetaBlockProcessor( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, + 0, ) missingDataArgs := missingData.ResolverArgs{ @@ -179,7 +180,7 @@ func createMetaBlockProcessor( HeaderValidator: headerValidator, BootStorer: bootStorer, BlockTracker: blockTracker, - MiniBlockTracker: &testscommon.MiniBlockTrackerStub{}, + MiniBlockTracker: &testscommon.MiniBlockTrackerStub{}, BlockSizeThrottler: &mock.BlockSizeThrottlerStub{}, HistoryRepository: &dblookupext.HistoryRepositoryStub{}, VMContainersFactory: metaVMFactory, diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 3032f7f202d..d47925b57b3 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -193,6 +193,7 @@ func createArgBaseProcessor( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, + 0, ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/export_test.go b/process/block/export_test.go index 9c9f924442e..4d4b6feb89b 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -250,6 +250,7 @@ func NewShardProcessorEmptyWith3shards( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, + 0, ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 1b13440a5cc..655e0a41f25 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -193,6 +193,7 @@ func createMockMetaArguments( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, + 0, ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/shardblockProposal_test.go b/process/block/shardblockProposal_test.go index 825dc7b01bb..cb1b43dfc72 100644 --- a/process/block/shardblockProposal_test.go +++ b/process/block/shardblockProposal_test.go @@ -1414,7 +1414,7 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { MaxResultsPerBlock: 10, } - executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}) + executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, 0) executionResult1 := &block.ExecutionResult{ BaseExecutionResult: &block.BaseExecutionResult{HeaderHash: []byte("hash1"), HeaderNonce: 1, HeaderRound: 2, GasUsed: 100_000_000}, @@ -1500,7 +1500,7 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { }, } - execResEst, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}) + execResEst, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, 0) sp, _ := blproc.ConstructPartialShardBlockProcessorForTest(map[string]interface{}{ "executionManager": &processMocks.ExecutionManagerMock{ diff --git a/process/estimator/executionResultInclusionEstimator.go b/process/estimator/executionResultInclusionEstimator.go index 33f0e1e625e..0f4e3f17075 100644 --- a/process/estimator/executionResultInclusionEstimator.go +++ b/process/estimator/executionResultInclusionEstimator.go @@ -31,10 +31,10 @@ type RoundHandler interface { // node. It determines, at proposal‑time and at validation‑time, whether one or more pending execution results can be // safely embedded in the block that is being produced / verified. type ExecutionResultInclusionEstimator struct { - cfg config.ExecutionResultInclusionEstimatorConfig // immutable after construction - tGas uint64 // time per gas unit on minimum‑spec hardware - 1 ns per gas unit - roundHandler RoundHandler - // TODO add also max estimated block gas capacity - used gas must be lower than this + cfg config.ExecutionResultInclusionEstimatorConfig // immutable after construction + tGas uint64 // time per gas unit on minimum‑spec hardware - 1 ns per gas unit + roundHandler RoundHandler + maxBlockGasCapacity uint64 // max cumulative gas of the included execution results (0 = uncapped) execResSizeComputation ExecResSizeComputationHandler } @@ -43,6 +43,7 @@ func NewExecutionResultInclusionEstimator( cfg config.ExecutionResultInclusionEstimatorConfig, roundHandler RoundHandler, execResultComputationHandler ExecResSizeComputationHandler, + maxBlockGasCapacity uint64, ) (*ExecutionResultInclusionEstimator, error) { err := checkConfig(cfg) if err != nil { @@ -56,6 +57,7 @@ func NewExecutionResultInclusionEstimator( cfg: cfg, tGas: tGas, roundHandler: roundHandler, + maxBlockGasCapacity: maxBlockGasCapacity, execResSizeComputation: execResultComputationHandler, }, nil } @@ -106,6 +108,7 @@ func (erie *ExecutionResultInclusionEstimator) Decide( // accumulated execution tBase for each pending execution result in ns (1 gas = 1ns) estimatedTBase := tBase + var accumulatedGas uint64 for pendingExecutionIndex, executionResultMeta := range pending { if pendingExecutionIndex > 0 { previousExecutionResultMeta = pending[pendingExecutionIndex-1] @@ -164,6 +167,22 @@ func (erie *ExecutionResultInclusionEstimator) Decide( return pendingExecutionIndex } + newAccumulatedGas, overflow := bits.Add64(accumulatedGas, executionResultMeta.GetGasUsed(), 0) + if overflow != 0 { + log.Debug("ExecutionResultInclusionEstimator: overflow detected in accumulated gas", + "accumulatedGas", accumulatedGas, + "gasUsed", executionResultMeta.GetGasUsed()) + return pendingExecutionIndex + } + if erie.maxBlockGasCapacity > 0 && newAccumulatedGas > erie.maxBlockGasCapacity { + log.Debug("ExecutionResultInclusionEstimator: max block gas capacity reached", + "accumulatedGas", newAccumulatedGas, + "maxBlockGasCapacity", erie.maxBlockGasCapacity, + "currentIndex", pendingExecutionIndex) + return pendingExecutionIndex + } + accumulatedGas = newAccumulatedGas + if execResSizeLimitChecker.IsMaxExecResSizeReached(1) { log.Debug("ExecutionResultInclusionEstimator: estimated max size reached", "currentIndex", pendingExecutionIndex) diff --git a/process/estimator/executionResultInclusionEstimator_test.go b/process/estimator/executionResultInclusionEstimator_test.go index eeb049f6edb..a0050835545 100644 --- a/process/estimator/executionResultInclusionEstimator_test.go +++ b/process/estimator/executionResultInclusionEstimator_test.go @@ -47,7 +47,7 @@ func TestEstimatorCreation(t *testing.T) { var erie *estimator.ExecutionResultInclusionEstimator cfg := config.ExecutionResultInclusionEstimatorConfig{MaxResultsPerBlock: 10} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, nil, newExecResultSizeComputationHandler()) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, nil, newExecResultSizeComputationHandler(), 0) require.Equal(t, process.ErrNilRoundHandler, err) require.True(t, erie.IsInterfaceNil(), "IsInterfaceNil() should return true if RoundHandler is nil") }) @@ -55,7 +55,7 @@ func TestEstimatorCreation(t *testing.T) { t.Run("Default config", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 0, MaxResultsPerBlock: 1} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) require.Nil(t, err) require.NotNil(t, erie, "NewExecutionResultInclusionEstimator should not return nil") }) @@ -63,7 +63,7 @@ func TestEstimatorCreation(t *testing.T) { t.Run("Custom config", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 120, MaxResultsPerBlock: 10} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) require.Nil(t, err) require.NotNil(t, erie, "NewExecutionResultInclusionEstimator should not return nil") }) @@ -83,13 +83,13 @@ func TestDecide(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - defaultErie, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, newExecResultSizeComputationHandler()) + defaultErie, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, newExecResultSizeComputationHandler(), 0) roundNow := uint64(3) t.Run("Empty pending", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -122,7 +122,7 @@ func TestDecide(t *testing.T) { t.Run("Reject second item", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -142,7 +142,7 @@ func TestDecide(t *testing.T) { t.Run("Allow only up to boundary (t_done == t_now)", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -161,7 +161,7 @@ func TestDecide(t *testing.T) { t.Run("Hit MaxResultsPerBlock cap", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 1} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -177,6 +177,27 @@ func TestDecide(t *testing.T) { require.Equal(t, wantAllowed, got, fmt.Sprintf("Decide() = %d, want %d", got, wantAllowed)) }) + t.Run("hit max block gas capacity", func(t *testing.T) { + t.Parallel() + + cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} + maxBlockGasCapacity := uint64(150) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), maxBlockGasCapacity) + lastNotarised := &common.LastExecutionResultForInclusion{ + NotarizedInRound: 1, + ProposedInRound: 0, + } + // cumulative gas after the second item (200) exceeds the cap (150), so only the first is allowed + pending := []data.BaseExecutionResultHandler{ + &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 100}}, + &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 100}}, + } + wantAllowed := 1 + + got := erie.Decide(lastNotarised, pending, roundNow) + require.Equal(t, wantAllowed, got, fmt.Sprintf("Decide() = %d, want %d", got, wantAllowed)) + }) + t.Run("Genesis fallback", func(t *testing.T) { t.Parallel() @@ -187,7 +208,7 @@ func TestDecide(t *testing.T) { }, } cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) var lastNotarised *common.LastExecutionResultForInclusion = nil pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 100}}, // after genesis @@ -202,7 +223,7 @@ func TestDecide(t *testing.T) { t.Run("Overflow protection", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -234,7 +255,7 @@ func TestOverflowProtection(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 1000}}, @@ -255,7 +276,7 @@ func TestOverflowProtection(t *testing.T) { MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) const nominalSafetyMargin = 100 safetyMargin := cfg.SafetyMargin - nominalSafetyMargin // 10 @@ -282,7 +303,7 @@ func TestOverflowProtection(t *testing.T) { NotarizedInRound: uint64(math.MaxUint64 - 3), ProposedInRound: 0, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: uint64(math.MaxUint64-110) / 1_000_000, GasUsed: 509000000}}, // This will bring estimatedTime close to max in margin calculation &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 1}}, @@ -308,7 +329,7 @@ func TestDecide_EdgeCases(t *testing.T) { SafetyMargin: 10, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) roundNow := uint64(3) t.Run("zero GasUsed", func(t *testing.T) { @@ -326,7 +347,7 @@ func TestDecide_EdgeCases(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 0, GasUsed: 100}}, } @@ -338,7 +359,7 @@ func TestDecide_EdgeCases(t *testing.T) { t.Run("HeaderRound before last notarised", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 3, ProposedInRound: 2, @@ -415,12 +436,12 @@ func TestDecide_RoundStartAlignment(t *testing.T) { } roundNow := uint64(5) cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, } - //second execution result finishes in round 4, allignment will take its finish time as base. third small enough to fit so all accepted + // second execution result finishes in round 4, allignment will take its finish time as base. third small enough to fit so all accepted pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 50000000}}, &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 3, HeaderRound: 3, GasUsed: 120000000}}, @@ -441,7 +462,7 @@ func TestDecide_RoundStartAlignment(t *testing.T) { } roundNow := uint64(5) cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -471,7 +492,7 @@ func TestSafetyMargin(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{ @@ -492,7 +513,7 @@ func TestSafetyMargin(t *testing.T) { SafetyMargin: 110, // delta = 10 MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) gasUsed := uint64(100_000_000 * 100 / 110) // such that with margin it fits exactly 100ms pending := []data.BaseExecutionResultHandler{ @@ -517,7 +538,7 @@ func BenchmarkDecideScaling_10(b *testing.B) { return round * 1000 }, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) last := &common.LastExecutionResultForInclusion{ NotarizedInRound: 0, ProposedInRound: 0, From 87c677cdeb83cca29d7c74c8eb4e394c82edadf6 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Wed, 17 Jun 2026 18:42:08 +0300 Subject: [PATCH 09/12] TODO: this account adapter may be required to be changed as the roothash should be the last execution result roothash --- factory/state/stateComponents.go | 1 - process/block/baseProcess.go | 13 ++++++++++++- process/block/baseProcess_test.go | 9 +++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/factory/state/stateComponents.go b/factory/state/stateComponents.go index 0a2e4f278df..0a0af5e47b8 100644 --- a/factory/state/stateComponents.go +++ b/factory/state/stateComponents.go @@ -316,7 +316,6 @@ func (scf *stateComponentsFactory) createAccountsAdapters(triesContainer common. return nil, fmt.Errorf("accountsRepository: %w", err) } - // TODO: this account adapter may be required to be changed as the roothash should be the last execution result roothash accountsAdapterProposal, err := state.NewAccountsDB(argsAPIAccountsDB) if err != nil { return nil, fmt.Errorf("accounts adapter for proposal: %w: %s", errors.ErrAccountsAdapterCreation, err) diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index e2b53abe93c..e8007b94ade 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -3070,7 +3070,18 @@ func (bp *baseProcessor) OnExecutedBlock(header data.HeaderHandler, rootHash []b } func (bp *baseProcessor) recreateTrieIfNeeded() error { - rootHash := bp.blockChain.GetCurrentBlockRootHash() + prevHeader := bp.blockChain.GetCurrentBlockHeader() + prevHeaderHash := bp.blockChain.GetCurrentBlockHeaderHash() + + var rootHash []byte + if !check.IfNil(prevHeader) && len(prevHeaderHash) > 0 { + lastExecResHandler, err := common.GetOrCreateLastExecutionResultForPrevHeader(prevHeader, prevHeaderHash) + if err != nil { + return err + } + rootHash = lastExecResHandler.GetRootHash() + } + if len(rootHash) == 0 { genesisBlock := bp.blockChain.GetGenesisHeader() rootHash = genesisBlock.GetRootHash() diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index d47925b57b3..0c06187e030 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -4989,8 +4989,13 @@ func TestBaseProcessor_RecreateTrieIfNeeded(t *testing.T) { coreComponents, dataComponents, bootstrapComponents, statusComponents := createComponentHolderMocks() dataComponents.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockRootHashCalled: func() []byte { - return []byte("rootHash") + GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + return &block.Header{ + RootHash: []byte("rootHash"), + } + }, + GetCurrentBlockHeaderHashCalled: func() []byte { + return []byte("headerHash") }, } arguments := CreateMockArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) From 7b41e2433850ae93761a1b14ac32f931202585d3 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 26 Jun 2026 16:43:57 +0300 Subject: [PATCH 10/12] fixes after review --- epochStart/metachain/epochStartData.go | 5 +- factory/processing/blockProcessorCreator.go | 10 +-- integrationTests/testFullNode.go | 4 +- integrationTests/testProcessorNode.go | 2 +- integrationTests/testSyncNode.go | 2 +- .../vm/staking/metaBlockProcessorCreator.go | 2 +- process/block/baseProcess.go | 13 +--- process/block/baseProcess_test.go | 11 +-- process/block/export_test.go | 2 +- process/block/metablock_test.go | 2 +- process/block/shardblockProposal_test.go | 12 +++- .../executionResultInclusionEstimator.go | 27 ++++--- .../executionResultInclusionEstimator_test.go | 70 ++++++++++++------- 13 files changed, 84 insertions(+), 78 deletions(-) diff --git a/epochStart/metachain/epochStartData.go b/epochStart/metachain/epochStartData.go index 2004f225495..76ffd180b73 100644 --- a/epochStart/metachain/epochStartData.go +++ b/epochStart/metachain/epochStartData.go @@ -418,7 +418,10 @@ func (e *epochStartData) computePendingMiniBlockList( epochStartIdentifier := core.EpochStartIdentifier(prevEpoch) - previousEpochStartMeta, _ := process.GetMetaHeaderFromStorage([]byte(epochStartIdentifier), e.marshalizer, e.store) + previousEpochStartMeta, err := process.GetMetaHeaderFromStorage([]byte(epochStartIdentifier), e.marshalizer, e.store) + if err != nil { + log.Debug("computePendingMiniBlockList.GetMetaHeaderFromStorage failed", "err", err) + } allPending := make([]block.MiniBlockHeader, 0) for shId, shardData := range startData.LastFinalizedHeaders { diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 882c0d0856a..6cce34c907e 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -606,14 +606,11 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( return nil, err } - maxBlockGasCapacity := pcf.coreData.EconomicsData().MaxGasLimitPerBlock(pcf.bootstrapComponents.ShardCoordinator().SelfId()) - overestimationFactor := pcf.coreData.EconomicsData().BlockCapacityOverestimationFactor() - maxBlockGasCapacity = maxBlockGasCapacity * overestimationFactor / 100 inclusionEstimator, err := estimator.NewExecutionResultInclusionEstimator( pcf.config.ExecutionResultInclusionEstimator, pcf.coreData.RoundHandler(), execResSizeComputationHandler, - maxBlockGasCapacity, + pcf.coreData.EconomicsData(), ) if err != nil { return nil, err @@ -1195,14 +1192,11 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( return nil, err } - maxBlockGasCapacity := pcf.coreData.EconomicsData().MaxGasLimitPerBlock(pcf.bootstrapComponents.ShardCoordinator().SelfId()) - overestimationFactor := pcf.coreData.EconomicsData().BlockCapacityOverestimationFactor() - maxBlockGasCapacity = maxBlockGasCapacity * overestimationFactor / 100 inclusionEstimator, err := estimator.NewExecutionResultInclusionEstimator( pcf.config.ExecutionResultInclusionEstimator, pcf.coreData.RoundHandler(), execResSizeComputationHandler, - maxBlockGasCapacity, + pcf.coreData.EconomicsData(), ) if err != nil { return nil, err diff --git a/integrationTests/testFullNode.go b/integrationTests/testFullNode.go index 853de6e39f2..53043dccaae 100644 --- a/integrationTests/testFullNode.go +++ b/integrationTests/testFullNode.go @@ -995,7 +995,7 @@ func (tpn *TestFullNode) initBlockProcessor( }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - 0, + tpn.EconomicsData, ) if err != nil { log.LogIfError(err) @@ -1383,7 +1383,7 @@ func (tpn *TestFullNode) initBlockProcessorWithSync( }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - 0, + tpn.EconomicsData, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 8199e779ebb..6d55670609b 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2596,7 +2596,7 @@ func (tpn *TestProcessorNode) initBlockProcessor() { }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - 0, + tpn.EconomicsData, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index df2bf98c6b2..a01e7075375 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -162,7 +162,7 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - 0, + tpn.EconomicsData, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 2ad31cb3260..601cd9dfe49 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -137,7 +137,7 @@ func createMetaBlockProcessor( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - 0, + coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 5f530b6f059..993c6bde9f5 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -3087,18 +3087,7 @@ func (bp *baseProcessor) OnExecutedBlock(header data.HeaderHandler, rootHash []b } func (bp *baseProcessor) recreateTrieIfNeeded() error { - prevHeader := bp.blockChain.GetCurrentBlockHeader() - prevHeaderHash := bp.blockChain.GetCurrentBlockHeaderHash() - - var rootHash []byte - if !check.IfNil(prevHeader) && len(prevHeaderHash) > 0 { - lastExecResHandler, err := common.GetOrCreateLastExecutionResultForPrevHeader(prevHeader, prevHeaderHash) - if err != nil { - return err - } - rootHash = lastExecResHandler.GetRootHash() - } - + rootHash := bp.blockChain.GetCurrentBlockRootHash() if len(rootHash) == 0 { genesisBlock := bp.blockChain.GetGenesisHeader() rootHash = genesisBlock.GetRootHash() diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 92f0ea9924e..2316f6c8623 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -194,7 +194,7 @@ func createArgBaseProcessor( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - 0, + coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ @@ -5176,13 +5176,8 @@ func TestBaseProcessor_RecreateTrieIfNeeded(t *testing.T) { coreComponents, dataComponents, bootstrapComponents, statusComponents := createComponentHolderMocks() dataComponents.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{ - RootHash: []byte("rootHash"), - } - }, - GetCurrentBlockHeaderHashCalled: func() []byte { - return []byte("headerHash") + GetCurrentBlockRootHashCalled: func() []byte { + return []byte("rootHash") }, } arguments := CreateMockArguments(coreComponents, dataComponents, bootstrapComponents, statusComponents) diff --git a/process/block/export_test.go b/process/block/export_test.go index b064f7ce662..64bc36414ea 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -250,7 +250,7 @@ func NewShardProcessorEmptyWith3shards( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - 0, + coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index c6db3ddad2d..a700efda1b0 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -193,7 +193,7 @@ func createMockMetaArguments( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - 0, + coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/shardblockProposal_test.go b/process/block/shardblockProposal_test.go index 82e0668b2df..c0a189d8efa 100644 --- a/process/block/shardblockProposal_test.go +++ b/process/block/shardblockProposal_test.go @@ -1413,8 +1413,16 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } + economics := &economicsmocks.EconomicsHandlerMock{ + BlockCapacityOverestimationFactorCalled: func() uint64 { + return 100 + }, + MaxGasLimitPerBlockCalled: func(shardID uint32) uint64 { + return 600_000_000 + }, + } - executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, 0) + executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, economics) executionResult1 := &block.ExecutionResult{ BaseExecutionResult: &block.BaseExecutionResult{HeaderHash: []byte("hash1"), HeaderNonce: 1, HeaderRound: 2, GasUsed: 100_000_000}, @@ -1500,7 +1508,7 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { }, } - execResEst, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, 0) + execResEst, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, &economicsmocks.EconomicsHandlerMock{}) sp, _ := blproc.ConstructPartialShardBlockProcessorForTest(map[string]interface{}{ "executionManager": &processMocks.ExecutionManagerMock{ diff --git a/process/estimator/executionResultInclusionEstimator.go b/process/estimator/executionResultInclusionEstimator.go index 0f4e3f17075..de77c986f3d 100644 --- a/process/estimator/executionResultInclusionEstimator.go +++ b/process/estimator/executionResultInclusionEstimator.go @@ -34,7 +34,7 @@ type ExecutionResultInclusionEstimator struct { cfg config.ExecutionResultInclusionEstimatorConfig // immutable after construction tGas uint64 // time per gas unit on minimum‑spec hardware - 1 ns per gas unit roundHandler RoundHandler - maxBlockGasCapacity uint64 // max cumulative gas of the included execution results (0 = uncapped) + economics process.EconomicsDataHandler execResSizeComputation ExecResSizeComputationHandler } @@ -43,7 +43,7 @@ func NewExecutionResultInclusionEstimator( cfg config.ExecutionResultInclusionEstimatorConfig, roundHandler RoundHandler, execResultComputationHandler ExecResSizeComputationHandler, - maxBlockGasCapacity uint64, + economics process.EconomicsDataHandler, ) (*ExecutionResultInclusionEstimator, error) { err := checkConfig(cfg) if err != nil { @@ -52,12 +52,15 @@ func NewExecutionResultInclusionEstimator( if check.IfNil(roundHandler) { return nil, process.ErrNilRoundHandler } + if check.IfNil(economics) { + return nil, process.ErrNilEconomicsData + } return &ExecutionResultInclusionEstimator{ cfg: cfg, tGas: tGas, roundHandler: roundHandler, - maxBlockGasCapacity: maxBlockGasCapacity, + economics: economics, execResSizeComputation: execResultComputationHandler, }, nil } @@ -108,7 +111,6 @@ func (erie *ExecutionResultInclusionEstimator) Decide( // accumulated execution tBase for each pending execution result in ns (1 gas = 1ns) estimatedTBase := tBase - var accumulatedGas uint64 for pendingExecutionIndex, executionResultMeta := range pending { if pendingExecutionIndex > 0 { previousExecutionResultMeta = pending[pendingExecutionIndex-1] @@ -167,21 +169,16 @@ func (erie *ExecutionResultInclusionEstimator) Decide( return pendingExecutionIndex } - newAccumulatedGas, overflow := bits.Add64(accumulatedGas, executionResultMeta.GetGasUsed(), 0) - if overflow != 0 { - log.Debug("ExecutionResultInclusionEstimator: overflow detected in accumulated gas", - "accumulatedGas", accumulatedGas, - "gasUsed", executionResultMeta.GetGasUsed()) - return pendingExecutionIndex - } - if erie.maxBlockGasCapacity > 0 && newAccumulatedGas > erie.maxBlockGasCapacity { + maxBlockGasCapacity := erie.economics.MaxGasLimitPerBlock(common.MetachainShardId) + overestimationFactor := erie.economics.BlockCapacityOverestimationFactor() + maxBlockGasCapacity = maxBlockGasCapacity * overestimationFactor / 100 + if executionResultMeta.GetGasUsed() > maxBlockGasCapacity { log.Debug("ExecutionResultInclusionEstimator: max block gas capacity reached", - "accumulatedGas", newAccumulatedGas, - "maxBlockGasCapacity", erie.maxBlockGasCapacity, + "gasUsed", executionResultMeta.GetGasUsed(), + "maxBlockGasCapacity", maxBlockGasCapacity, "currentIndex", pendingExecutionIndex) return pendingExecutionIndex } - accumulatedGas = newAccumulatedGas if execResSizeLimitChecker.IsMaxExecResSizeReached(1) { log.Debug("ExecutionResultInclusionEstimator: estimated max size reached", diff --git a/process/estimator/executionResultInclusionEstimator_test.go b/process/estimator/executionResultInclusionEstimator_test.go index a0050835545..4652cb9807c 100644 --- a/process/estimator/executionResultInclusionEstimator_test.go +++ b/process/estimator/executionResultInclusionEstimator_test.go @@ -7,6 +7,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" "github.com/stretchr/testify/require" @@ -23,6 +24,17 @@ func newExecResultSizeComputationHandler() estimator.ExecResSizeComputationHandl return execResSizeComputationHandler } +func getDefaultEconomics() process.EconomicsDataHandler { + return &economicsmocks.EconomicsHandlerMock{ + BlockCapacityOverestimationFactorCalled: func() uint64 { + return 100 + }, + MaxGasLimitPerBlockCalled: func(shardID uint32) uint64 { + return 600_000_000 + }, + } +} + func TestEstimatorCreation(t *testing.T) { t.Parallel() genesisTimeStampMs := uint64(1000) @@ -47,7 +59,7 @@ func TestEstimatorCreation(t *testing.T) { var erie *estimator.ExecutionResultInclusionEstimator cfg := config.ExecutionResultInclusionEstimatorConfig{MaxResultsPerBlock: 10} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, nil, newExecResultSizeComputationHandler(), 0) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, nil, newExecResultSizeComputationHandler(), getDefaultEconomics()) require.Equal(t, process.ErrNilRoundHandler, err) require.True(t, erie.IsInterfaceNil(), "IsInterfaceNil() should return true if RoundHandler is nil") }) @@ -55,7 +67,7 @@ func TestEstimatorCreation(t *testing.T) { t.Run("Default config", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 0, MaxResultsPerBlock: 1} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) require.Nil(t, err) require.NotNil(t, erie, "NewExecutionResultInclusionEstimator should not return nil") }) @@ -63,7 +75,7 @@ func TestEstimatorCreation(t *testing.T) { t.Run("Custom config", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 120, MaxResultsPerBlock: 10} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) require.Nil(t, err) require.NotNil(t, erie, "NewExecutionResultInclusionEstimator should not return nil") }) @@ -83,13 +95,13 @@ func TestDecide(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - defaultErie, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, newExecResultSizeComputationHandler(), 0) + defaultErie, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) roundNow := uint64(3) t.Run("Empty pending", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -122,7 +134,7 @@ func TestDecide(t *testing.T) { t.Run("Reject second item", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -142,7 +154,7 @@ func TestDecide(t *testing.T) { t.Run("Allow only up to boundary (t_done == t_now)", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -161,7 +173,7 @@ func TestDecide(t *testing.T) { t.Run("Hit MaxResultsPerBlock cap", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 1} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -181,16 +193,24 @@ func TestDecide(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - maxBlockGasCapacity := uint64(150) - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), maxBlockGasCapacity) + maxBlockGasCapacity := uint64(100) + economics := &economicsmocks.EconomicsHandlerMock{ + MaxGasLimitPerBlockCalled: func(shardID uint32) uint64 { + return maxBlockGasCapacity + }, + BlockCapacityOverestimationFactorCalled: func() uint64 { + return 100 + }, + } + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), economics) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, } - // cumulative gas after the second item (200) exceeds the cap (150), so only the first is allowed + // max gas limit per block 100, so only the first is allowed pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 100}}, - &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 100}}, + &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 200}}, } wantAllowed := 1 @@ -208,7 +228,7 @@ func TestDecide(t *testing.T) { }, } cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) var lastNotarised *common.LastExecutionResultForInclusion = nil pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 100}}, // after genesis @@ -223,7 +243,7 @@ func TestDecide(t *testing.T) { t.Run("Overflow protection", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -255,7 +275,7 @@ func TestOverflowProtection(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 1000}}, @@ -276,7 +296,7 @@ func TestOverflowProtection(t *testing.T) { MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) const nominalSafetyMargin = 100 safetyMargin := cfg.SafetyMargin - nominalSafetyMargin // 10 @@ -303,7 +323,7 @@ func TestOverflowProtection(t *testing.T) { NotarizedInRound: uint64(math.MaxUint64 - 3), ProposedInRound: 0, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: uint64(math.MaxUint64-110) / 1_000_000, GasUsed: 509000000}}, // This will bring estimatedTime close to max in margin calculation &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 1}}, @@ -329,7 +349,7 @@ func TestDecide_EdgeCases(t *testing.T) { SafetyMargin: 10, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) roundNow := uint64(3) t.Run("zero GasUsed", func(t *testing.T) { @@ -347,7 +367,7 @@ func TestDecide_EdgeCases(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 0, GasUsed: 100}}, } @@ -359,7 +379,7 @@ func TestDecide_EdgeCases(t *testing.T) { t.Run("HeaderRound before last notarised", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 3, ProposedInRound: 2, @@ -436,7 +456,7 @@ func TestDecide_RoundStartAlignment(t *testing.T) { } roundNow := uint64(5) cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -462,7 +482,7 @@ func TestDecide_RoundStartAlignment(t *testing.T) { } roundNow := uint64(5) cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -492,7 +512,7 @@ func TestSafetyMargin(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{ @@ -513,7 +533,7 @@ func TestSafetyMargin(t *testing.T) { SafetyMargin: 110, // delta = 10 MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) gasUsed := uint64(100_000_000 * 100 / 110) // such that with margin it fits exactly 100ms pending := []data.BaseExecutionResultHandler{ @@ -538,7 +558,7 @@ func BenchmarkDecideScaling_10(b *testing.B) { return round * 1000 }, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), 0) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) last := &common.LastExecutionResultForInclusion{ NotarizedInRound: 0, ProposedInRound: 0, From c6c63bdd9b42510da8fbea63e826b179e494ec07 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 26 Jun 2026 17:28:09 +0300 Subject: [PATCH 11/12] removed inclusion estimator todo changes --- factory/processing/blockProcessorCreator.go | 2 - integrationTests/testFullNode.go | 2 - integrationTests/testProcessorNode.go | 1 - integrationTests/testSyncNode.go | 1 - .../vm/staking/metaBlockProcessorCreator.go | 1 - process/block/baseProcess_test.go | 1 - process/block/export_test.go | 1 - process/block/metablock_test.go | 1 - process/block/shardblockProposal_test.go | 4 +- .../executionResultInclusionEstimator.go | 24 +----- .../executionResultInclusionEstimator_test.go | 84 +++++-------------- 11 files changed, 27 insertions(+), 95 deletions(-) diff --git a/factory/processing/blockProcessorCreator.go b/factory/processing/blockProcessorCreator.go index 6cce34c907e..0a242f685af 100644 --- a/factory/processing/blockProcessorCreator.go +++ b/factory/processing/blockProcessorCreator.go @@ -610,7 +610,6 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( pcf.config.ExecutionResultInclusionEstimator, pcf.coreData.RoundHandler(), execResSizeComputationHandler, - pcf.coreData.EconomicsData(), ) if err != nil { return nil, err @@ -1196,7 +1195,6 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( pcf.config.ExecutionResultInclusionEstimator, pcf.coreData.RoundHandler(), execResSizeComputationHandler, - pcf.coreData.EconomicsData(), ) if err != nil { return nil, err diff --git a/integrationTests/testFullNode.go b/integrationTests/testFullNode.go index 53043dccaae..245ed627b2e 100644 --- a/integrationTests/testFullNode.go +++ b/integrationTests/testFullNode.go @@ -995,7 +995,6 @@ func (tpn *TestFullNode) initBlockProcessor( }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - tpn.EconomicsData, ) if err != nil { log.LogIfError(err) @@ -1383,7 +1382,6 @@ func (tpn *TestFullNode) initBlockProcessorWithSync( }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - tpn.EconomicsData, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 6d55670609b..ddbf5d98e22 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -2596,7 +2596,6 @@ func (tpn *TestProcessorNode) initBlockProcessor() { }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - tpn.EconomicsData, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/testSyncNode.go b/integrationTests/testSyncNode.go index a01e7075375..6c1980782bd 100644 --- a/integrationTests/testSyncNode.go +++ b/integrationTests/testSyncNode.go @@ -162,7 +162,6 @@ func (tpn *TestProcessorNode) initBlockProcessorWithSync() { }, tpn.RoundHandler, &testscommon.ExecResSizeComputationStub{}, - tpn.EconomicsData, ) if err != nil { log.LogIfError(err) diff --git a/integrationTests/vm/staking/metaBlockProcessorCreator.go b/integrationTests/vm/staking/metaBlockProcessorCreator.go index 601cd9dfe49..487bd934305 100644 --- a/integrationTests/vm/staking/metaBlockProcessorCreator.go +++ b/integrationTests/vm/staking/metaBlockProcessorCreator.go @@ -137,7 +137,6 @@ func createMetaBlockProcessor( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 2316f6c8623..6de919c3d92 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -194,7 +194,6 @@ func createArgBaseProcessor( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/export_test.go b/process/block/export_test.go index 64bc36414ea..92f5779a79e 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -250,7 +250,6 @@ func NewShardProcessorEmptyWith3shards( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index a700efda1b0..9dfd9bc05ce 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -193,7 +193,6 @@ func createMockMetaArguments( }, coreComponents.RoundHandler(), &testscommon.ExecResSizeComputationStub{}, - coreComponents.EconomicsData(), ) missingDataArgs := missingData.ResolverArgs{ diff --git a/process/block/shardblockProposal_test.go b/process/block/shardblockProposal_test.go index c0a189d8efa..9eaf9d357f2 100644 --- a/process/block/shardblockProposal_test.go +++ b/process/block/shardblockProposal_test.go @@ -1422,7 +1422,7 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { }, } - executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, economics) + executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}) executionResult1 := &block.ExecutionResult{ BaseExecutionResult: &block.BaseExecutionResult{HeaderHash: []byte("hash1"), HeaderNonce: 1, HeaderRound: 2, GasUsed: 100_000_000}, @@ -1508,7 +1508,7 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { }, } - execResEst, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}, &economicsmocks.EconomicsHandlerMock{}) + execResEst, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{}) sp, _ := blproc.ConstructPartialShardBlockProcessorForTest(map[string]interface{}{ "executionManager": &processMocks.ExecutionManagerMock{ diff --git a/process/estimator/executionResultInclusionEstimator.go b/process/estimator/executionResultInclusionEstimator.go index de77c986f3d..33f0e1e625e 100644 --- a/process/estimator/executionResultInclusionEstimator.go +++ b/process/estimator/executionResultInclusionEstimator.go @@ -31,10 +31,10 @@ type RoundHandler interface { // node. It determines, at proposal‑time and at validation‑time, whether one or more pending execution results can be // safely embedded in the block that is being produced / verified. type ExecutionResultInclusionEstimator struct { - cfg config.ExecutionResultInclusionEstimatorConfig // immutable after construction - tGas uint64 // time per gas unit on minimum‑spec hardware - 1 ns per gas unit - roundHandler RoundHandler - economics process.EconomicsDataHandler + cfg config.ExecutionResultInclusionEstimatorConfig // immutable after construction + tGas uint64 // time per gas unit on minimum‑spec hardware - 1 ns per gas unit + roundHandler RoundHandler + // TODO add also max estimated block gas capacity - used gas must be lower than this execResSizeComputation ExecResSizeComputationHandler } @@ -43,7 +43,6 @@ func NewExecutionResultInclusionEstimator( cfg config.ExecutionResultInclusionEstimatorConfig, roundHandler RoundHandler, execResultComputationHandler ExecResSizeComputationHandler, - economics process.EconomicsDataHandler, ) (*ExecutionResultInclusionEstimator, error) { err := checkConfig(cfg) if err != nil { @@ -52,15 +51,11 @@ func NewExecutionResultInclusionEstimator( if check.IfNil(roundHandler) { return nil, process.ErrNilRoundHandler } - if check.IfNil(economics) { - return nil, process.ErrNilEconomicsData - } return &ExecutionResultInclusionEstimator{ cfg: cfg, tGas: tGas, roundHandler: roundHandler, - economics: economics, execResSizeComputation: execResultComputationHandler, }, nil } @@ -169,17 +164,6 @@ func (erie *ExecutionResultInclusionEstimator) Decide( return pendingExecutionIndex } - maxBlockGasCapacity := erie.economics.MaxGasLimitPerBlock(common.MetachainShardId) - overestimationFactor := erie.economics.BlockCapacityOverestimationFactor() - maxBlockGasCapacity = maxBlockGasCapacity * overestimationFactor / 100 - if executionResultMeta.GetGasUsed() > maxBlockGasCapacity { - log.Debug("ExecutionResultInclusionEstimator: max block gas capacity reached", - "gasUsed", executionResultMeta.GetGasUsed(), - "maxBlockGasCapacity", maxBlockGasCapacity, - "currentIndex", pendingExecutionIndex) - return pendingExecutionIndex - } - if execResSizeLimitChecker.IsMaxExecResSizeReached(1) { log.Debug("ExecutionResultInclusionEstimator: estimated max size reached", "currentIndex", pendingExecutionIndex) diff --git a/process/estimator/executionResultInclusionEstimator_test.go b/process/estimator/executionResultInclusionEstimator_test.go index 4652cb9807c..93a9d3d6f64 100644 --- a/process/estimator/executionResultInclusionEstimator_test.go +++ b/process/estimator/executionResultInclusionEstimator_test.go @@ -7,8 +7,6 @@ import ( "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" - "github.com/multiversx/mx-chain-go/testscommon/economicsmocks" - "github.com/stretchr/testify/require" "github.com/multiversx/mx-chain-go/common" @@ -24,17 +22,6 @@ func newExecResultSizeComputationHandler() estimator.ExecResSizeComputationHandl return execResSizeComputationHandler } -func getDefaultEconomics() process.EconomicsDataHandler { - return &economicsmocks.EconomicsHandlerMock{ - BlockCapacityOverestimationFactorCalled: func() uint64 { - return 100 - }, - MaxGasLimitPerBlockCalled: func(shardID uint32) uint64 { - return 600_000_000 - }, - } -} - func TestEstimatorCreation(t *testing.T) { t.Parallel() genesisTimeStampMs := uint64(1000) @@ -59,7 +46,7 @@ func TestEstimatorCreation(t *testing.T) { var erie *estimator.ExecutionResultInclusionEstimator cfg := config.ExecutionResultInclusionEstimatorConfig{MaxResultsPerBlock: 10} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, nil, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, nil, newExecResultSizeComputationHandler()) require.Equal(t, process.ErrNilRoundHandler, err) require.True(t, erie.IsInterfaceNil(), "IsInterfaceNil() should return true if RoundHandler is nil") }) @@ -67,7 +54,7 @@ func TestEstimatorCreation(t *testing.T) { t.Run("Default config", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 0, MaxResultsPerBlock: 1} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) require.Nil(t, err) require.NotNil(t, erie, "NewExecutionResultInclusionEstimator should not return nil") }) @@ -75,7 +62,7 @@ func TestEstimatorCreation(t *testing.T) { t.Run("Custom config", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 120, MaxResultsPerBlock: 10} - erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, err := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) require.Nil(t, err) require.NotNil(t, erie, "NewExecutionResultInclusionEstimator should not return nil") }) @@ -95,13 +82,13 @@ func TestDecide(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - defaultErie, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + defaultErie, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, newExecResultSizeComputationHandler()) roundNow := uint64(3) t.Run("Empty pending", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -134,7 +121,7 @@ func TestDecide(t *testing.T) { t.Run("Reject second item", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -154,7 +141,7 @@ func TestDecide(t *testing.T) { t.Run("Allow only up to boundary (t_done == t_now)", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -173,7 +160,7 @@ func TestDecide(t *testing.T) { t.Run("Hit MaxResultsPerBlock cap", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 1} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -189,35 +176,6 @@ func TestDecide(t *testing.T) { require.Equal(t, wantAllowed, got, fmt.Sprintf("Decide() = %d, want %d", got, wantAllowed)) }) - t.Run("hit max block gas capacity", func(t *testing.T) { - t.Parallel() - - cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - maxBlockGasCapacity := uint64(100) - economics := &economicsmocks.EconomicsHandlerMock{ - MaxGasLimitPerBlockCalled: func(shardID uint32) uint64 { - return maxBlockGasCapacity - }, - BlockCapacityOverestimationFactorCalled: func() uint64 { - return 100 - }, - } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), economics) - lastNotarised := &common.LastExecutionResultForInclusion{ - NotarizedInRound: 1, - ProposedInRound: 0, - } - // max gas limit per block 100, so only the first is allowed - pending := []data.BaseExecutionResultHandler{ - &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 100}}, - &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 200}}, - } - wantAllowed := 1 - - got := erie.Decide(lastNotarised, pending, roundNow) - require.Equal(t, wantAllowed, got, fmt.Sprintf("Decide() = %d, want %d", got, wantAllowed)) - }) - t.Run("Genesis fallback", func(t *testing.T) { t.Parallel() @@ -228,7 +186,7 @@ func TestDecide(t *testing.T) { }, } cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) var lastNotarised *common.LastExecutionResultForInclusion = nil pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 100}}, // after genesis @@ -243,7 +201,7 @@ func TestDecide(t *testing.T) { t.Run("Overflow protection", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -275,7 +233,7 @@ func TestOverflowProtection(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 1, GasUsed: 1000}}, @@ -296,7 +254,7 @@ func TestOverflowProtection(t *testing.T) { MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) const nominalSafetyMargin = 100 safetyMargin := cfg.SafetyMargin - nominalSafetyMargin // 10 @@ -323,7 +281,7 @@ func TestOverflowProtection(t *testing.T) { NotarizedInRound: uint64(math.MaxUint64 - 3), ProposedInRound: 0, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: uint64(math.MaxUint64-110) / 1_000_000, GasUsed: 509000000}}, // This will bring estimatedTime close to max in margin calculation &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 2, HeaderRound: 2, GasUsed: 1}}, @@ -349,7 +307,7 @@ func TestDecide_EdgeCases(t *testing.T) { SafetyMargin: 10, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) roundNow := uint64(3) t.Run("zero GasUsed", func(t *testing.T) { @@ -367,7 +325,7 @@ func TestDecide_EdgeCases(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{BaseExecutionResult: &block.BaseExecutionResult{HeaderNonce: 1, HeaderRound: 0, GasUsed: 100}}, } @@ -379,7 +337,7 @@ func TestDecide_EdgeCases(t *testing.T) { t.Run("HeaderRound before last notarised", func(t *testing.T) { t.Parallel() cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 3, ProposedInRound: 2, @@ -456,7 +414,7 @@ func TestDecide_RoundStartAlignment(t *testing.T) { } roundNow := uint64(5) cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -482,7 +440,7 @@ func TestDecide_RoundStartAlignment(t *testing.T) { } roundNow := uint64(5) cfg := config.ExecutionResultInclusionEstimatorConfig{SafetyMargin: 110, MaxResultsPerBlock: 10} - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) lastNotarised := &common.LastExecutionResultForInclusion{ NotarizedInRound: 1, ProposedInRound: 0, @@ -512,7 +470,7 @@ func TestSafetyMargin(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) pending := []data.BaseExecutionResultHandler{ &block.ExecutionResult{ @@ -533,7 +491,7 @@ func TestSafetyMargin(t *testing.T) { SafetyMargin: 110, // delta = 10 MaxResultsPerBlock: 10, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) gasUsed := uint64(100_000_000 * 100 / 110) // such that with margin it fits exactly 100ms pending := []data.BaseExecutionResultHandler{ @@ -558,7 +516,7 @@ func BenchmarkDecideScaling_10(b *testing.B) { return round * 1000 }, } - erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler(), getDefaultEconomics()) + erie, _ := estimator.NewExecutionResultInclusionEstimator(cfg, roundHandler, newExecResultSizeComputationHandler()) last := &common.LastExecutionResultForInclusion{ NotarizedInRound: 0, ProposedInRound: 0, From ac79a535f23d49ac4c710cc68e4313d577ded203 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 26 Jun 2026 17:28:51 +0300 Subject: [PATCH 12/12] removed dead code --- process/block/shardblockProposal_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/process/block/shardblockProposal_test.go b/process/block/shardblockProposal_test.go index 9eaf9d357f2..da136c63048 100644 --- a/process/block/shardblockProposal_test.go +++ b/process/block/shardblockProposal_test.go @@ -1413,14 +1413,6 @@ func Test_addExecutionResultsOnHeader(t *testing.T) { SafetyMargin: 110, MaxResultsPerBlock: 10, } - economics := &economicsmocks.EconomicsHandlerMock{ - BlockCapacityOverestimationFactorCalled: func() uint64 { - return 100 - }, - MaxGasLimitPerBlockCalled: func(shardID uint32) uint64 { - return 600_000_000 - }, - } executionResultsInclusionEstimator, _ := estimator.NewExecutionResultInclusionEstimator(defaultCfg, roundHandler, &testscommon.ExecResSizeComputationStub{})