Skip to content

Supernova meta processing#7354

Merged
AdoAdoAdo merged 66 commits into
feat/supernova-async-execfrom
supernova-meta-processing
Nov 6, 2025
Merged

Supernova meta processing#7354
AdoAdoAdo merged 66 commits into
feat/supernova-async-execfrom
supernova-meta-processing

Conversation

@AdoAdoAdo

@AdoAdoAdo AdoAdoAdo commented Oct 20, 2025

Copy link
Copy Markdown
Contributor

Reasoning behind the pull request

  • This pull request implements supernova meta block processing functionality, introducing support for V3 meta headers and execution results-based block creation.
  • The changes enable meta blocks to reference shard headers through execution results rather than direct inclusion, and refactor the epoch start trigger interface to accept round parameters.

Proposed changes

  • Added new CreateNewHeaderProposal and CreateBlockProposal methods for V3 meta block creation
  • Implemented ShardInfoCreator component to handle shard info creation from both V3 and legacy headers
  • Refactored EpochStartTriggerHandler interface, replacing UpdateRound() with parameter on SetEpochChange(round)
  • Renamed meta block reference tracking methods from MetaBlock to generic Header for broader applicability

Testing procedure

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?

@codecov

codecov Bot commented Oct 20, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.50327% with 52 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.35%. Comparing base (0562801) to head (7faab3c).
⚠️ Report is 68 commits behind head on feat/supernova-async-exec.

Files with missing lines Patch % Lines
process/block/metablockProposal.go 93.19% 11 Missing and 5 partials ⚠️
process/block/shardblockProposal.go 62.50% 15 Missing ⚠️
process/block/metablock.go 74.35% 5 Missing and 5 partials ⚠️
process/block/baseProcess.go 94.02% 2 Missing and 2 partials ⚠️
process/common.go 0.00% 2 Missing and 2 partials ⚠️
factory/processing/blockProcessorCreator.go 80.00% 1 Missing and 1 partial ⚠️
epochStart/shardchain/trigger.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                      Coverage Diff                      @@
##           feat/supernova-async-exec    #7354      +/-   ##
=============================================================
+ Coverage                      77.30%   77.35%   +0.04%     
=============================================================
  Files                            867      868       +1     
  Lines                         116906   117321     +415     
=============================================================
+ Hits                           90379    90758     +379     
- Misses                         20565    20591      +26     
- Partials                        5962     5972      +10     

☔ 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.

Comment thread process/block/baseProcess.go Outdated
"hash", currentBlockHash)
bp.revertGasForCrossShardDstMeMiniBlocks(currMiniBlocksAdded, pendingMiniBlocks)

return false, pendingMiniBlocks, nil

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

just a note, this might be misleading, as the returned pendingMiniBlocks are not pending anymore, as they were reverted.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

although the comment from metablockProposal.go clarifies this a bit

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.

refactored this part

Comment thread process/block/gasConsumption.go Outdated

// RevertIncomingMiniBlocks reverts the gas consumption for the given incoming mini blocks
func (gc *gasConsumption) RevertIncomingMiniBlocks(miniBlockHashes [][]byte) {
// TODO: implement this

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

implemented on #7357

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.

will remove todo once it is merged.

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.

removed

if !ok {
continue
}
mp.addHeader(shardHdrInfo.Hash, shardHdrInfo.Header, shardHdrInfo.UsedInBlock)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

pass the entire structure?

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.

addHeader was not refactored in this PR

func (mp *metaProcessor) createProposalMiniBlocks(haveTime func() bool) error {
if !haveTime() {
log.Debug("metaProcessor.createProposalMiniBlocks", "error", process.ErrTimeIsOut)
return nil

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

return nil here = create a proposal with empty body?

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.

yes

shardHeaders []data.HeaderHandler,
shardHeaderHashes [][]byte,
) ([]data.ShardDataHandler, error) {
if !metaHeader.IsHeaderV3() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

check header for 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.

done

shardHeaders []data.ShardHeaderHandler,
shardHeaderHashes [][]byte,
) ([]data.ShardDataHandler, error) {
if metaHeader.IsHeaderV3() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

check header for 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.

done

Comment thread process/block/shardInfo.go Outdated
return nil, process.ErrWrongTypeAssertion
}

execResultHandler.GetMiniBlockHeadersHandlers()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

to be removed

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.

yes, removed

Comment thread process/block/shardInfo.go Outdated
execResultHandler data.ExecutionResultHandler,
) []block.MiniBlockHeader {
mbHeaderHandlers := execResultHandler.GetMiniBlockHeadersHandlers()
shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0)
shardMiniBlockHeaders := make([]block.MiniBlockHeader, 0, len(mbHeaderHandlers))

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

@ssd04 ssd04 self-requested a review November 4, 2025 14:41
Comment thread process/block/baseProcess.go Outdated
Comment on lines +2806 to +2817
return &CrossShardIncomingMbsCreationResult{
HeaderFinished: false,
PendingMiniBlocks: pendingMiniBlocks,
AddedMiniBlocks: currMiniBlocksAdded,
}, nil
}

return &CrossShardIncomingMbsCreationResult{
HeaderFinished: true,
PendingMiniBlocks: pendingMiniBlocks,
AddedMiniBlocks: currMiniBlocksAdded,
}, nil

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.

