Skip to content

Commit

Permalink
Merge pull request #6680 from multiversx/MX-16369-propose-block-with-…
Browse files Browse the repository at this point in the history
…last-cross-chain-hash

[sovereign] Proposed epoch start header with last cross chain hash and request it if missing
  • Loading branch information
mariusmihaic authored Feb 6, 2025
2 parents ae6a791 + 3f838e2 commit 1b50045
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 18 deletions.
2 changes: 1 addition & 1 deletion cmd/sovereignnode/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ go 1.20

require (
github.com/google/gops v0.3.18
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250131122047-725dd68e256f
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250206111825-25fbb1b4851c
github.com/multiversx/mx-chain-go v1.8.4
github.com/multiversx/mx-chain-logger-go v1.0.15
github.com/multiversx/mx-chain-sovereign-bridge-go v0.0.0-20240116102202-4cf6fbbd95a3
Expand Down
4 changes: 2 additions & 2 deletions cmd/sovereignnode/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,8 @@ github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUY
github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o=
github.com/multiversx/mx-chain-communication-go v1.1.1 h1:y4DoQeQOJTaSUsRzczQFazf8JYQmInddypApqA3AkwM=
github.com/multiversx/mx-chain-communication-go v1.1.1/go.mod h1:WK6bP4pGEHGDDna/AYRIMtl6G9OA0NByI1Lw8PmOnRM=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250131122047-725dd68e256f h1:iyDk0Zk0n4pHZnrdX30SxevTy+xg9GcEyAmBss45Nfs=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250131122047-725dd68e256f/go.mod h1:P/YBoFnt25XUaCQ7Q/SD15vhnc9yV5JDhHxyFO9P8Z0=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250206111825-25fbb1b4851c h1:Cz5b0xd9lbSWGIwmfuPuHqL0e5kTun/PW5NpkVRIAXQ=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250206111825-25fbb1b4851c/go.mod h1:P/YBoFnt25XUaCQ7Q/SD15vhnc9yV5JDhHxyFO9P8Z0=
github.com/multiversx/mx-chain-crypto-go v1.2.12 h1:zWip7rpUS4CGthJxfKn5MZfMfYPjVjIiCID6uX5BSOk=
github.com/multiversx/mx-chain-crypto-go v1.2.12/go.mod h1:HzcPpCm1zanNct/6h2rIh+MFrlXbjA5C8+uMyXj3LI4=
github.com/multiversx/mx-chain-es-indexer-go v1.7.15-0.20250131122054-68d88c13fdac h1:AaD3sEsepJTHeLqp20ZvMzTY1KakWXYK2qcJfqfEdZM=
Expand Down
3 changes: 3 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,3 +874,6 @@ var ErrNilAPIRewardsHandler = errors.New("nil api rewards handler has been provi

// ErrNilOutportDataProviderFactory signals that a nil outport data provider factory has been provided
var ErrNilOutportDataProviderFactory = errors.New("nil outport data provider factory has been provided")

// ErrReceivedSovereignEpochStartBlockWithExtendedHeaders signals that an invalid epoch start sovereign block has been received
var ErrReceivedSovereignEpochStartBlockWithExtendedHeaders = errors.New("received invalid epoch start sovereign block, should not contain any extended headers")
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
github.com/klauspost/cpuid/v2 v2.2.5
github.com/mitchellh/mapstructure v1.5.0
github.com/multiversx/mx-chain-communication-go v1.1.1
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250131122047-725dd68e256f
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250206111825-25fbb1b4851c
github.com/multiversx/mx-chain-crypto-go v1.2.12
github.com/multiversx/mx-chain-es-indexer-go v1.7.15-0.20250131122054-68d88c13fdac
github.com/multiversx/mx-chain-logger-go v1.0.15
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@ github.com/multiversx/concurrent-map v0.1.4 h1:hdnbM8VE4b0KYJaGY5yJS2aNIW9TFFsUY
github.com/multiversx/concurrent-map v0.1.4/go.mod h1:8cWFRJDOrWHOTNSqgYCUvwT7c7eFQ4U2vKMOp4A/9+o=
github.com/multiversx/mx-chain-communication-go v1.1.1 h1:y4DoQeQOJTaSUsRzczQFazf8JYQmInddypApqA3AkwM=
github.com/multiversx/mx-chain-communication-go v1.1.1/go.mod h1:WK6bP4pGEHGDDna/AYRIMtl6G9OA0NByI1Lw8PmOnRM=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250131122047-725dd68e256f h1:iyDk0Zk0n4pHZnrdX30SxevTy+xg9GcEyAmBss45Nfs=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250131122047-725dd68e256f/go.mod h1:P/YBoFnt25XUaCQ7Q/SD15vhnc9yV5JDhHxyFO9P8Z0=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250206111825-25fbb1b4851c h1:Cz5b0xd9lbSWGIwmfuPuHqL0e5kTun/PW5NpkVRIAXQ=
github.com/multiversx/mx-chain-core-go v1.2.25-0.20250206111825-25fbb1b4851c/go.mod h1:P/YBoFnt25XUaCQ7Q/SD15vhnc9yV5JDhHxyFO9P8Z0=
github.com/multiversx/mx-chain-crypto-go v1.2.12 h1:zWip7rpUS4CGthJxfKn5MZfMfYPjVjIiCID6uX5BSOk=
github.com/multiversx/mx-chain-crypto-go v1.2.12/go.mod h1:HzcPpCm1zanNct/6h2rIh+MFrlXbjA5C8+uMyXj3LI4=
github.com/multiversx/mx-chain-es-indexer-go v1.7.15-0.20250131122054-68d88c13fdac h1:AaD3sEsepJTHeLqp20ZvMzTY1KakWXYK2qcJfqfEdZM=
Expand Down
82 changes: 70 additions & 12 deletions process/block/sovereignChainBlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ func (scbp *sovereignChainBlockProcessor) CreateBlock(initialHdr data.HeaderHand
return nil, nil, err
}

err = scbp.createEpochStartDataCrossChain(sovereignChainHeaderHandler)
if err != nil {
return nil, nil, err
}

scbp.blockChainHook.SetCurrentHeader(initialHdr)
scbp.requestHandler.SetEpoch(initialHdr.GetEpoch())
return initialHdr, &block.Body{}, nil
Expand Down Expand Up @@ -676,12 +681,60 @@ func (scbp *sovereignChainBlockProcessor) requestExtendedShardHeaders(sovereignC
_ = core.EmptyChannel(scbp.chRcvAllExtendedShardHdrs)

if len(sovereignChainHeader.GetExtendedShardHeaderHashes()) == 0 {
return 0
return scbp.computeAndRequestEpochStartExtendedHeaderIfMissing(sovereignChainHeader)
}

return scbp.computeExistingAndRequestMissingExtendedShardHeaders(sovereignChainHeader)
}

func (scbp *sovereignChainBlockProcessor) computeAndRequestEpochStartExtendedHeaderIfMissing(sovereignChainHeader data.SovereignChainHeaderHandler) uint32 {
if !sovereignChainHeader.IsStartOfEpochBlock() {
return 0
}

lastCrossChainData := sovereignChainHeader.GetLastFinalizedCrossChainHeaderHandler()
shouldCheckEpochStartCrossChainHash := lastCrossChainData != nil && len(lastCrossChainData.GetHeaderHash()) != 0
if !shouldCheckEpochStartCrossChainHash {
return 0
}

lastCrossChainHash := lastCrossChainData.GetHeaderHash()
if !scbp.shouldRequestEpochStartCrossChainHash(lastCrossChainHash) {
return 0
}

scbp.hdrsForCurrBlock.mutHdrsForBlock.Lock()
scbp.hdrsForCurrBlock.missingHdrs++
scbp.hdrsForCurrBlock.hdrHashAndInfo[string(lastCrossChainHash)] = &hdrInfo{
hdr: nil,
usedInBlock: false,
}
scbp.hdrsForCurrBlock.mutHdrsForBlock.Unlock()

go scbp.extendedShardHeaderRequester.RequestExtendedShardHeader(lastCrossChainHash)

return 1
}

func (scbp *sovereignChainBlockProcessor) shouldRequestEpochStartCrossChainHash(lastCrossChainHash []byte) bool {
_, errMissingHdrPool := process.GetExtendedShardHeaderFromPool(
lastCrossChainHash,
scbp.dataPool.Headers())
_, lastNotarizedHdrHash, _ := scbp.blockTracker.GetLastCrossNotarizedHeader(core.MainChainShardId)

missingHeaderInTracker := !bytes.Equal(lastNotarizedHdrHash, lastCrossChainHash)
missingHeaderInPool := errMissingHdrPool != nil
shouldRequestLastCrossChainHeader := missingHeaderInTracker || missingHeaderInPool

log.Debug("sovereignChainBlockProcessor.checkAndRequestIfMissingEpochStartExtendedHeader",
"missingHeaderInTracker", missingHeaderInTracker,
"missingHeaderInPool", missingHeaderInPool,
"shouldRequestLastCrossChainHeader", shouldRequestLastCrossChainHeader,
)

return shouldRequestLastCrossChainHeader
}

func (scbp *sovereignChainBlockProcessor) computeExistingAndRequestMissingExtendedShardHeaders(sovereignChainHeader data.SovereignChainHeaderHandler) uint32 {
scbp.hdrsForCurrBlock.mutHdrsForBlock.Lock()
defer scbp.hdrsForCurrBlock.mutHdrsForBlock.Unlock()
Expand Down Expand Up @@ -745,7 +798,7 @@ func (scbp *sovereignChainBlockProcessor) ProcessBlock(headerHandler data.Header
"nonce", headerHandler.GetNonce(),
)

sovereignChainHeader, ok := headerHandler.(data.SovereignChainHeaderHandler)
sovChainHeader, ok := headerHandler.(data.SovereignChainHeaderHandler)
if !ok {
return nil, nil, process.ErrWrongTypeAssertion
}
Expand All @@ -772,7 +825,7 @@ func (scbp *sovereignChainBlockProcessor) ProcessBlock(headerHandler data.Header
scbp.blockChainHook.SetCurrentHeader(headerHandler)

scbp.txCoordinator.RequestBlockTransactions(body)
requestedExtendedShardHdrs := scbp.requestExtendedShardHeaders(sovereignChainHeader)
requestedExtendedShardHdrs := scbp.requestExtendedShardHeaders(sovChainHeader)

if haveTime() < 0 {
return nil, nil, process.ErrTimeIsOut
Expand All @@ -799,7 +852,7 @@ func (scbp *sovereignChainBlockProcessor) ProcessBlock(headerHandler data.Header
go scbp.checkAndRequestIfExtendedShardHeadersMissing()
}()

err = scbp.checkExtendedShardHeadersValidity()
err = scbp.checkExtendedShardHeadersValidity(sovChainHeader)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -840,7 +893,7 @@ func (scbp *sovereignChainBlockProcessor) ProcessBlock(headerHandler data.Header
return nil, nil, err
}

err = scbp.verifySovereignPostProcessBlock(headerHandler, newBody, sovereignChainHeader)
err = scbp.verifySovereignPostProcessBlock(headerHandler, newBody, sovChainHeader)
if err != nil {
return nil, nil, err
}
Expand All @@ -849,7 +902,7 @@ func (scbp *sovereignChainBlockProcessor) ProcessBlock(headerHandler data.Header
}

// checkExtendedShardHeadersValidity checks if used extended shard headers are valid as construction
func (scbp *sovereignChainBlockProcessor) checkExtendedShardHeadersValidity() error {
func (scbp *sovereignChainBlockProcessor) checkExtendedShardHeadersValidity(sovereignChainHeader data.SovereignChainHeaderHandler) error {
lastCrossNotarizedHeader, _, err := scbp.blockTracker.GetLastCrossNotarizedHeader(core.MainChainShardId)
if err != nil {
return err
Expand All @@ -865,6 +918,11 @@ func (scbp *sovereignChainBlockProcessor) checkExtendedShardHeadersValidity() er
return nil
}

// we should not have an epoch start block with main chain headers to be processed
if sovereignChainHeader.IsStartOfEpochBlock() {
return errors.ErrReceivedSovereignEpochStartBlockWithExtendedHeaders
}

if scbp.isGenesisHeaderWithNoPreviousTracking(extendedShardHdrs[0]) {
// we are missing pre-genesis header, so we can't link it to previous header
if len(extendedShardHdrs) == 1 {
Expand Down Expand Up @@ -992,7 +1050,7 @@ func (scbp *sovereignChainBlockProcessor) processEpochStartMetaBlock(
return scbp.applyBodyToHeaderForEpochChange(header, body)
}

func (scbp *sovereignChainBlockProcessor) createEpochStartDataCrossChain(sovHdr *block.SovereignChainHeader) error {
func (scbp *sovereignChainBlockProcessor) createEpochStartDataCrossChain(sovHdr data.SovereignChainHeaderHandler) error {
lastCrossNotarizedHeader, lastCrossNotarizedHeaderHash, err := scbp.blockTracker.GetLastCrossNotarizedHeader(core.MainChainShardId)
if err != nil {
return err
Expand All @@ -1009,15 +1067,13 @@ func (scbp *sovereignChainBlockProcessor) createEpochStartDataCrossChain(sovHdr
"lastCrossNotarizedHeaderNonce", lastCrossNotarizedHeader.GetNonce(),
)

sovHdr.EpochStart.LastFinalizedCrossChainHeader = block.EpochStartCrossChainData{
return sovHdr.SetLastFinalizedCrossChainHeaderHandler(&block.EpochStartCrossChainData{
ShardID: core.MainChainShardId,
Epoch: lastCrossNotarizedHeader.GetEpoch(),
Round: lastCrossNotarizedHeader.GetRound(),
Nonce: lastCrossNotarizedHeader.GetNonce(),
HeaderHash: lastCrossNotarizedHeaderHash,
}

return nil
})
}

func (scbp *sovereignChainBlockProcessor) applyBodyToHeaderForEpochChange(header data.HeaderHandler, body *block.Body) error {
Expand Down Expand Up @@ -1122,7 +1178,9 @@ func (scbp *sovereignChainBlockProcessor) sortExtendedShardHeadersForCurrentBloc

scbp.hdrsForCurrBlock.mutHdrsForBlock.RLock()
for _, headerInfo := range scbp.hdrsForCurrBlock.hdrHashAndInfo {
hdrsForCurrentBlock = append(hdrsForCurrentBlock, headerInfo.hdr)
if headerInfo.usedInBlock {
hdrsForCurrentBlock = append(hdrsForCurrentBlock, headerInfo.hdr)
}
}
scbp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock()

Expand Down
1 change: 1 addition & 0 deletions process/track/blockNotarizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/multiversx/mx-chain-core-go/data"
"github.com/multiversx/mx-chain-core-go/hashing"
"github.com/multiversx/mx-chain-core-go/marshal"

"github.com/multiversx/mx-chain-go/process"
"github.com/multiversx/mx-chain-go/sharding"
)
Expand Down

0 comments on commit 1b50045

Please sign in to comment.