Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions epochStart/bootstrap/disabled/disabledEpochStartTrigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ func (e *epochStartTrigger) ShouldProposeEpochChange(_ uint64, _ uint64) bool {
func (e *epochStartTrigger) SetEpochChangeProposed(_ bool) {
}

// GetEpochChangeProposed -
func (e *epochStartTrigger) GetEpochChangeProposed() bool {
return false
}

// SetEpochChange -
func (e *epochStartTrigger) SetEpochChange(_ uint64) {}

Expand Down
4 changes: 3 additions & 1 deletion epochStart/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (

"github.com/multiversx/mx-chain-core-go/data"
"github.com/multiversx/mx-chain-core-go/data/block"
vmcommon "github.com/multiversx/mx-chain-vm-common-go"

"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/state"
vmcommon "github.com/multiversx/mx-chain-vm-common-go"
)

// TriggerHandler defines the functionalities for an start of epoch trigger
Expand All @@ -23,6 +24,7 @@ type TriggerHandler interface {
SetEpochChange(round uint64)
ShouldProposeEpochChange(round uint64, nonce uint64) bool
SetEpochChangeProposed(value bool)
GetEpochChangeProposed() bool
EpochStartRound() uint64
EpochStartMetaHdrHash() []byte
LastCommitedEpochStartHdr() (data.HeaderHandler, error)
Expand Down
7 changes: 7 additions & 0 deletions epochStart/metachain/trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ func (t *trigger) SetEpochChangeProposed(value bool) {
t.epochChangeProposed = value
}

// GetEpochChangeProposed returns the epoch change proposed flag
func (t *trigger) GetEpochChangeProposed() bool {
t.mutTrigger.RLock()
defer t.mutTrigger.RUnlock()
return t.epochChangeProposed
}

func (t *trigger) shouldTriggerEpochStart(currentRound uint64, currentNonce uint64) bool {
isZeroEpochEdgeCase := currentNonce < minimumNonceToStartEpoch
isNormalEpochStart := currentRound > t.currEpochStartRound+t.getRoundsPerEpoch(t.epoch)-t.getOffsetPerEpoch(t.epoch)
Expand Down
5 changes: 5 additions & 0 deletions epochStart/shardchain/trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,11 @@ func (t *trigger) SetEpochChangeProposed(_ bool) {
// no implementation needed
}

// GetEpochChangeProposed will always return false
func (t *trigger) GetEpochChangeProposed() bool {
return false
}

// SetFinalityAttestingRound sets the round which finalized the start of epoch block
func (t *trigger) SetFinalityAttestingRound(_ uint64) {
}
Expand Down
10 changes: 10 additions & 0 deletions factory/mock/epochStartTriggerStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type EpochStartTriggerStub struct {
ShouldProposeEpochChangeCalled func(round uint64, nonce uint64) bool
SetEpochChangeCalled func(round uint64)
SetEpochChangeProposedCalled func(value bool)
GetEpochChangeProposedCalled func() bool
}

// SetEpochChange -
Expand All @@ -48,6 +49,15 @@ func (e *EpochStartTriggerStub) SetEpochChangeProposed(value bool) {
}
}

// GetEpochChangeProposed -
func (e *EpochStartTriggerStub) GetEpochChangeProposed() bool {
if e.GetEpochChangeProposedCalled != nil {
return e.GetEpochChangeProposedCalled()
}

return false
}

// RevertStateToBlock -
func (e *EpochStartTriggerStub) RevertStateToBlock(_ data.HeaderHandler) error {
return nil
Expand Down
10 changes: 10 additions & 0 deletions integrationTests/mock/endOfEpochTriggerStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type EpochStartTriggerStub struct {
ShouldProposeEpochChangeCalled func(round uint64, nonce uint64) bool
SetEpochChangeCalled func(round uint64)
SetEpochChangeProposedCalled func(value bool)
GetEpochChangeProposedCalled func() bool
}

// SetEpochChange -
Expand All @@ -48,6 +49,15 @@ func (e *EpochStartTriggerStub) SetEpochChangeProposed(value bool) {
}
}

// GetEpochChangeProposed -
func (e *EpochStartTriggerStub) GetEpochChangeProposed() bool {
if e.GetEpochChangeProposedCalled != nil {
return e.GetEpochChangeProposedCalled()
}

return false
}

// RevertStateToBlock -
func (e *EpochStartTriggerStub) RevertStateToBlock(_ data.HeaderHandler) error {
return nil
Expand Down
10 changes: 10 additions & 0 deletions node/mock/endOfEpochTriggerStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type EpochStartTriggerStub struct {
ShouldProposeEpochChangeCalled func(round uint64, nonce uint64) bool
SetEpochChangeCalled func(round uint64)
SetEpochChangeProposedCalled func(value bool)
GetEpochChangeProposedCalled func() bool
}

// SetEpochChange -
Expand All @@ -46,6 +47,15 @@ func (e *EpochStartTriggerStub) SetEpochChangeProposed(value bool) {
}
}

// GetEpochChangeProposed -
func (e *EpochStartTriggerStub) GetEpochChangeProposed() bool {
if e.GetEpochChangeProposedCalled != nil {
return e.GetEpochChangeProposedCalled()
}

return false
}

// RevertStateToBlock -
func (e *EpochStartTriggerStub) RevertStateToBlock(_ data.HeaderHandler) error {
return nil
Expand Down
7 changes: 6 additions & 1 deletion process/block/metablockProposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (mp *metaProcessor) CreateBlockProposal(

metaHdr.SoftwareVersion = []byte(mp.headerIntegrityVerifier.GetVersion(metaHdr.Epoch, metaHdr.Round))

if metaHdr.IsStartOfEpochBlock() || metaHdr.GetEpochChangeProposed() || mp.epochStartTrigger.IsEpochStart() {
if metaHdr.IsStartOfEpochBlock() || metaHdr.GetEpochChangeProposed() || mp.epochStartTrigger.GetEpochChangeProposed() {
// no new transactions in start of epoch block
// to simplify bootstrapping
return metaHdr, &block.Body{}, nil
Expand Down Expand Up @@ -978,6 +978,11 @@ func (mp *metaProcessor) checkShardHeadersValidityAndFinalityProposal(
return fmt.Errorf("%w : checkShardHeadersValidityAndFinalityProposal -> getShardHeadersFromMetaHeader", err)
}

shouldNotHaveShardHeaders := metaHeaderHandler.IsStartOfEpochBlock() || metaHeaderHandler.IsEpochChangeProposed() || mp.epochStartTrigger.GetEpochChangeProposed()
if len(usedShardHeaders.orderedShardHeaders) > 0 && shouldNotHaveShardHeaders {
return fmt.Errorf("%w : between epoch change proposed and epoch start block", process.ErrShardHeadersShouldNotBeNotarized)
}
Comment on lines +981 to +984

Copilot AI Feb 2, 2026

Copy link

Choose a reason for hiding this comment

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

The new validation logic that checks if shard headers should not be notarized during epoch change is missing test coverage. There should be test cases in Test_checkShardHeadersValidityAndFinalityProposal that verify:

  1. When GetEpochChangeProposed() returns true and there are shard headers present, the error ErrShardHeadersShouldNotBeNotarized is returned
  2. When IsStartOfEpochBlock() returns true and there are shard headers present, the error is returned
  3. When IsEpochChangeProposed() returns true on the meta header and there are shard headers present, the error is returned

Copilot uses AI. Check for mistakes.

ok := mp.hasProofsForHeaders(usedShardHeaders.headersPerShard)
if !ok {
return process.ErrMissingHeaderProof
Expand Down
29 changes: 27 additions & 2 deletions process/block/metablockProposal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ func TestMetaProcessor_CreateBlockProposal(t *testing.T) {
require.NotNil(t, header)
require.NotNil(t, body)
})
t.Run("no mini blocks added if isEpochStart", func(t *testing.T) {
t.Run("no mini blocks added if epoch change propose set", func(t *testing.T) {
t.Parallel()

coreComponents, dataComponents, bootstrapComponents, statusComponents := createMockComponentHolders()
Expand All @@ -661,7 +661,7 @@ func TestMetaProcessor_CreateBlockProposal(t *testing.T) {
},
}
arguments.EpochStartTrigger = &testscommon.EpochStartTriggerStub{
IsEpochStartCalled: func() bool {
GetEpochChangeProposedCalled: func() bool {
return true
},
}
Expand Down Expand Up @@ -1157,6 +1157,11 @@ func Test_checkShardHeadersValidityAndFinalityProposal(t *testing.T) {
return nil, nil, expectedErr
},
},
"epochStartTrigger": &testscommon.EpochStartTriggerStub{
GetEpochChangeProposedCalled: func() bool {
return false
},
},
})
require.Nil(t, err)

Expand Down Expand Up @@ -1189,6 +1194,11 @@ func Test_checkShardHeadersValidityAndFinalityProposal(t *testing.T) {
return &testscommon.HeaderHandlerStub{}, nil, nil
},
},
"epochStartTrigger": &testscommon.EpochStartTriggerStub{
GetEpochChangeProposedCalled: func() bool {
return false
},
},
"dataPool": dataPoolMock,
})
require.Nil(t, err)
Expand Down Expand Up @@ -1242,6 +1252,11 @@ func Test_checkShardHeadersValidityAndFinalityProposal(t *testing.T) {
return &testscommon.HeaderHandlerStub{}, nil, nil
},
},
"epochStartTrigger": &testscommon.EpochStartTriggerStub{
GetEpochChangeProposedCalled: func() bool {
return false
},
},
"dataPool": dataPoolMock,
"proofsPool": proofsPool,
"store": storage,
Expand Down Expand Up @@ -1296,6 +1311,11 @@ func Test_checkShardHeadersValidityAndFinalityProposal(t *testing.T) {
return &testscommon.HeaderHandlerStub{}, nil, nil
},
},
"epochStartTrigger": &testscommon.EpochStartTriggerStub{
GetEpochChangeProposedCalled: func() bool {
return false
},
},
"dataPool": dataPoolMock,
"marshalizer": marshaller,
"blockChain": &testscommon.ChainHandlerStub{
Expand Down Expand Up @@ -1336,6 +1356,11 @@ func Test_checkShardHeadersValidityAndFinalityProposal(t *testing.T) {
return &testscommon.HeaderHandlerStub{}, nil, nil
},
},
"epochStartTrigger": &testscommon.EpochStartTriggerStub{
GetEpochChangeProposedCalled: func() bool {
return false
},
},
"dataPool": dataPoolMock,
"marshalizer": &marshal.GogoProtoMarshalizer{},
"proofsPool": &dataRetrieverMock.ProofsPoolMock{
Expand Down
3 changes: 3 additions & 0 deletions process/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -1448,3 +1448,6 @@ var ErrNoReferencedHeader = errors.New("no referenced header")

// ErrExecutionResultNotFound signals that the execution result was not found
var ErrExecutionResultNotFound = errors.New("execution result not found")

// ErrShardHeadersShouldNotBeNotarized signals that shard headers should not be notarized
var ErrShardHeadersShouldNotBeNotarized = errors.New("shard headers should not be notarized")
1 change: 1 addition & 0 deletions process/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ type EpochStartTriggerHandler interface {
SetEpochChange(round uint64)
ShouldProposeEpochChange(round uint64, nonce uint64) bool
SetEpochChangeProposed(value bool)
GetEpochChangeProposed() bool
IsEpochStart() bool
Epoch() uint32
MetaEpoch() uint32
Expand Down
9 changes: 9 additions & 0 deletions process/mock/endOfEpochTriggerStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type EpochStartTriggerStub struct {
ShouldProposeEpochChangeCalled func(round uint64, nonce uint64) bool
SetEpochChangeCalled func(round uint64)
SetEpochChangeProposedCalled func(value bool)
GetEpochChangeProposedCalled func() bool
}

func (e *EpochStartTriggerStub) SetEpochChangeProposed(value bool) {
Expand All @@ -32,6 +33,14 @@ func (e *EpochStartTriggerStub) SetEpochChangeProposed(value bool) {
}
}

// GetEpochChangeProposed -
func (e *EpochStartTriggerStub) GetEpochChangeProposed() bool {
if e.GetEpochChangeProposedCalled != nil {
return e.GetEpochChangeProposedCalled()
}
return false
}

// SetEpochChange -
func (e *EpochStartTriggerStub) SetEpochChange(round uint64) {
if e.SetEpochChangeCalled != nil {
Expand Down
9 changes: 9 additions & 0 deletions testscommon/epochStartTriggerStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type EpochStartTriggerStub struct {
ShouldProposeEpochChangeCalled func(round uint64, nonce uint64) bool
SetEpochChangeCalled func(round uint64)
SetEpochChangeProposedCalled func(value bool)
GetEpochChangeProposedCalled func() bool
}

// SetEpochChange -
Expand Down Expand Up @@ -119,6 +120,14 @@ func (e *EpochStartTriggerStub) SetEpochChangeProposed(value bool) {
}
}

// GetEpochChangeProposed -
func (e *EpochStartTriggerStub) GetEpochChangeProposed() bool {
if e.GetEpochChangeProposedCalled != nil {
return e.GetEpochChangeProposedCalled()
}
return false
}

// Update -
func (e *EpochStartTriggerStub) Update(round uint64, nonce uint64) {
if e.UpdateCalled != nil {
Expand Down
Loading