Suggested change
return &CrossShardIncomingMbsCreationResult{
HeaderFinished: false,
PendingMiniBlocks: pendingMiniBlocks,
AddedMiniBlocks: currMiniBlocksAdded,
}, nil
}
return &CrossShardIncomingMbsCreationResult{
HeaderFinished: true,
PendingMiniBlocks: pendingMiniBlocks,
AddedMiniBlocks: currMiniBlocksAdded,
}, nil
}
return &CrossShardIncomingMbsCreationResult{
HeaderFinished: hdrFinished,
PendingMiniBlocks: pendingMiniBlocks,
AddedMiniBlocks: currMiniBlocksAdded,
}, nil

return hdrFinished directly?

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

Comment thread process/block/metablock.go Outdated
func (mp *metaProcessor) getLastCrossNotarizedShardHdrs() (map[uint32]data.HeaderHandler, error) {
lastCrossNotarizedHeader := make(map[uint32]data.HeaderHandler, mp.shardCoordinator.NumberOfShards())
func (mp *metaProcessor) getLastCrossNotarizedShardHdrsAndAddToCurrentBlock() (map[uint32]data.HeaderHandler, error) {
lastCrossNotarizedHeader, err := mp.getLastCrossNotarizedShardHdrs()

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.

rename to ...Headers? same below

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

func (mp *metaProcessor) createShardInfo(metaHdr data.MetaHeaderHandler) ([]data.ShardDataHandler, error) {
var shardInfo []data.ShardDataHandler
if mp.epochStartTrigger.IsEpochStart() {
if metaHdr.IsStartOfEpochBlock() {

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 don't need to check by epochStartTrigger.IsEpochStart() on legacy?

@AdoAdoAdo AdoAdoAdo Nov 6, 2025

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.

adding of epoch start data should have already happened on the condition of epochStartTrigger.IsEpochStart() earlier (on block creation), so at this point the conditions should be equivalent for legacy.

return nil, process.ErrWrongTypeAssertion
}

header, err := sic.headersPool.GetHeaderByHash(execResultHandler.GetHeaderHash())

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.

i'm thinking if it might help to use GetHeader func (from process common which search in pool and then in storage) it should be in the pool but if there is an edge case

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.

that would mean giving the component access also to the storage service. I would leave it like this for now, the header should be in the pool. We can see first how the testing goes and decide later if if is really needed.

Comment on lines +29 to +33
shardHeader, ok := header.(data.ShardHeaderHandler)
if !ok {
return nil, process.ErrWrongTypeAssertion
}

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.

add IsHeaderV3 check? as for meta header proposal

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, added.

return nil, err
}

err = mp.addExecutionResultsOnHeader(metaHeader)

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.

do we add execution results on header on CreateNewHeaderProposal? shoudn't be set on CreateBlockProposal?

@AdoAdoAdo AdoAdoAdo Nov 6, 2025

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.

this was required on the metachain with the proposal flow, as otherwise we would not know that the epoch change should be done (we do the epoch change now when we notarize the execution results from an epoch change proposal, rather than relying on the epoch change trigger component).

This was done in order to have minimal changes to the trigger, considering that the detection of the epoch change conditions are now not in sync with the execution of an epoch change, and the commit of the epoch change.

return nil, nil
}

func (mp *metaProcessor) hasStartOfEpochExecutionResults(metaHeader data.MetaHeaderHandler) (bool, error) {

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.

Suggested change
func (mp *metaProcessor) hasStartOfEpochExecutionResults(metaHeader data.MetaHeaderHandler) (bool, error) {
func hasStartOfEpochExecutionResults(metaHeader data.MetaHeaderHandler) (bool, error) {

*optional: i might refactor a bit and use this also in epoch start bootstrap in another PR

@AdoAdoAdo AdoAdoAdo Nov 6, 2025

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.

yes, this could be moved and refactored, I would do this on another PR, there is an ongoing work of adding unit tests for this in a separate PR.

Comment on lines +401 to +402
}

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.

on legacy there was also go mp.requestShardHeadersIfNeeded(hdrsAddedForShard, lastShardHdr) we don't need it anymore?

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.

yes, I think we need something similar, but requesting both headers and proofs, and not based on the finality as the headers are already final once they have a proof.

This should be done on another PR.

defer s.mut.Unlock()

if check.IfNil(metaBlock) || len(metaBlockHash) == 0 {
if check.IfNil(header) || len(headerHash) == 0 {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

not related to this pr: can be done before mutex lock

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

Comment on lines +263 to +264
// TODO: pendingMiniBlocksHandler should be updated
shardData.NumPendingMiniBlocks = uint32(len(sic.pendingMiniBlocksHandler.GetPendingMiniBlocks(header.GetShardID())))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

done, coming in another PR

func (mp *metaProcessor) getLastCrossNotarizedShardHdrs() (map[uint32]data.HeaderHandler, error) {
lastCrossNotarizedHeader := make(map[uint32]data.HeaderHandler, mp.shardCoordinator.NumberOfShards())
func (mp *metaProcessor) getLastCrossNotarizedShardHdrsAndAddToCurrentBlock() (map[uint32]data.HeaderHandler, error) {
lastCrossNotarizedHeader, err := mp.getLastCrossNotarizedShardHeaders()

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.

here i was referring to the variable name, it confused me at first, but not directly related to this PR, it can remain as it is

@AdoAdoAdo AdoAdoAdo merged commit d97945b into feat/supernova-async-exec Nov 6, 2025
11 checks passed
@AdoAdoAdo AdoAdoAdo deleted the supernova-meta-processing branch November 6, 2025 11:38
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.

6 participants