diff --git a/process/block/headerForBlock/export_test.go b/process/block/headerForBlock/export_test.go index f1547738d9..eeb43c67f6 100644 --- a/process/block/headerForBlock/export_test.go +++ b/process/block/headerForBlock/export_test.go @@ -48,3 +48,23 @@ func (hfb *headersForBlock) ComputeExistingAndRequestMissingShardHeaders(metaBlo func (hfb *headersForBlock) UpdateLastNotarizedBlockForShard(hdr data.ShardHeaderHandler, headerHash []byte) { hfb.updateLastNotarizedBlockForShard(hdr, headerHash) } + +// SetLastNotarizedHeaderForShard - +func (hfb *headersForBlock) SetLastNotarizedHeaderForShard(shardID uint32, info LastNotarizedHeaderInfoHandler) { + hfb.lastNotarizedShardHeaders[shardID] = info +} + +// SetHighestHdrNonceForCurrentBlock - +func (hfb *headersForBlock) SetHighestHdrNonceForCurrentBlock(shardID uint32, nonce uint64) { + hfb.highestHdrNonce[shardID] = nonce +} + +// SetShardBlockFinality - +func (hfb *headersForBlock) SetShardBlockFinality(finality uint32) { + hfb.blockFinality = finality +} + +// RequestMissingFinalityAttestingShardHeaders - +func (hfb *headersForBlock) RequestMissingFinalityAttestingShardHeaders() uint32 { + return hfb.requestMissingFinalityAttestingShardHeaders() +} diff --git a/process/block/headerForBlock/headersForBlock.go b/process/block/headerForBlock/headersForBlock.go index 3d2726b9ad..f3f3a3863a 100644 --- a/process/block/headerForBlock/headersForBlock.go +++ b/process/block/headerForBlock/headersForBlock.go @@ -580,6 +580,8 @@ func (hfb *headersForBlock) requestMissingFinalityAttestingHeaders( false, false, ) + + hfb.requestProofIfNeeded(headersHashes[index], headers[index]) } } diff --git a/process/block/headerForBlock/headersForBlock_test.go b/process/block/headerForBlock/headersForBlock_test.go index d1da9b42c8..9abb4912ab 100644 --- a/process/block/headerForBlock/headersForBlock_test.go +++ b/process/block/headerForBlock/headersForBlock_test.go @@ -914,6 +914,98 @@ func TestHeadersForBlock_ComputeHeadersForCurrentBlock(t *testing.T) { }) } +func TestHeadersForBlock_RequestMissingFinalityAttestingShardHeaders(t *testing.T) { + t.Parallel() + + t.Run("attestation header present but proof missing should request proof", func(t *testing.T) { + t.Parallel() + + referencedHeaderHash := []byte("sh0TestHash1") + referencedHeader := &block.HeaderV2{ + Header: &block.Header{ + ShardID: 0, + Round: 100, + Nonce: 100, + }, + } + attestationHeaderHash := []byte("sh0TestHash2") + attestationHeader := &block.HeaderV2{ + Header: &block.Header{ + ShardID: 0, + Round: 101, + Nonce: 101, + PrevHash: referencedHeaderHash, + }, + } + + counter := 0 + var requestedShardID uint32 + var requestedHash []byte + var mutRequestEquivalentProof sync.Mutex + wg := &sync.WaitGroup{} + wg.Add(1) + + args := createMockArgs() + args.ShardCoordinator = &testscommon.ShardsCoordinatorMock{ + NoShards: 2, + } + args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ + IsFlagEnabledInEpochCalled: func(flag core.EnableEpochFlag, epoch uint32) bool { + return flag == common.AndromedaFlag + }, + } + args.RequestHandler = &testscommon.RequestHandlerStub{ + RequestEquivalentProofByHashCalled: func(headerShard uint32, headerHash []byte) { + mutRequestEquivalentProof.Lock() + counter++ + requestedShardID = headerShard + requestedHash = append([]byte(nil), headerHash...) + mutRequestEquivalentProof.Unlock() + + wg.Done() + }, + } + + poolsHolder, ok := args.DataPool.(*dataRetriever.PoolsHolderMock) + require.True(t, ok) + poolsHolder.SetHeadersPool(createPoolsHolderForHeaderRequests()) + poolsHolder.SetProofsPool(&dataRetriever.ProofsPoolMock{ + HasProofCalled: func(shardID uint32, headerHash []byte) bool { + return false // no proof available for the attestation header + }, + }) + + args.BlockTracker = &mock.BlockTrackerStub{ + GetLastCrossNotarizedHeaderCalled: func(shardID uint32) (data.HeaderHandler, []byte, error) { + return referencedHeader, referencedHeaderHash, nil + }, + } + + hfb, err := headerForBlock.NewHeadersForBlock(args) + require.NoError(t, err) + + hfb.SetShardBlockFinality(1) + hfb.SetHighestHdrNonceForCurrentBlock(referencedHeader.GetShardID(), referencedHeader.GetNonce()) + hfb.SetLastNotarizedHeaderForShard( + referencedHeader.GetShardID(), + headerForBlock.NewLastNotarizedHeaderInfo(referencedHeader, referencedHeaderHash, false, false), + ) + + poolsHolder.Headers().AddHeader(attestationHeaderHash, attestationHeader) + + missingFinalityHeaders := hfb.RequestMissingFinalityAttestingShardHeaders() + require.Equal(t, uint32(0), missingFinalityHeaders) + + wg.Wait() + + mutRequestEquivalentProof.Lock() + require.Equal(t, 1, counter) + require.Equal(t, attestationHeader.GetShardID(), requestedShardID) + require.Equal(t, attestationHeaderHash, requestedHash) + mutRequestEquivalentProof.Unlock() + }) +} + type headerData struct { header data.HeaderHandler headerHash []byte diff --git a/process/block/interceptedBlocks/common.go b/process/block/interceptedBlocks/common.go index cdd6133caa..188f0766c5 100644 --- a/process/block/interceptedBlocks/common.go +++ b/process/block/interceptedBlocks/common.go @@ -10,7 +10,6 @@ import ( "github.com/multiversx/mx-chain-go/sharding" ) -const maxLenMiniBlockReservedField = 10 const maxLenMiniBlockHeaderReservedField = 32 func checkForDuplicateHashes(hashes [][]byte) error { diff --git a/process/coordinator/process.go b/process/coordinator/process.go index b5a27f108c..c438fa5e78 100644 --- a/process/coordinator/process.go +++ b/process/coordinator/process.go @@ -484,40 +484,6 @@ func (tc *transactionCoordinator) processMiniBlocksFromMe( return nil } -// TODO consider calling this from VerifyBlockProposal instead of ProcessBlockProposal -func (tc *transactionCoordinator) checkMiniBlock( - miniBlock *block.MiniBlock, -) error { - // there are checks for non existing shard id at interceptors level - - if miniBlock.SenderShardID != tc.shardCoordinator.SelfId() && miniBlock.GetReceiverShardID() != tc.shardCoordinator.SelfId() && miniBlock.GetReceiverShardID() != core.AllShardId { - return fmt.Errorf("%w - not valid shard ids: block type: %s, sender shard id: %d, receiver shard id: %d", - process.ErrInvalidShardId, - miniBlock.Type, - miniBlock.SenderShardID, - miniBlock.ReceiverShardID) - } - - if miniBlock.GetType() == block.PeerBlock && - (miniBlock.GetSenderShardID() != core.MetachainShardId || miniBlock.GetReceiverShardID() != core.AllShardId) { - return fmt.Errorf("%w - peer blocks: block type: %s, sender shard id: %d, receiver shard id: %d", - process.ErrInvalidShardId, - miniBlock.Type, - miniBlock.SenderShardID, - miniBlock.ReceiverShardID) - } - - if miniBlock.GetType() != block.PeerBlock && miniBlock.GetReceiverShardID() == core.AllShardId { - return fmt.Errorf("%w - invalid all shard ids: block type: %s, sender shard id: %d, receiver shard id: %d", - process.ErrInvalidShardId, - miniBlock.Type, - miniBlock.SenderShardID, - miniBlock.ReceiverShardID) - } - - return nil -} - func (tc *transactionCoordinator) processMiniBlocksToMe( header data.HeaderHandler, body *block.Body,