Skip to content

Chain handler last execution info#7356

Merged
AdoAdoAdo merged 19 commits into
feat/supernova-async-execfrom
chain-handler-last-execution-info
Nov 3, 2025
Merged

Chain handler last execution info#7356
AdoAdoAdo merged 19 commits into
feat/supernova-async-execfrom
chain-handler-last-execution-info

Conversation

@ssd04

@ssd04 ssd04 commented Oct 20, 2025

Copy link
Copy Markdown
Contributor

Reasoning behind the pull request

  • With the new execution model, we need to differentiate in chain handler current notarized block (from consensus flow) and last executed block (from async execution flow)
  • For this, a new set of fields have been added to chain handler in order to be able to fetch last executed block info

Proposed changes

  • Added last executed (on local executor) block info in chain handler
  • Adapt chain handler integrations to use rootHash based on last executed results

Testing procedure

  • With feature branch

Pre-requisites

Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:

  • was the PR targeted to the correct branch?
  • if this is a larger feature that probably needs more than one PR, is there a feat branch created?
  • if this is a feat branch merging, do all satellite projects have a proper tag inside go.mod?

@ssd04 ssd04 self-assigned this Oct 20, 2025
@codecov

codecov Bot commented Oct 20, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.59184% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.31%. Comparing base (857919f) to head (e053c0d).
⚠️ Report is 21 commits behind head on feat/supernova-async-exec.

Files with missing lines Patch % Lines
process/block/shardblockProposal.go 45.45% 3 Missing and 3 partials ⚠️
process/smartContract/scQueryService.go 33.33% 5 Missing and 1 partial ⚠️
...external/transactionAPI/apiTransactionProcessor.go 82.60% 2 Missing and 2 partials ⚠️
process/block/shardblock.go 0.00% 1 Missing and 1 partial ⚠️
state/blockInfoProviders/currentBlockInfo.go 71.42% 2 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##           feat/supernova-async-exec    #7356   +/-   ##
==========================================================
  Coverage                      77.31%   77.31%           
==========================================================
  Files                            867      867           
  Lines                         116789   116874   +85     
==========================================================
+ Hits                           90292    90364   +72     
- Misses                         20548    20555    +7     
- Partials                        5949     5955    +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ssd04 ssd04 marked this pull request as ready for review October 21, 2025 10:40
sstanculeanu
sstanculeanu previously approved these changes Oct 21, 2025
@raduchis raduchis self-requested a review October 28, 2025 10:03
Comment thread facade/nodeFacade.go
}

func (nf *nodeFacade) getCurrentRootHash() []byte {
currentHeader := nf.blockchain.GetCurrentBlockHeader()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could the currentHeader be nil?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added nil check

Comment thread process/asyncExecution/headersExecutor.go
Comment thread process/block/shardblock.go
return bh.blockChain.GetCurrentBlockRootHash()
}

_, _, lastExecutedRootHash := bh.blockChain.GetLastExecutedBlockInfo()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the currentHeader is nil this might return something slightly different than the apiTransactionsProcessor.go line 492 - getCurrentRootHash and nodeFacade.go line 638 - getCurrentRootHash.
Is there any way to "unify" the responses?

Comment thread facade/nodeFacade.go
}

func (nf *nodeFacade) getCurrentRootHash() []byte {
currentHeader := nf.blockchain.GetCurrentBlockHeader()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this method backwards compatible? Previously with or without nil currentHeader the nf.blockchain.GetCurrentBlockRootHash() was returned. Right now if the currentHeader is nil, it will return the nf.blockchain.GetLastExecutedBlockInfo().
It might not matter because it is on the nodeFacade...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe do this instead to keep it backwards compatible:

if currentHeader != nil && currentHeader.IsHeaderV3() {
    _, _, lastExecutedRootHash := nf.blockchain.GetLastExecutedBlockInfo()
	return lastExecutedRootHash
} 

return nf.blockchain.GetCurrentBlockRootHash()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

headerHash []byte,
scheduledHeaderRootHash []byte,
) {
if header.IsHeaderV3() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this different than Andromeda?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after supernova we set last execution info from headersExecutor

}

func (he *headersExecutor) process(pair queue.HeaderBodyPair) error {
executionResult, err := he.blockProcessor.ProcessBlockProposal(pair.Header, pair.Body)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use a check inside ProcessBlockProposal, that we start the execution from the correct roothash.

can you add this on shardblock with a todo to add it also for the metablock?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added root hash check

return nil, ErrNilBlockHeader
}

if blockHeader.IsHeaderV3() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when committing the first v3 header, do we create a lastExecutedBlockInfo from the previous V2 block?
otherwise we might have a gap here.

Comment thread testscommon/chainHandlerMock.go Outdated
finalBlockHash []byte
finalBlockRootHash []byte

lastNotarizedBlockNonce uint64

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it called lastNotarized?
should it be lastExecuted ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, renamed

Comment thread facade/nodeFacade.go
}

func (nf *nodeFacade) getCurrentRootHash() []byte {
currentHeader := nf.blockchain.GetCurrentBlockHeader()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe do this instead to keep it backwards compatible:

if currentHeader != nil && currentHeader.IsHeaderV3() {
    _, _, lastExecutedRootHash := nf.blockchain.GetLastExecutedBlockInfo()
	return lastExecutedRootHash
} 

return nf.blockchain.GetCurrentBlockRootHash()

AdoAdoAdo
AdoAdoAdo previously approved these changes Nov 1, 2025
AdoAdoAdo
AdoAdoAdo previously approved these changes Nov 1, 2025
@AdoAdoAdo AdoAdoAdo requested a review from Copilot November 1, 2025 12:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for tracking last executed block information separately from current block info, primarily to support HeaderV3 where block execution happens asynchronously. The changes introduce GetLastExecutedBlockInfo and SetLastExecutedBlockInfo methods across chain handlers and update various components to use last executed block info for state root hash retrieval when dealing with HeaderV3.

Key changes:

  • New methods GetLastExecutedBlockInfo() and SetLastExecutedBlockInfo() added to chain handler interfaces and implementations
  • State root hash retrieval logic updated to use last executed block info for HeaderV3
  • Headers executor now sets both final block info and last executed block info after processing
  • New validation check added before block execution to verify root hash consistency

Reviewed Changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
testscommon/chainHandlerStub.go Added stub methods for last executed block info
testscommon/chainHandlerMock.go Added mock implementation with fields for last executed block tracking
dataRetriever/blockchain/baseBlockchain.go Core implementation of last executed block info getters/setters
dataRetriever/blockchain/blockchain.go Initialized last executed block info in shard blockchain
dataRetriever/blockchain/metachain.go Initialized last executed block info in meta blockchain
process/asyncExecution/headersExecutor.go Sets both final and last executed block info after processing
state/blockInfoProviders/currentBlockInfo.go Uses last executed info for HeaderV3
process/smartContract/hooks/blockChainHook.go Retrieves root hash from last executed info for HeaderV3
process/smartContract/scQueryService.go Query service uses last executed header/root for HeaderV3
node/external/transactionAPI/apiTransactionProcessor.go API processor retrieves root hash from last executed info for HeaderV3
facade/nodeFacade.go Facade retrieves root hash from last executed info for HeaderV3
process/block/shardblock.go Skips setting final block info for HeaderV3 (handled in async executor)
process/block/shardblockProposal.go Adds root hash validation check before execution
go.mod Updated mx-chain-core-go dependency version

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread process/block/shardblockProposal.go Outdated
Comment on lines +397 to +403
lastCommitedRootHash, err := sp.accountsDB[state.UserAccountsState].RootHash()
if err != nil {
return err
}

currentRootHash := sp.blockChain.GetCurrentBlockRootHash()
if !bytes.Equal(lastCommitedRootHash, currentRootHash) {

Copilot AI Nov 1, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'lastCommitedRootHash' to 'lastCommittedRootHash'.

Suggested change
lastCommitedRootHash, err := sp.accountsDB[state.UserAccountsState].RootHash()
if err != nil {
return err
}
currentRootHash := sp.blockChain.GetCurrentBlockRootHash()
if !bytes.Equal(lastCommitedRootHash, currentRootHash) {
lastCommittedRootHash, err := sp.accountsDB[state.UserAccountsState].RootHash()
if err != nil {
return err
}
currentRootHash := sp.blockChain.GetCurrentBlockRootHash()
if !bytes.Equal(lastCommittedRootHash, currentRootHash) {

Copilot uses AI. Check for mistakes.
Comment thread facade/nodeFacade_test.go Outdated
}
arg.Node = &mock.NodeStub{
GetProofCalled: func(rootHash string, _ string) (*common.GetProofResponse, error) {
require.Equal(t, rootHash, rootHash)

Copilot AI Nov 1, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertion compares rootHash with itself, which always passes. This should likely compare the rootHash parameter against the expected value from line 1148.

Suggested change
require.Equal(t, rootHash, rootHash)
require.Equal(t, string(rootHash1), rootHash)

Copilot uses AI. Check for mistakes.
@AdoAdoAdo AdoAdoAdo merged commit e96692e into feat/supernova-async-exec Nov 3, 2025
11 checks passed
@AdoAdoAdo AdoAdoAdo deleted the chain-handler-last-execution-info branch November 3, 2025 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants