From 79f8cd04756d5878bba6d6656c77a5e325ec952f Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Tue, 1 Oct 2019 18:29:19 +0300 Subject: [PATCH 01/10] * Improved restoreMetaBlockIntoPool mechanism --- process/block/shardblock.go | 41 ++++++++----------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 6362e474934..d696b7931b5 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -609,32 +609,8 @@ func (sp *shardProcessor) restoreMetaBlockIntoPool(miniBlockHashes map[string]ui } } - for _, metaBlockKey := range metaBlockPool.Keys() { - if len(miniBlockHashes) == 0 { - break - } - metaBlock, ok := metaBlockPool.Peek(metaBlockKey) - if !ok { - log.Error(process.ErrNilMetaBlockHeader.Error()) - continue - } - - hdr, ok := metaBlock.(data.HeaderHandler) - if !ok { - metaBlockPool.Remove(metaBlockKey) - log.Error(process.ErrWrongTypeAssertion.Error()) - continue - } - - crossMiniBlockHashes := hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) - for key := range miniBlockHashes { - _, ok = crossMiniBlockHashes[key] - if !ok { - continue - } - - sp.removeProcessedMiniBlock(metaBlockKey, []byte(key)) - } + for miniBlockHash := range miniBlockHashes { + sp.removeProcessedMiniBlock([]byte(miniBlockHash)) } return nil @@ -1738,15 +1714,14 @@ func (sp *shardProcessor) addProcessedMiniBlock(metaBlockHash []byte, miniBlockH sp.mutProcessedMiniBlocks.Unlock() } -func (sp *shardProcessor) removeProcessedMiniBlock(metaBlockHash []byte, miniBlockHash []byte) { +func (sp *shardProcessor) removeProcessedMiniBlock(miniBlockHash []byte) { sp.mutProcessedMiniBlocks.Lock() - miniBlocksProcessed, ok := sp.processedMiniBlocks[string(metaBlockHash)] - if !ok { - sp.mutProcessedMiniBlocks.Unlock() - return + for _, miniBlocksProcessed := range sp.processedMiniBlocks { + _, isProcessed := miniBlocksProcessed[string(miniBlockHash)] + if isProcessed { + delete(miniBlocksProcessed, string(miniBlockHash)) + } } - - delete(miniBlocksProcessed, string(miniBlockHash)) sp.mutProcessedMiniBlocks.Unlock() } From f7b40575e2093844a6bb76f1e236ced0a5deeda1 Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Wed, 2 Oct 2019 13:33:10 +0300 Subject: [PATCH 02/10] * Improved management of requested/received meta header which are missing --- process/block/baseProcess.go | 8 +- process/block/displayBlock.go | 2 +- process/block/interceptedBlockHeader.go | 10 +- process/block/interceptedMetaBlockHeader.go | 8 +- process/block/metablock.go | 20 +- process/block/metablock_test.go | 28 +-- process/block/preprocess/basePreProcess.go | 13 +- process/block/shardblock.go | 195 +++++++++++--------- process/block/shardblock_test.go | 20 +- 9 files changed, 164 insertions(+), 140 deletions(-) diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 8413b239092..17cd7ee2b4f 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -86,7 +86,7 @@ func (bp *baseProcessor) RevertAccountState() { } } -// AddLastNotarizedHdr adds the last notarized header +// AddLastNotarizedHdr adds the last notarized hdr func (bp *baseProcessor) AddLastNotarizedHdr(shardId uint32, processedHdr data.HeaderHandler) { bp.mutNotarizedHdrs.Lock() bp.notarizedHdrs[shardId] = append(bp.notarizedHdrs[shardId], processedHdr) @@ -210,7 +210,7 @@ func (bp *baseProcessor) isHdrConstructionValid(currHdr, prevHdr data.HeaderHand } //TODO: add verification if rand seed was correctly computed add other verification - //TODO: check here if the 2 header blocks were correctly signed and the consensus group was correctly elected + //TODO: check here if the 2 hdr blocks were correctly signed and the consensus group was correctly elected if prevHdr.GetRound() >= currHdr.GetRound() { log.Debug(fmt.Sprintf("round does not match in shard %d: local block round is %d and node received block with round %d\n", currHdr.GetShardID(), prevHdr.GetRound(), currHdr.GetRound())) @@ -355,8 +355,8 @@ func (bp *baseProcessor) getLastNotarizedHdr(shardId uint32) (data.HeaderHandler } // SetLastNotarizedHeadersSlice sets the headers blocks in notarizedHdrs for every shard -// This is done when starting a new epoch so metachain can use it when validating next shard header blocks -// and shard can validate the next meta header +// This is done when starting a new epoch so metachain can use it when validating next shard hdr blocks +// and shard can validate the next meta hdr func (bp *baseProcessor) setLastNotarizedHeadersSlice(startHeaders map[uint32]data.HeaderHandler) error { //TODO: protect this to be called only once at genesis time //TODO: do this on constructor as it is a must to for blockprocessor to work diff --git a/process/block/displayBlock.go b/process/block/displayBlock.go index 085189bb40c..bdb48427e4e 100644 --- a/process/block/displayBlock.go +++ b/process/block/displayBlock.go @@ -226,7 +226,7 @@ func DisplayLastNotarized( shardId uint32) { if lastNotarizedHdrForShard == nil || lastNotarizedHdrForShard.IsInterfaceNil() { - log.Error("last notarized header for shard is nil") + log.Error("last notarized hdr for shard is nil") return } diff --git a/process/block/interceptedBlockHeader.go b/process/block/interceptedBlockHeader.go index b1493158f5b..baadd92362d 100644 --- a/process/block/interceptedBlockHeader.go +++ b/process/block/interceptedBlockHeader.go @@ -38,17 +38,17 @@ func NewInterceptedHeader( } } -// SetHash sets the hash of this header. The hash will also be the ID of this object +// SetHash sets the hash of this hdr. The hash will also be the ID of this object func (inHdr *InterceptedHeader) SetHash(hash []byte) { inHdr.hash = hash } -// Hash gets the hash of this header +// Hash gets the hash of this hdr func (inHdr *InterceptedHeader) Hash() []byte { return inHdr.hash } -// Shard returns the shard ID for which this header is addressed +// Shard returns the shard ID for which this hdr is addressed func (inHdr *InterceptedHeader) Shard() uint32 { return inHdr.ShardId } @@ -63,7 +63,7 @@ func (inHdr *InterceptedHeader) GetUnderlyingObject() interface{} { return inHdr.Header } -// IntegrityAndValidity checks the integrity and validity of a block header wrapper +// IntegrityAndValidity checks the integrity and validity of a block hdr wrapper func (inHdr *InterceptedHeader) IntegrityAndValidity(coordinator sharding.Coordinator) error { err := inHdr.Integrity(coordinator) if err != nil { @@ -144,7 +144,7 @@ func (inHdr *InterceptedHeader) VerifySig() error { return err } - // get marshalled block header without signature and bitmap + // get marshalled block hdr without signature and bitmap // as this is the message that was signed headerCopy := *inHdr.Header headerCopy.Signature = nil diff --git a/process/block/interceptedMetaBlockHeader.go b/process/block/interceptedMetaBlockHeader.go index b0fbcdf0227..010606a2858 100644 --- a/process/block/interceptedMetaBlockHeader.go +++ b/process/block/interceptedMetaBlockHeader.go @@ -38,12 +38,12 @@ func NewInterceptedMetaHeader( } } -// SetHash sets the hash of this header. The hash will also be the ID of this object +// SetHash sets the hash of this hdr. The hash will also be the ID of this object func (imh *InterceptedMetaHeader) SetHash(hash []byte) { imh.hash = hash } -// Hash gets the hash of this header +// Hash gets the hash of this hdr func (imh *InterceptedMetaHeader) Hash() []byte { return imh.hash } @@ -53,7 +53,7 @@ func (imh *InterceptedMetaHeader) GetMetaHeader() *block.MetaBlock { return imh.MetaBlock } -// IntegrityAndValidity checks the integrity and validity of a block header wrapper +// IntegrityAndValidity checks the integrity and validity of a block hdr wrapper func (imh *InterceptedMetaHeader) IntegrityAndValidity(coordinator sharding.Coordinator) error { err := imh.Integrity(coordinator) if err != nil { @@ -136,7 +136,7 @@ func (imh *InterceptedMetaHeader) VerifySig() error { return err } - // get marshalled block header without signature and bitmap + // get marshalled block hdr without signature and bitmap // as this is the message that was signed headerCopy := *imh.MetaBlock headerCopy.Signature = nil diff --git a/process/block/metablock.go b/process/block/metablock.go index c5c49e6ce24..21178a59570 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -147,7 +147,7 @@ func (mp *metaProcessor) ProcessBlock( err := mp.checkBlockValidity(chainHandler, headerHandler, bodyHandler) if err != nil { if err == process.ErrBlockHashDoesNotMatch { - log.Info(fmt.Sprintf("requested missing meta header with hash %s for shard %d\n", + log.Info(fmt.Sprintf("requested missing meta hdr with hash %s for shard %d\n", core.ToB64(headerHandler.GetPrevHash()), headerHandler.GetShardID())) @@ -743,7 +743,7 @@ func (mp *metaProcessor) checkShardHeadersFinality(header *block.MetaBlock, high break } - // found a header with the next nonce + // found a hdr with the next nonce tmpHdr := sortedHdrPerShard[shId][i] if tmpHdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { err := mp.isHdrConstructionValid(tmpHdr, lastVerifiedHdr) @@ -841,7 +841,7 @@ func (mp *metaProcessor) isShardHeaderValidFinal(currHdr *block.Header, lastHdr return true, hdrIds } - // found a header with the next nonce + // found a hdr with the next nonce tmpHdr := sortedShardHdrs[i] if tmpHdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { err := mp.isHdrConstructionValid(tmpHdr, lastVerifiedHdr) @@ -862,7 +862,7 @@ func (mp *metaProcessor) isShardHeaderValidFinal(currHdr *block.Header, lastHdr return false, nil } -// receivedHeader is a call back function which is called when a new header +// receivedHeader is a call back function which is called when a new hdr // is added in the headers pool func (mp *metaProcessor) receivedHeader(headerHash []byte) { shardHdrsCache := mp.dataPool.ShardHeaders() @@ -885,7 +885,7 @@ func (mp *metaProcessor) receivedHeader(headerHash []byte) { return } - log.Debug(fmt.Sprintf("received header with hash %s and nonce %d from network\n", + log.Debug(fmt.Sprintf("received hdr with hash %s and nonce %d from network\n", core.ToB64(headerHash), header.GetNonce())) @@ -925,7 +925,7 @@ func (mp *metaProcessor) receivedHeader(headerHash []byte) { } // requestFinalMissingHeaders requests the headers needed to accept the current selected headers for processing the -// current block. It requests the nextKValidity headers greater than the highest shard header, for each shard, related +// current block. It requests the nextKValidity headers greater than the highest shard hdr, for each shard, related // to the block which should be processed func (mp *metaProcessor) requestFinalMissingHeaders() uint32 { requestedBlockHeaders := uint32(0) @@ -1178,9 +1178,9 @@ func (mp *metaProcessor) createPeerInfo() ([]block.PeerData, error) { return peerInfo, nil } -// CreateBlockHeader creates a miniblock header list given a block body +// CreateBlockHeader creates a miniblock hdr list given a block body func (mp *metaProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round uint64, haveTime func() bool) (data.HeaderHandler, error) { - log.Debug(fmt.Sprintf("started creating block header in round %d\n", round)) + log.Debug(fmt.Sprintf("started creating block hdr in round %d\n", round)) // TODO: add PrevRandSeed and RandSeed when BLS signing is completed header := &block.MetaBlock{ ShardInfo: make([]block.ShardData, 0), @@ -1233,7 +1233,7 @@ func (mp *metaProcessor) MarshalizedDataToBroadcast( mrsData := make(map[uint32][]byte) mrsTxs := make(map[string][][]byte) - // send headers which can validate the current header + // send headers which can validate the current hdr return mrsData, mrsTxs, nil } @@ -1357,7 +1357,7 @@ func (mp *metaProcessor) DecodeBlockBody(dta []byte) data.BodyHandler { return &body } -// DecodeBlockHeader method decodes block header from a given byte array +// DecodeBlockHeader method decodes block hdr from a given byte array func (mp *metaProcessor) DecodeBlockHeader(dta []byte) data.HeaderHandler { if dta == nil { return nil diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index 271413ff620..e614803bf4d 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -901,7 +901,7 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.Nil(t, err) assert.True(t, removeHdrWasCalled) assert.True(t, forkDetectorAddCalled) - //this should sleep as there is an async call to display current header and block in CommitBlock + //this should sleep as there is an async call to display current hdr and block in CommitBlock time.Sleep(time.Second) } @@ -1440,7 +1440,7 @@ func TestMetaProcessor_CreateShardInfoShouldWorkHdrsAdded(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1464,7 +1464,7 @@ func TestMetaProcessor_CreateShardInfoShouldWorkHdrsAdded(t *testing.T) { pool.ShardHeaders().Put(hdrHash1, headers[0]) pool.ShardHeaders().Put(hdrHash11, headers[1]) - // header shard 1 + // hdr shard 1 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(1).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1488,7 +1488,7 @@ func TestMetaProcessor_CreateShardInfoShouldWorkHdrsAdded(t *testing.T) { pool.ShardHeaders().Put(hdrHash2, headers[2]) pool.ShardHeaders().Put(hdrHash22, headers[3]) - // header shard 2 + // hdr shard 2 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(2).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1608,7 +1608,7 @@ func TestMetaProcessor_CreateShardInfoEmptyBlockHDRRoundTooHigh(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1632,7 +1632,7 @@ func TestMetaProcessor_CreateShardInfoEmptyBlockHDRRoundTooHigh(t *testing.T) { pool.ShardHeaders().Put(hdrHash1, headers[0]) pool.ShardHeaders().Put(hdrHash11, headers[1]) - // header shard 1 + // hdr shard 1 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(1).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1656,7 +1656,7 @@ func TestMetaProcessor_CreateShardInfoEmptyBlockHDRRoundTooHigh(t *testing.T) { pool.ShardHeaders().Put(hdrHash2, headers[2]) pool.ShardHeaders().Put(hdrHash22, headers[3]) - // header shard 2 + // hdr shard 2 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(2).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1817,7 +1817,7 @@ func TestMetaProcessor_CreateLastNotarizedHdrs(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -1847,13 +1847,13 @@ func TestMetaProcessor_CreateLastNotarizedHdrs(t *testing.T) { shDataPrev := block.ShardData{ShardId: 0, HeaderHash: prevHash} metaHdr.ShardInfo = append(metaHdr.ShardInfo, shDataPrev) - // test header not in pool and defer called + // test hdr not in pool and defer called err := mp.SaveLastNotarizedHeader(metaHdr) assert.Equal(t, process.ErrMissingHeader, err) notarizedHdrs = mp.NotarizedHdrs() assert.Equal(t, firstNonce, mp.LastNotarizedHdrForShard(currHdr.ShardId).GetNonce()) - // wrong header type in pool and defer called + // wrong hdr type in pool and defer called pool.ShardHeaders().Put(currHash, metaHdr) pool.ShardHeaders().Put(prevHash, prevHdr) @@ -1911,7 +1911,7 @@ func TestMetaProcessor_CheckShardHeadersValidity(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -2131,7 +2131,7 @@ func TestMetaProcessor_CheckShardHeadersFinality(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -2245,7 +2245,7 @@ func TestMetaProcessor_IsHdrConstructionValid(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -2354,7 +2354,7 @@ func TestMetaProcessor_IsShardHeaderValidFinal(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, diff --git a/process/block/preprocess/basePreProcess.go b/process/block/preprocess/basePreProcess.go index b1355dc0f20..d3b07091c0b 100644 --- a/process/block/preprocess/basePreProcess.go +++ b/process/block/preprocess/basePreProcess.go @@ -163,9 +163,10 @@ func (bpp *basePreProcess) computeExistingAndMissing( currType block.Type, txPool dataRetriever.ShardedDataCacherNotifier, ) map[uint32][]*txsHashesInfo { + missingTxsForShard := make(map[uint32][]*txsHashesInfo, 0) - forBlock.mutTxsForBlock.Lock() + forBlock.mutTxsForBlock.Lock() for i := 0; i < len(body); i++ { miniBlock := body[i] if miniBlock.Type != currType { @@ -177,18 +178,19 @@ func (bpp *basePreProcess) computeExistingAndMissing( for j := 0; j < len(miniBlock.TxHashes); j++ { txHash := miniBlock.TxHashes[j] - tx, _ := process.GetTransactionHandlerFromPool( + tx, err := process.GetTransactionHandlerFromPool( miniBlock.SenderShardID, miniBlock.ReceiverShardID, txHash, txPool) - if tx == nil || tx.IsInterfaceNil() { + if err != nil { txHashes = append(txHashes, txHash) forBlock.missingTxs++ - } else { - forBlock.txHashAndInfo[string(txHash)] = &txInfo{tx: tx, txShardInfo: txShardInfo} + continue } + + forBlock.txHashAndInfo[string(txHash)] = &txInfo{tx: tx, txShardInfo: txShardInfo} } if len(txHashes) > 0 { @@ -196,7 +198,6 @@ func (bpp *basePreProcess) computeExistingAndMissing( &txsHashesInfo{txHashes: txHashes, receiverShardID: miniBlock.ReceiverShardID}) } } - forBlock.mutTxsForBlock.Unlock() return missingTxsForShard diff --git a/process/block/shardblock.go b/process/block/shardblock.go index d696b7931b5..b5b1848971b 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -20,6 +20,17 @@ import ( const maxCleanTime = time.Second +type hdrInfo struct { + hdr data.HeaderHandler +} + +type hdrForBlock struct { + missingHdrs uint32 + missingFinalHdrs uint32 + mutHdrsForBlock sync.RWMutex + hdrHashAndInfo map[string]*hdrInfo +} + // shardProcessor implements shardProcessor interface and actually it tries to execute block type shardProcessor struct { *baseProcessor @@ -31,10 +42,8 @@ type shardProcessor struct { mutUsedMetaHdrsHashes sync.Mutex usedMetaHdrsHashes map[uint64][][]byte - mutRequestedMetaHdrsHashes sync.RWMutex - requestedMetaHdrsHashes map[string]bool - currHighestMetaHdrNonce uint64 - allNeededMetaHdrsFound bool + hdrsForCurrBlock hdrForBlock + currHighestMetaHdrNonce uint64 processedMiniBlocks map[string]map[string]struct{} mutProcessedMiniBlocks sync.RWMutex @@ -120,7 +129,7 @@ func NewShardProcessor(arguments ArgShardProcessor) (*shardProcessor, error) { return nil, process.ErrNilTransactionPool } - sp.requestedMetaHdrsHashes = make(map[string]bool) + sp.hdrsForCurrBlock.hdrHashAndInfo = make(map[string]*hdrInfo) sp.usedMetaHdrsHashes = make(map[uint64][][]byte) sp.processedMiniBlocks = make(map[string]map[string]struct{}) @@ -132,7 +141,6 @@ func NewShardProcessor(arguments ArgShardProcessor) (*shardProcessor, error) { sp.onRequestHeaderHandler = arguments.RequestHandler.RequestHeader sp.metaBlockFinality = process.MetaBlockFinality - sp.allNeededMetaHdrsFound = true return &sp, nil } @@ -152,7 +160,7 @@ func (sp *shardProcessor) ProcessBlock( err := sp.checkBlockValidity(chainHandler, headerHandler, bodyHandler) if err != nil { if err == process.ErrBlockHashDoesNotMatch { - log.Info(fmt.Sprintf("requested missing shard header with hash %s for shard %d\n", + log.Info(fmt.Sprintf("requested missing shard hdr with hash %s for shard %d\n", core.ToB64(headerHandler.GetPrevHash()), headerHandler.GetShardID())) @@ -199,7 +207,7 @@ func (sp *shardProcessor) ProcessBlock( return err } - sp.txCoordinator.CreateBlockStarted() + sp.CreateBlockStarted() sp.txCoordinator.RequestBlockTransactions(body) requestedMetaHdrs, requestedFinalMetaHdrs := sp.requestMetaHeaders(header) @@ -215,13 +223,17 @@ func (sp *shardProcessor) ProcessBlock( if requestedMetaHdrs > 0 || requestedFinalMetaHdrs > 0 { log.Info(fmt.Sprintf("requested %d missing meta headers and %d final meta headers\n", requestedMetaHdrs, requestedFinalMetaHdrs)) err = sp.waitForMetaHdrHashes(haveTime()) - sp.mutRequestedMetaHdrsHashes.Lock() - sp.allNeededMetaHdrsFound = true - unreceivedMetaHdrs := len(sp.requestedMetaHdrsHashes) - sp.mutRequestedMetaHdrsHashes.Unlock() + + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() + missingHdrs := sp.hdrsForCurrBlock.missingHdrs + sp.hdrsForCurrBlock.missingHdrs = 0 + sp.hdrsForCurrBlock.missingFinalHdrs = 0 + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() + if requestedMetaHdrs > 0 { - log.Info(fmt.Sprintf("received %d missing meta headers\n", int(requestedMetaHdrs)-unreceivedMetaHdrs)) + log.Info(fmt.Sprintf("received %d missing meta headers\n", requestedMetaHdrs-missingHdrs)) } + if err != nil { return err } @@ -282,7 +294,7 @@ func (sp *shardProcessor) ProcessBlock( func (sp *shardProcessor) setMetaConsensusData(finalizedMetaBlocks []data.HeaderHandler) error { sp.specialAddressHandler.ClearMetaConsensusData() - // for every finalized metablock header, reward the metachain consensus group members with accounts in shard + // for every finalized metablock hdr, reward the metachain consensus group members with accounts in shard for _, metaBlock := range finalizedMetaBlocks { round := metaBlock.GetRound() epoch := metaBlock.GetEpoch() @@ -305,30 +317,30 @@ func (sp *shardProcessor) SetConsensusData(randomness []byte, round uint64, epoc // checkMetaHeadersValidity - checks if listed metaheaders are valid as construction func (sp *shardProcessor) checkMetaHeadersValidityAndFinality(header *block.Header) error { - metablockCache := sp.dataPool.MetaBlocks() - if metablockCache == nil { - return process.ErrNilMetaBlockPool - } - tmpNotedHdr, err := sp.getLastNotarizedHdr(sharding.MetachainShardId) if err != nil { return err } currAddedMetaHdrs := make([]*block.MetaBlock, 0) + + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() for _, metaHash := range header.MetaBlockHashes { - value, ok := metablockCache.Peek(metaHash) + value, ok := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaHash)] if !ok { + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return process.ErrNilMetaBlockHeader } - metaHdr, ok := value.(*block.MetaBlock) + metaHdr, ok := value.hdr.(*block.MetaBlock) if !ok { + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return process.ErrWrongTypeAssertion } currAddedMetaHdrs = append(currAddedMetaHdrs, metaHdr) } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() if len(currAddedMetaHdrs) == 0 { return nil @@ -373,7 +385,7 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error break } - // found a header with the next nonce + // found a hdr with the next nonce if tmpHdr.hdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { err = sp.isHdrConstructionValid(tmpHdr.hdr, lastVerifiedHdr) if err != nil { @@ -441,7 +453,7 @@ func (sp *shardProcessor) getFinalityAttestingHeaders( return orderedMetaBlocks, nil } -// check if header has the same miniblocks as presented in body +// check if hdr has the same miniblocks as presented in body func (sp *shardProcessor) checkHeaderBodyCorrelation(hdr *block.Header, body block.Body) error { mbHashesFromHdr := make(map[string]*block.MiniBlockHeader) for i := 0; i < len(hdr.MiniBlockHeaders); i++ { @@ -806,7 +818,7 @@ func (sp *shardProcessor) cleanTxsPools() { log.Info(fmt.Sprintf("Total txs removed from pools cleaner %d", sp.txsPoolsCleaner.NumRemovedTxs())) } -// getHighestHdrForOwnShardFromMetachain calculates the highest shard header notarized by metachain +// getHighestHdrForOwnShardFromMetachain calculates the highest shard hdr notarized by metachain func (sp *shardProcessor) getHighestHdrForOwnShardFromMetachain( processedHdrs []data.HeaderHandler, ) ([]data.HeaderHandler, [][]byte, error) { @@ -862,7 +874,7 @@ func (sp *shardProcessor) getHighestHdrForShardFromMetachain(shardId uint32, hdr if err != nil { go sp.onRequestHeaderHandler(shardInfo.ShardId, shardInfo.HeaderHash) - log.Info(fmt.Sprintf("requested missing shard header with hash %s for shard %d\n", + log.Info(fmt.Sprintf("requested missing shard hdr with hash %s for shard %d\n", core.ToB64(shardInfo.HeaderHash), shardInfo.ShardId)) @@ -898,24 +910,28 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) return nil, err } - for _, metaBlockKey := range header.MetaBlockHashes { - obj, ok := sp.dataPool.MetaBlocks().Peek(metaBlockKey) + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() + for _, metaBlockHash := range header.MetaBlockHashes { + value, ok := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] if !ok { + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return nil, process.ErrNilMetaBlockHeader } - metaBlock, ok := obj.(*block.MetaBlock) + metaBlock, ok := value.hdr.(*block.MetaBlock) if !ok { + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return nil, process.ErrWrongTypeAssertion } crossMiniBlockHashes := metaBlock.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) for key := range crossMiniBlockHashes { if usedMbs[key] { - sp.addProcessedMiniBlock(metaBlockKey, []byte(key)) + sp.addProcessedMiniBlock(metaBlockHash, []byte(key)) } } } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return processedMetaHeaders, nil } @@ -926,7 +942,7 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlocks( usedMetaBlockHashes [][]byte, ) ([]data.HeaderHandler, error) { if usedMiniBlocks == nil || usedMetaBlockHashes == nil { - // not an error, it can happen that no metablock header or no miniblock is used. + // not an error, it can happen that no metablock hdr or no miniblock is used. return make([]data.HeaderHandler, 0), nil } @@ -970,7 +986,7 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( return nil, nil, process.ErrWrongTypeAssertion } - log.Debug(fmt.Sprintf("meta header nonce: %d\n", metaBlock.Nonce)) + log.Debug(fmt.Sprintf("meta hdr nonce: %d\n", metaBlock.Nonce)) crossMiniBlockHashes := metaBlock.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) for hash := range crossMiniBlockHashes { @@ -988,7 +1004,7 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( delete(miniBlockHashes, key) } - log.Debug(fmt.Sprintf("cross mini blocks in meta header: %d\n", len(crossMiniBlockHashes))) + log.Debug(fmt.Sprintf("cross mini blocks in meta hdr: %d\n", len(crossMiniBlockHashes))) processedAll := true for key := range crossMiniBlockHashes { @@ -1104,38 +1120,38 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { core.ToB64(metaBlockHash), metaBlock.GetNonce())) - sp.mutRequestedMetaHdrsHashes.Lock() + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() - if !sp.allNeededMetaHdrsFound { - if sp.requestedMetaHdrsHashes[string(metaBlockHash)] { - delete(sp.requestedMetaHdrsHashes, string(metaBlockHash)) + if sp.hdrsForCurrBlock.missingHdrs > 0 || sp.hdrsForCurrBlock.missingFinalHdrs > 0 { + hdrInfoForHash := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] + if hdrInfoForHash != nil && (hdrInfoForHash.hdr == nil || hdrInfoForHash.hdr.IsInterfaceNil()) { + sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)].hdr = metaBlock + sp.hdrsForCurrBlock.missingHdrs-- if metaBlock.GetNonce() > sp.currHighestMetaHdrNonce { sp.currHighestMetaHdrNonce = metaBlock.GetNonce() } } - lenReqMetaHdrsHashes := len(sp.requestedMetaHdrsHashes) - areFinalAttestingHdrsInCache := false - if lenReqMetaHdrsHashes == 0 { - requestedBlockHeaders := sp.requestFinalMissingHeaders() - if requestedBlockHeaders == 0 { - log.Info(fmt.Sprintf("received all final meta headers\n")) - areFinalAttestingHdrsInCache = true + if sp.hdrsForCurrBlock.missingHdrs == 0 { + missingFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs + sp.hdrsForCurrBlock.missingFinalHdrs = sp.requestFinalMissingHeaders() + if sp.hdrsForCurrBlock.missingFinalHdrs == 0 { + log.Info(fmt.Sprintf("received %d missing final meta headers\n", missingFinalHdrs)) } else { - log.Info(fmt.Sprintf("requested %d missing final meta headers\n", requestedBlockHeaders)) + log.Info(fmt.Sprintf("requested %d missing final meta headers\n", sp.hdrsForCurrBlock.missingHdrs)) } } - sp.allNeededMetaHdrsFound = lenReqMetaHdrsHashes == 0 && areFinalAttestingHdrsInCache - - sp.mutRequestedMetaHdrsHashes.Unlock() + missingHdrs := sp.hdrsForCurrBlock.missingHdrs + missingFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - if lenReqMetaHdrsHashes == 0 && areFinalAttestingHdrsInCache { + if missingHdrs == 0 || missingFinalHdrs == 0 { sp.chRcvAllMetaHdrs <- true } } else { - sp.mutRequestedMetaHdrsHashes.Unlock() + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() } lastNotarizedHdr, err := sp.getLastNotarizedHdr(sharding.MetachainShardId) @@ -1153,7 +1169,7 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { } // requestFinalMissingHeaders requests the headers needed to accept the current selected headers for processing the -// current block. It requests the metaBlockFinality headers greater than the highest meta header related to the block +// current block. It requests the metaBlockFinality headers greater than the highest meta hdr related to the block // which should be processed func (sp *shardProcessor) requestFinalMissingHeaders() uint32 { requestedBlockHeaders := uint32(0) @@ -1162,14 +1178,18 @@ func (sp *shardProcessor) requestFinalMissingHeaders() uint32 { continue } - _, _, err := process.GetMetaHeaderFromPoolWithNonce( + metaBlock, metaBlockHash, err := process.GetMetaHeaderFromPoolWithNonce( i, sp.dataPool.MetaBlocks(), sp.dataPool.HeadersNonces()) + if err != nil { requestedBlockHeaders++ go sp.onRequestHeaderHandlerByNonce(sharding.MetachainShardId, i) + continue } + + sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] = &hdrInfo{hdr: metaBlock} } return requestedBlockHeaders @@ -1178,57 +1198,52 @@ func (sp *shardProcessor) requestFinalMissingHeaders() uint32 { func (sp *shardProcessor) requestMetaHeaders(header *block.Header) (uint32, uint32) { _ = process.EmptyChannel(sp.chRcvAllMetaHdrs) - sp.mutRequestedMetaHdrsHashes.Lock() - - sp.requestedMetaHdrsHashes = make(map[string]bool) - sp.allNeededMetaHdrsFound = true - if len(header.MetaBlockHashes) == 0 { - sp.mutRequestedMetaHdrsHashes.Unlock() return 0, 0 } - missingHeaderHashes := sp.computeMissingHeaders(header) + missingHeaderHashes := sp.computeMissingAndExistingMetaHeaders(header) - requestedBlockHeaders := uint32(0) + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() for _, hash := range missingHeaderHashes { - requestedBlockHeaders++ - sp.requestedMetaHdrsHashes[string(hash)] = true + sp.hdrsForCurrBlock.hdrHashAndInfo[string(hash)] = &hdrInfo{hdr: nil} go sp.onRequestHeaderHandler(sharding.MetachainShardId, hash) } - requestedFinalBlockHeaders := uint32(0) - if requestedBlockHeaders > 0 { - sp.allNeededMetaHdrsFound = false - } else { - requestedFinalBlockHeaders = sp.requestFinalMissingHeaders() - if requestedFinalBlockHeaders > 0 { - sp.allNeededMetaHdrsFound = false - } + if sp.hdrsForCurrBlock.missingHdrs == 0 { + sp.hdrsForCurrBlock.missingFinalHdrs = sp.requestFinalMissingHeaders() } - sp.mutRequestedMetaHdrsHashes.Unlock() + requestedHdrs := sp.hdrsForCurrBlock.missingHdrs + requestedFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - return requestedBlockHeaders, requestedFinalBlockHeaders + return requestedHdrs, requestedFinalHdrs } -func (sp *shardProcessor) computeMissingHeaders(header *block.Header) [][]byte { +func (sp *shardProcessor) computeMissingAndExistingMetaHeaders(header *block.Header) [][]byte { missingHeaders := make([][]byte, 0) sp.currHighestMetaHdrNonce = uint64(0) + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() for i := 0; i < len(header.MetaBlockHashes); i++ { hdr, err := process.GetMetaHeaderFromPool( header.MetaBlockHashes[i], sp.dataPool.MetaBlocks()) + if err != nil { missingHeaders = append(missingHeaders, header.MetaBlockHashes[i]) + sp.hdrsForCurrBlock.missingHdrs++ continue } + sp.hdrsForCurrBlock.hdrHashAndInfo[string(header.MetaBlockHashes[i])] = &hdrInfo{hdr: hdr} + if hdr.Nonce > sp.currHighestMetaHdrNonce { sp.currHighestMetaHdrNonce = hdr.Nonce } } + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() return missingHeaders } @@ -1250,24 +1265,21 @@ func (sp *shardProcessor) verifyCrossShardMiniBlockDstMe(hdr *block.Header) erro } func (sp *shardProcessor) getAllMiniBlockDstMeFromMeta(round uint64, metaHashes [][]byte) (map[string][]byte, error) { - metaBlockCache := sp.dataPool.MetaBlocks() - if metaBlockCache == nil { - return nil, process.ErrNilMetaBlockPool - } - lastHdr, err := sp.getLastNotarizedHdr(sharding.MetachainShardId) if err != nil { return nil, err } mMiniBlockMeta := make(map[string][]byte) + + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() for _, metaHash := range metaHashes { - val, _ := metaBlockCache.Peek(metaHash) - if val == nil { + value, ok := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaHash)] + if !ok { continue } - hdr, ok := val.(*block.MetaBlock) + hdr, ok := value.hdr.(*block.MetaBlock) if !ok { continue } @@ -1287,6 +1299,7 @@ func (sp *shardProcessor) getAllMiniBlockDstMeFromMeta(round uint64, metaHashes mMiniBlockMeta[mbHash] = metaHash } } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return mMiniBlockMeta, nil } @@ -1354,7 +1367,7 @@ func (sp *shardProcessor) isMetaHeaderFinal(currHdr data.HeaderHandler, sortedHd return true } - // found a header with the next nonce + // found a hdr with the next nonce tmpHdr := sortedHdrs[i].hdr if tmpHdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { err := sp.isHdrConstructionValid(tmpHdr, lastVerifiedHdr) @@ -1374,7 +1387,7 @@ func (sp *shardProcessor) isMetaHeaderFinal(currHdr data.HeaderHandler, sortedHd return false } -// full verification through metachain header +// full verification through metachain hdr func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( noShards uint32, maxItemsInBlock uint32, @@ -1422,7 +1435,7 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( itemsAddedInHeader := uint32(len(usedMetaHdrsHashes) + len(miniBlocks)) if itemsAddedInHeader >= maxItemsInBlock { - log.Info(fmt.Sprintf("%d max records allowed to be added in shard header has been reached\n", maxItemsInBlock)) + log.Info(fmt.Sprintf("%d max records allowed to be added in shard hdr has been reached\n", maxItemsInBlock)) break } @@ -1551,9 +1564,9 @@ func (sp *shardProcessor) createMiniBlocks( return miniBlocks, nil } -// CreateBlockHeader creates a miniblock header list given a block body +// CreateBlockHeader creates a miniblock hdr list given a block body func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round uint64, haveTime func() bool) (data.HeaderHandler, error) { - log.Debug(fmt.Sprintf("started creating block header in round %d\n", round)) + log.Debug(fmt.Sprintf("started creating block hdr in round %d\n", round)) header := &block.Header{ MiniBlockHeaders: make([]block.MiniBlockHeader, 0), RootHash: sp.getRootHash(), @@ -1674,7 +1687,7 @@ func (sp *shardProcessor) DecodeBlockBody(dta []byte) data.BodyHandler { return body } -// DecodeBlockHeader method decodes block header from a given byte array +// DecodeBlockHeader method decodes block hdr from a given byte array func (sp *shardProcessor) DecodeBlockHeader(dta []byte) data.HeaderHandler { if dta == nil { return nil @@ -1752,3 +1765,13 @@ func (sp *shardProcessor) isMiniBlockProcessed(metaBlockHash []byte, miniBlockHa return isProcessed } + +func (sp *shardProcessor) CreateBlockStarted() { + sp.txCoordinator.CreateBlockStarted() + + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() + sp.hdrsForCurrBlock.missingHdrs = 0 + sp.hdrsForCurrBlock.missingFinalHdrs = 0 + sp.hdrsForCurrBlock.hdrHashAndInfo = make(map[string]*hdrInfo) + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() +} diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index 3cda2c559f5..7aa5d722264 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -1755,7 +1755,7 @@ func TestShardProcessor_CommitBlockNoTxInPoolShouldErr(t *testing.T) { txHash := []byte("txHash") rootHash := []byte("root hash") - hdrHash := []byte("header hash") + hdrHash := []byte("hdr hash") hdr := &block.Header{ Nonce: 1, Round: 1, @@ -1836,7 +1836,7 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { txHash := []byte("tx_hash1") rootHash := []byte("root hash") - hdrHash := []byte("header hash") + hdrHash := []byte("hdr hash") randSeed := []byte("rand seed") prevHdr := &block.Header{ @@ -1927,7 +1927,7 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.Nil(t, err) assert.True(t, forkDetectorAddCalled) assert.Equal(t, hdrHash, blkc.GetCurrentBlockHeaderHash()) - //this should sleep as there is an async call to display current header and block in CommitBlock + //this should sleep as there is an async call to display current hdr and block in CommitBlock time.Sleep(time.Second) } @@ -1937,7 +1937,7 @@ func TestShardProcessor_CommitBlockCallsIndexerMethods(t *testing.T) { txHash := []byte("tx_hash1") rootHash := []byte("root hash") - hdrHash := []byte("header hash") + hdrHash := []byte("hdr hash") randSeed := []byte("rand seed") prevHdr := &block.Header{ @@ -3221,7 +3221,7 @@ func TestShardProcessor_IsHdrConstructionValid(t *testing.T) { //put the existing headers inside datapool - //header shard 0 + //hdr shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, @@ -3338,7 +3338,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { RandSeed: prevRandSeed} notarizedHdrs[sharding.MetachainShardId] = append(notarizedHdrs[sharding.MetachainShardId], lastHdr) - //header shard 0 + //hdr shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, @@ -3363,7 +3363,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { mbHeaders := make([]block.MiniBlockHeader, 0) blockHeader := &block.Header{} - // test header not in pool and defer called + // test hdr not in pool and defer called processedMetaHdrs, err := sp.GetProcessedMetaBlocksFromHeader(blockHeader) assert.Nil(t, err) @@ -3378,7 +3378,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { assert.Equal(t, firstNonce, sp.LastNotarizedHdrForShard(sharding.MetachainShardId).GetNonce()) assert.Equal(t, 0, len(processedMetaHdrs)) - // wrong header type in pool and defer called + // wrong hdr type in pool and defer called dataPool.MetaBlocks().Put(currHash, shardHdr) hashes := make([][]byte, 0) @@ -3533,7 +3533,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNotAllMBFinished(t *tes miniBlocks := make([]block.MiniBlock, 0) miniBlocks = append(miniBlocks, miniblock1, miniblock2) - //header shard 0 + //hdr shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, @@ -3673,7 +3673,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrAllMBFinished(t *testin miniBlocks := make([]block.MiniBlock, 0) miniBlocks = append(miniBlocks, miniblock1, miniblock2) - //header shard 0 + //hdr shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, From 245f03bf93e51174d0357a67cf2ce1b22b4e7b89 Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Wed, 2 Oct 2019 17:23:55 +0300 Subject: [PATCH 03/10] * Changed the approach for requested/received missing meta headers --- process/block/shardblock.go | 172 ++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 87 deletions(-) diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 1b5e0be5c30..766ef1ad931 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -20,6 +20,11 @@ import ( const maxCleanTime = time.Second +type nonceAndHashInfo struct { + hash []byte + nonce uint64 +} + type hdrInfo struct { hdr data.HeaderHandler } @@ -38,9 +43,9 @@ type shardProcessor struct { blocksTracker process.BlocksTracker metaBlockFinality int - chRcvAllMetaHdrs chan bool - mutUsedMetaHdrsHashes sync.Mutex - usedMetaHdrsHashes map[uint64][][]byte + chRcvAllMetaHdrs chan bool + //mutUsedMetaHdrsHashes sync.Mutex + //usedMetaHdrsHashes map[uint64][][]byte hdrsForCurrBlock hdrForBlock currHighestMetaHdrNonce uint64 @@ -130,7 +135,6 @@ func NewShardProcessor(arguments ArgShardProcessor) (*shardProcessor, error) { } sp.hdrsForCurrBlock.hdrHashAndInfo = make(map[string]*hdrInfo) - sp.usedMetaHdrsHashes = make(map[uint64][][]byte) sp.processedMiniBlocks = make(map[string]map[string]struct{}) metaBlockPool := sp.dataPool.MetaBlocks() @@ -263,7 +267,7 @@ func (sp *shardProcessor) ProcessBlock( } }() - processedMetaHdrs, err := sp.getProcessedMetaBlocksFromMiniBlocks(body, header.MetaBlockHashes) + processedMetaHdrs, err := sp.getProcessedMetaBlocksFromMiniBlocks(body) if err != nil { return err } @@ -632,7 +636,7 @@ func (sp *shardProcessor) restoreMetaBlockIntoPool(miniBlockHashes map[string]ui // as long as the transactions limit for the block has not been reached and there is still time to add transactions func (sp *shardProcessor) CreateBlockBody(round uint64, haveTime func() bool) (data.BodyHandler, error) { log.Debug(fmt.Sprintf("started creating block body in round %d\n", round)) - sp.txCoordinator.CreateBlockStarted() + sp.CreateBlockStarted() sp.blockSizeThrottler.ComputeMaxItems() miniBlocks, err := sp.createMiniBlocks(sp.shardCoordinator.NumberOfShards(), sp.blockSizeThrottler.MaxItemsToAdd(), round, haveTime) @@ -907,29 +911,23 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) log.Debug(fmt.Sprintf("cross mini blocks in body: %d\n", len(miniBlockHashes))) - processedMetaHeaders, usedMbs, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes, header.MetaBlockHashes) + processedMetaHeaders, processedCrossMiniBlocksHashes, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) if err != nil { return nil, err } sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() - for _, metaBlockHash := range header.MetaBlockHashes { - value, ok := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] - if !ok { - sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return nil, process.ErrNilMetaBlockHeader - } - - metaBlock, ok := value.hdr.(*block.MetaBlock) + for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + metaBlock, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return nil, process.ErrWrongTypeAssertion } crossMiniBlockHashes := metaBlock.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) - for key := range crossMiniBlockHashes { - if usedMbs[key] { - sp.addProcessedMiniBlock(metaBlockHash, []byte(key)) + for hash := range crossMiniBlockHashes { + if processedCrossMiniBlocksHashes[hash] { + sp.addProcessedMiniBlock([]byte(metaBlockHash), []byte(hash)) } } } @@ -941,50 +939,52 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) // getProcessedMetaBlocks returns all the meta blocks fully processed func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlocks( usedMiniBlocks []*block.MiniBlock, - usedMetaBlockHashes [][]byte, ) ([]data.HeaderHandler, error) { - if usedMiniBlocks == nil || usedMetaBlockHashes == nil { + + nrMiniBlocksUsed := len(usedMiniBlocks) + + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() + nrMetaBlocksUsed := len(sp.hdrsForCurrBlock.hdrHashAndInfo) + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() + + if nrMiniBlocksUsed == 0 || nrMetaBlocksUsed == 0 { // not an error, it can happen that no metablock hdr or no miniblock is used. return make([]data.HeaderHandler, 0), nil } miniBlockHashes := make(map[int][]byte, 0) for i := 0; i < len(usedMiniBlocks); i++ { - miniBlock := usedMiniBlocks[i] - if miniBlock.SenderShardID == sp.shardCoordinator.SelfId() { + if usedMiniBlocks[i].SenderShardID == sp.shardCoordinator.SelfId() { continue } - mbHash, err := core.CalculateHash(sp.marshalizer, sp.hasher, miniBlock) + miniBlockHash, err := core.CalculateHash(sp.marshalizer, sp.hasher, usedMiniBlocks[i]) if err != nil { log.Debug(err.Error()) continue } - miniBlockHashes[i] = mbHash + + miniBlockHashes[i] = miniBlockHash } log.Debug(fmt.Sprintf("cross mini blocks in body: %d\n", len(miniBlockHashes))) - processedMetaBlocks, _, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes, usedMetaBlockHashes) + processedMetaBlocks, _, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) return processedMetaBlocks, err } func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( miniBlockHashes map[int][]byte, - usedMetaBlockHashes [][]byte, ) ([]data.HeaderHandler, map[string]bool, error) { processedMetaHdrs := make([]data.HeaderHandler, 0) - processedMBs := make(map[string]bool) - - for _, metaBlockKey := range usedMetaBlockHashes { - obj, _ := sp.dataPool.MetaBlocks().Peek(metaBlockKey) - if obj == nil { - return nil, nil, process.ErrNilMetaBlockHeader - } + processedCrossMiniBlocksHashes := make(map[string]bool) - metaBlock, ok := obj.(*block.MetaBlock) + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() + for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + metaBlock, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return nil, nil, process.ErrWrongTypeAssertion } @@ -992,16 +992,16 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( crossMiniBlockHashes := metaBlock.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) for hash := range crossMiniBlockHashes { - processedMBs[hash] = sp.isMiniBlockProcessed(metaBlockKey, []byte(hash)) + processedCrossMiniBlocksHashes[hash] = sp.isMiniBlockProcessed([]byte(metaBlockHash), []byte(hash)) } - for key := range miniBlockHashes { - _, ok = crossMiniBlockHashes[string(miniBlockHashes[key])] + for key, miniBlockHash := range miniBlockHashes { + _, ok = crossMiniBlockHashes[string(miniBlockHash)] if !ok { continue } - processedMBs[string(miniBlockHashes[key])] = true + processedCrossMiniBlocksHashes[string(miniBlockHash)] = true delete(miniBlockHashes, key) } @@ -1009,8 +1009,8 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( log.Debug(fmt.Sprintf("cross mini blocks in meta hdr: %d\n", len(crossMiniBlockHashes))) processedAll := true - for key := range crossMiniBlockHashes { - if !processedMBs[key] { + for hash := range crossMiniBlockHashes { + if !processedCrossMiniBlocksHashes[hash] { processedAll = false break } @@ -1020,8 +1020,9 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( processedMetaHdrs = append(processedMetaHdrs, metaBlock) } } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return processedMetaHdrs, processedMBs, nil + return processedMetaHdrs, processedCrossMiniBlocksHashes, nil } func (sp *shardProcessor) removeProcessedMetaBlocksFromPool(processedMetaHdrs []data.HeaderHandler) error { @@ -1395,47 +1396,33 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( maxItemsInBlock uint32, round uint64, haveTime func() bool, -) (block.MiniBlockSlice, [][]byte, uint32, error) { - - metaBlockCache := sp.dataPool.MetaBlocks() - if metaBlockCache == nil || metaBlockCache.IsInterfaceNil() { - return nil, nil, 0, process.ErrNilMetaBlockPool - } - - miniBlockCache := sp.dataPool.MiniBlocks() - if miniBlockCache == nil || miniBlockCache.IsInterfaceNil() { - return nil, nil, 0, process.ErrNilMiniBlockPool - } - - txPool := sp.dataPool.Transactions() - if txPool == nil || txPool.IsInterfaceNil() { - return nil, nil, 0, process.ErrNilTransactionPool - } +) (block.MiniBlockSlice, uint32, uint32, error) { miniBlocks := make(block.MiniBlockSlice, 0) - nrTxAdded := uint32(0) + txsAdded := uint32(0) + hdrsAdded := uint32(0) orderedMetaBlocks, err := sp.getOrderedMetaBlocks(round) if err != nil { - return nil, nil, 0, err + return nil, 0, 0, err } log.Info(fmt.Sprintf("meta blocks ordered: %d\n", len(orderedMetaBlocks))) lastMetaHdr, err := sp.getLastNotarizedHdr(sharding.MetachainShardId) if err != nil { - return nil, nil, 0, err + return nil, 0, 0, err } // do processing in order - usedMetaHdrsHashes := make([][]byte, 0) + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() for i := 0; i < len(orderedMetaBlocks); i++ { if !haveTime() { - log.Info(fmt.Sprintf("time is up after putting %d cross txs with destination to current shard\n", nrTxAdded)) + log.Info(fmt.Sprintf("time is up after putting %d cross txs with destination to current shard\n", txsAdded)) break } - itemsAddedInHeader := uint32(len(usedMetaHdrsHashes) + len(miniBlocks)) + itemsAddedInHeader := uint32(len(sp.hdrsForCurrBlock.hdrHashAndInfo) + len(miniBlocks)) if itemsAddedInHeader >= maxItemsInBlock { log.Info(fmt.Sprintf("%d max records allowed to be added in shard hdr has been reached\n", maxItemsInBlock)) break @@ -1457,12 +1444,13 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( } if len(hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId())) == 0 { - usedMetaHdrsHashes = append(usedMetaHdrsHashes, orderedMetaBlocks[i].hash) + sp.hdrsForCurrBlock.hdrHashAndInfo[string(orderedMetaBlocks[i].hash)] = &hdrInfo{hdr: hdr} + hdrsAdded++ lastMetaHdr = hdr continue } - itemsAddedInBody := nrTxAdded + itemsAddedInBody := txsAdded if itemsAddedInBody >= maxItemsInBlock { continue } @@ -1482,10 +1470,11 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( // all txs processed, add to processed miniblocks miniBlocks = append(miniBlocks, currMBProcessed...) - nrTxAdded = nrTxAdded + currTxsAdded + txsAdded = txsAdded + currTxsAdded if currTxsAdded > 0 { - usedMetaHdrsHashes = append(usedMetaHdrsHashes, orderedMetaBlocks[i].hash) + sp.hdrsForCurrBlock.hdrHashAndInfo[string(orderedMetaBlocks[i].hash)] = &hdrInfo{hdr: hdr} + hdrsAdded++ } if !hdrProcessFinished { @@ -1495,12 +1484,9 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( lastMetaHdr = hdr } } + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - sp.mutUsedMetaHdrsHashes.Lock() - sp.usedMetaHdrsHashes[round] = usedMetaHdrsHashes - sp.mutUsedMetaHdrsHashes.Unlock() - - return miniBlocks, usedMetaHdrsHashes, nrTxAdded, nil + return miniBlocks, txsAdded, hdrsAdded, nil } func (sp *shardProcessor) createMiniBlocks( @@ -1526,12 +1512,12 @@ func (sp *shardProcessor) createMiniBlocks( return nil, process.ErrNilTransactionPool } - destMeMiniBlocks, usedMetaHdrsHashes, txs, err := sp.createAndProcessCrossMiniBlocksDstMe(noShards, maxItemsInBlock, round, haveTime) + destMeMiniBlocks, txs, hdrs, err := sp.createAndProcessCrossMiniBlocksDstMe(noShards, maxItemsInBlock, round, haveTime) if err != nil { log.Info(err.Error()) } - processedMetaHdrs, errNotCritical := sp.getProcessedMetaBlocksFromMiniBlocks(destMeMiniBlocks, usedMetaHdrsHashes) + processedMetaHdrs, errNotCritical := sp.getProcessedMetaBlocksFromMiniBlocks(destMeMiniBlocks) if errNotCritical != nil { log.Debug(errNotCritical.Error()) } @@ -1548,7 +1534,7 @@ func (sp *shardProcessor) createMiniBlocks( } maxTxSpaceRemained := int32(maxItemsInBlock) - int32(txs) - maxMbSpaceRemained := int32(maxItemsInBlock) - int32(len(destMeMiniBlocks)) - int32(len(usedMetaHdrsHashes)) + maxMbSpaceRemained := int32(maxItemsInBlock) - int32(len(destMeMiniBlocks)) - int32(hdrs) if maxTxSpaceRemained > 0 && maxMbSpaceRemained > 0 { mbFromMe := sp.txCoordinator.CreateMbsAndProcessTransactionsFromMe( @@ -1569,6 +1555,7 @@ func (sp *shardProcessor) createMiniBlocks( // CreateBlockHeader creates a miniblock hdr list given a block body func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round uint64, haveTime func() bool) (data.HeaderHandler, error) { log.Debug(fmt.Sprintf("started creating block hdr in round %d\n", round)) + header := &block.Header{ MiniBlockHeaders: make([]block.MiniBlockHeader, 0), RootHash: sp.getRootHash(), @@ -1590,20 +1577,20 @@ func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round return nil, process.ErrWrongTypeAssertion } - mbLen := len(body) totalTxCount := 0 - miniBlockHeaders := make([]block.MiniBlockHeader, mbLen) - for i := 0; i < mbLen; i++ { + miniBlockHeaders := make([]block.MiniBlockHeader, len(body)) + + for i := 0; i < len(body); i++ { txCount := len(body[i].TxHashes) totalTxCount += txCount - mbBytes, err := sp.marshalizer.Marshal(body[i]) + + miniBlockHash, err := core.CalculateHash(sp.marshalizer, sp.hasher, body[i]) if err != nil { return nil, err } - mbHash := sp.hasher.Compute(string(mbBytes)) miniBlockHeaders[i] = block.MiniBlockHeader{ - Hash: mbHash, + Hash: miniBlockHash, SenderShardID: body[i].SenderShardID, ReceiverShardID: body[i].ReceiverShardID, TxCount: uint32(txCount), @@ -1615,16 +1602,27 @@ func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round header.TxCount = uint32(totalTxCount) sp.appStatusHandler.SetUInt64Value(core.MetricNumTxInBlock, uint64(totalTxCount)) - sp.appStatusHandler.SetUInt64Value(core.MetricNumMiniBlocks, uint64(mbLen)) + sp.appStatusHandler.SetUInt64Value(core.MetricNumMiniBlocks, uint64(len(body))) + + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() + usedMetaHdrsInfo := make([]*nonceAndHashInfo, 0) + for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + usedMetaHdrsInfo = append(usedMetaHdrsInfo, &nonceAndHashInfo{nonce: hdrInfo.hdr.GetNonce(), hash: []byte(metaBlockHash)}) + } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - sp.mutUsedMetaHdrsHashes.Lock() + if len(usedMetaHdrsInfo) > 1 { + sort.Slice(usedMetaHdrsInfo, func(i, j int) bool { + return usedMetaHdrsInfo[i].nonce < usedMetaHdrsInfo[j].nonce + }) + } - if usedMetaHdrsHashes, ok := sp.usedMetaHdrsHashes[round]; ok { - header.MetaBlockHashes = usedMetaHdrsHashes - delete(sp.usedMetaHdrsHashes, round) + usedMetaHdrsHashes := make([][]byte, len(usedMetaHdrsInfo)) + for i := 0; i < len(usedMetaHdrsInfo); i++ { + usedMetaHdrsHashes[i] = usedMetaHdrsInfo[i].hash } - sp.mutUsedMetaHdrsHashes.Unlock() + header.MetaBlockHashes = usedMetaHdrsHashes sp.blockSizeThrottler.Add( round, From d12bd69052a1558bc7af3e432838a260a8f13154 Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Wed, 2 Oct 2019 20:27:06 +0300 Subject: [PATCH 04/10] * Added usedInBlock flag to differentiate requested missing headers and requested missing finals headers --- process/block/export_test.go | 2 +- process/block/shardblock.go | 121 +++++++++++++++++-------------- process/block/shardblock_test.go | 4 +- 3 files changed, 69 insertions(+), 58 deletions(-) diff --git a/process/block/export_test.go b/process/block/export_test.go index 196de84e15b..ce15ee1afd5 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -263,7 +263,7 @@ func (sp *shardProcessor) CreateAndProcessCrossMiniBlocksDstMe( maxItemsInBlock uint32, round uint64, haveTime func() bool, -) (block.MiniBlockSlice, [][]byte, uint32, error) { +) (block.MiniBlockSlice, uint32, uint32, error) { return sp.createAndProcessCrossMiniBlocksDstMe(noShards, maxItemsInBlock, round, haveTime) } diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 766ef1ad931..1f604fa7abd 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -26,7 +26,8 @@ type nonceAndHashInfo struct { } type hdrInfo struct { - hdr data.HeaderHandler + usedInBlock bool + hdr data.HeaderHandler } type hdrForBlock struct { @@ -251,7 +252,7 @@ func (sp *shardProcessor) ProcessBlock( go sp.checkAndRequestIfMetaHeadersMissing(header.Round) }() - err = sp.checkMetaHeadersValidityAndFinality(header) + err = sp.checkMetaHeadersValidityAndFinality() if err != nil { return err } @@ -320,7 +321,7 @@ func (sp *shardProcessor) SetConsensusData(randomness []byte, round uint64, epoc } // checkMetaHeadersValidity - checks if listed metaheaders are valid as construction -func (sp *shardProcessor) checkMetaHeadersValidityAndFinality(header *block.Header) error { +func (sp *shardProcessor) checkMetaHeadersValidityAndFinality() error { tmpNotedHdr, err := sp.getLastNotarizedHdr(sharding.MetachainShardId) if err != nil { return err @@ -329,14 +330,12 @@ func (sp *shardProcessor) checkMetaHeadersValidityAndFinality(header *block.Head currAddedMetaHdrs := make([]*block.MetaBlock, 0) sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() - for _, metaHash := range header.MetaBlockHashes { - value, ok := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaHash)] - if !ok { - sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return process.ErrNilMetaBlockHeader + for _, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if !hdrInfo.usedInBlock { + continue } - metaHdr, ok := value.hdr.(*block.MetaBlock) + metaHdr, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() return process.ErrWrongTypeAssertion @@ -350,15 +349,18 @@ func (sp *shardProcessor) checkMetaHeadersValidityAndFinality(header *block.Head return nil } - sort.Slice(currAddedMetaHdrs, func(i, j int) bool { - return currAddedMetaHdrs[i].Nonce < currAddedMetaHdrs[j].Nonce - }) + if len(currAddedMetaHdrs) > 1 { + sort.Slice(currAddedMetaHdrs, func(i, j int) bool { + return currAddedMetaHdrs[i].Nonce < currAddedMetaHdrs[j].Nonce + }) + } for _, metaHdr := range currAddedMetaHdrs { err = sp.isHdrConstructionValid(metaHdr, tmpNotedHdr) if err != nil { return err } + tmpNotedHdr = metaHdr } @@ -918,6 +920,10 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if !hdrInfo.usedInBlock { + continue + } + metaBlock, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() @@ -982,6 +988,10 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if !hdrInfo.usedInBlock { + continue + } + metaBlock, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() @@ -1094,34 +1104,34 @@ func (sp *shardProcessor) removeProcessedMetaBlocksFromPool(processedMetaHdrs [] // upon receiving, it parses the new metablock and requests miniblocks and transactions // which destination is the current shard func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { - metaBlksCache := sp.dataPool.MetaBlocks() - if metaBlksCache == nil { - return - } - - metaHdrsNoncesCache := sp.dataPool.HeadersNonces() - if metaHdrsNoncesCache == nil && sp.metaBlockFinality > 0 { + metaBlockPool := sp.dataPool.MetaBlocks() + if metaBlockPool == nil { return } - miniBlksCache := sp.dataPool.MiniBlocks() - if miniBlksCache == nil || miniBlksCache.IsInterfaceNil() { - return - } + //metaHdrsNoncesCache := sp.dataPool.HeadersNonces() + //if metaHdrsNoncesCache == nil && sp.metaBlockFinality > 0 { + // return + //} + // + //miniBlksCache := sp.dataPool.MiniBlocks() + //if miniBlksCache == nil || miniBlksCache.IsInterfaceNil() { + // return + //} - obj, ok := metaBlksCache.Peek(metaBlockHash) + obj, ok := metaBlockPool.Peek(metaBlockHash) if !ok { return } - metaBlock, ok := obj.(data.HeaderHandler) + metaBlock, ok := obj.(*block.MetaBlock) if !ok { return } log.Debug(fmt.Sprintf("received metablock with hash %s and nonce %d from network\n", core.ToB64(metaBlockHash), - metaBlock.GetNonce())) + metaBlock.Nonce)) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() @@ -1131,8 +1141,8 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)].hdr = metaBlock sp.hdrsForCurrBlock.missingHdrs-- - if metaBlock.GetNonce() > sp.currHighestMetaHdrNonce { - sp.currHighestMetaHdrNonce = metaBlock.GetNonce() + if metaBlock.Nonce > sp.currHighestMetaHdrNonce { + sp.currHighestMetaHdrNonce = metaBlock.Nonce } } @@ -1150,7 +1160,7 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { missingFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - if missingHdrs == 0 || missingFinalHdrs == 0 { + if missingHdrs == 0 && missingFinalHdrs == 0 { sp.chRcvAllMetaHdrs <- true } } else { @@ -1192,7 +1202,7 @@ func (sp *shardProcessor) requestFinalMissingHeaders() uint32 { continue } - sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] = &hdrInfo{hdr: metaBlock} + sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] = &hdrInfo{hdr: metaBlock, usedInBlock: false} } return requestedBlockHeaders @@ -1205,11 +1215,11 @@ func (sp *shardProcessor) requestMetaHeaders(header *block.Header) (uint32, uint return 0, 0 } - missingHeaderHashes := sp.computeMissingAndExistingMetaHeaders(header) + missingHeadersHashes := sp.computeMissingAndExistingMetaHeaders(header) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() - for _, hash := range missingHeaderHashes { - sp.hdrsForCurrBlock.hdrHashAndInfo[string(hash)] = &hdrInfo{hdr: nil} + for _, hash := range missingHeadersHashes { + sp.hdrsForCurrBlock.hdrHashAndInfo[string(hash)] = &hdrInfo{hdr: nil, usedInBlock: true} go sp.onRequestHeaderHandler(sharding.MetachainShardId, hash) } @@ -1225,7 +1235,7 @@ func (sp *shardProcessor) requestMetaHeaders(header *block.Header) (uint32, uint } func (sp *shardProcessor) computeMissingAndExistingMetaHeaders(header *block.Header) [][]byte { - missingHeaders := make([][]byte, 0) + missingHeadersHashes := make([][]byte, 0) sp.currHighestMetaHdrNonce = uint64(0) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() @@ -1235,12 +1245,12 @@ func (sp *shardProcessor) computeMissingAndExistingMetaHeaders(header *block.Hea sp.dataPool.MetaBlocks()) if err != nil { - missingHeaders = append(missingHeaders, header.MetaBlockHashes[i]) + missingHeadersHashes = append(missingHeadersHashes, header.MetaBlockHashes[i]) sp.hdrsForCurrBlock.missingHdrs++ continue } - sp.hdrsForCurrBlock.hdrHashAndInfo[string(header.MetaBlockHashes[i])] = &hdrInfo{hdr: hdr} + sp.hdrsForCurrBlock.hdrHashAndInfo[string(header.MetaBlockHashes[i])] = &hdrInfo{hdr: hdr, usedInBlock: true} if hdr.Nonce > sp.currHighestMetaHdrNonce { sp.currHighestMetaHdrNonce = hdr.Nonce @@ -1248,18 +1258,18 @@ func (sp *shardProcessor) computeMissingAndExistingMetaHeaders(header *block.Hea } sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - return missingHeaders + return missingHeadersHashes } func (sp *shardProcessor) verifyCrossShardMiniBlockDstMe(hdr *block.Header) error { - mMiniBlockMeta, err := sp.getAllMiniBlockDstMeFromMeta(hdr.Round, hdr.MetaBlockHashes) + miniBlockMetaHashes, err := sp.getAllMiniBlockDstMeFromMeta(hdr.Round) if err != nil { return err } - miniBlockDstMe := hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) - for mbHash := range miniBlockDstMe { - if _, ok := mMiniBlockMeta[mbHash]; !ok { + crossMiniBlockHashes := hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) + for hash := range crossMiniBlockHashes { + if _, ok := miniBlockMetaHashes[hash]; !ok { return process.ErrCrossShardMBWithoutConfirmationFromMeta } } @@ -1267,26 +1277,23 @@ func (sp *shardProcessor) verifyCrossShardMiniBlockDstMe(hdr *block.Header) erro return nil } -func (sp *shardProcessor) getAllMiniBlockDstMeFromMeta(round uint64, metaHashes [][]byte) (map[string][]byte, error) { +func (sp *shardProcessor) getAllMiniBlockDstMeFromMeta(round uint64) (map[string][]byte, error) { lastHdr, err := sp.getLastNotarizedHdr(sharding.MetachainShardId) if err != nil { return nil, err } - mMiniBlockMeta := make(map[string][]byte) + miniBlockMetaHashes := make(map[string][]byte) sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() - for _, metaHash := range metaHashes { - value, ok := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaHash)] - if !ok { + for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if !hdrInfo.usedInBlock { continue } - - hdr, ok := value.hdr.(*block.MetaBlock) + hdr, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { continue } - if hdr.GetRound() > round { continue } @@ -1297,14 +1304,14 @@ func (sp *shardProcessor) getAllMiniBlockDstMeFromMeta(round uint64, metaHashes continue } - miniBlockDstMe := hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) - for mbHash := range miniBlockDstMe { - mMiniBlockMeta[mbHash] = metaHash + crossMiniBlockHashes := hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) + for hash := range crossMiniBlockHashes { + miniBlockMetaHashes[hash] = []byte(metaBlockHash) } } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return mMiniBlockMeta, nil + return miniBlockMetaHashes, nil } func (sp *shardProcessor) getOrderedMetaBlocks(round uint64) ([]*hashAndHdr, error) { @@ -1444,7 +1451,7 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( } if len(hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId())) == 0 { - sp.hdrsForCurrBlock.hdrHashAndInfo[string(orderedMetaBlocks[i].hash)] = &hdrInfo{hdr: hdr} + sp.hdrsForCurrBlock.hdrHashAndInfo[string(orderedMetaBlocks[i].hash)] = &hdrInfo{hdr: hdr, usedInBlock: true} hdrsAdded++ lastMetaHdr = hdr continue @@ -1473,7 +1480,7 @@ func (sp *shardProcessor) createAndProcessCrossMiniBlocksDstMe( txsAdded = txsAdded + currTxsAdded if currTxsAdded > 0 { - sp.hdrsForCurrBlock.hdrHashAndInfo[string(orderedMetaBlocks[i].hash)] = &hdrInfo{hdr: hdr} + sp.hdrsForCurrBlock.hdrHashAndInfo[string(orderedMetaBlocks[i].hash)] = &hdrInfo{hdr: hdr, usedInBlock: true} hdrsAdded++ } @@ -1607,6 +1614,10 @@ func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() usedMetaHdrsInfo := make([]*nonceAndHashInfo, 0) for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if !hdrInfo.usedInBlock { + continue + } + usedMetaHdrsInfo = append(usedMetaHdrsInfo, &nonceAndHashInfo{nonce: hdrInfo.hdr.GetNonce(), hash: []byte(metaBlockHash)}) } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index 7aa5d722264..da514523322 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -2690,7 +2690,7 @@ func TestShardProcessor_CreateAndProcessCrossMiniBlocksDstMe(t *testing.T) { miniBlockSlice, usedMetaHdrsHashes, noOfTxs, err := sp.CreateAndProcessCrossMiniBlocksDstMe(3, 2, 2, haveTimeTrue) assert.Equal(t, err == nil, true) assert.Equal(t, len(miniBlockSlice) == 0, true) - assert.Equal(t, len(usedMetaHdrsHashes) == 0, true) + assert.Equal(t, usedMetaHdrsHashes, uint32(0)) assert.Equal(t, noOfTxs, uint32(0)) } @@ -2797,7 +2797,7 @@ func TestShardProcessor_CreateAndProcessCrossMiniBlocksDstMeProcessPartOfMiniBlo miniBlocksReturned, usedMetaHdrsHashes, nrTxAdded, err := sp.CreateAndProcessCrossMiniBlocksDstMe(3, 2, 2, haveTimeTrue) assert.Equal(t, 0, len(miniBlocksReturned)) - assert.Equal(t, 0, len(usedMetaHdrsHashes)) + assert.Equal(t, uint32(0), usedMetaHdrsHashes) assert.Equal(t, uint32(0), nrTxAdded) assert.Nil(t, err) } From 1517d942795e4feb8831e53e72c5f62b18b2499f Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Thu, 3 Oct 2019 14:35:55 +0300 Subject: [PATCH 05/10] * Fixed unit tests --- process/block/baseProcess_test.go | 2 +- process/block/export_test.go | 25 ++- process/block/shardblock.go | 283 ++++++++++++++---------------- process/block/shardblock_test.go | 135 ++++++-------- 4 files changed, 207 insertions(+), 238 deletions(-) diff --git a/process/block/baseProcess_test.go b/process/block/baseProcess_test.go index 39b272400e6..8114f52efef 100644 --- a/process/block/baseProcess_test.go +++ b/process/block/baseProcess_test.go @@ -245,7 +245,7 @@ func initStore() *dataRetriever.ChainStorer { return store } -func createDummyMetaBlock(destShardId uint32, senderShardId uint32, miniBlockHashes ...[]byte) data.HeaderHandler { +func createDummyMetaBlock(destShardId uint32, senderShardId uint32, miniBlockHashes ...[]byte) *block.MetaBlock { metaBlock := &block.MetaBlock{ ShardInfo: []block.ShardData{ { diff --git a/process/block/export_test.go b/process/block/export_test.go index ce15ee1afd5..6fc28dafc6a 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -250,8 +250,8 @@ func (sp *shardProcessor) RequestFinalMissingHeaders() uint32 { return sp.requestFinalMissingHeaders() } -func (sp *shardProcessor) CheckMetaHeadersValidityAndFinality(hdr *block.Header) error { - return sp.checkMetaHeadersValidityAndFinality(hdr) +func (sp *shardProcessor) CheckMetaHeadersValidityAndFinality() error { + return sp.checkMetaHeadersValidityAndFinality() } func (sp *shardProcessor) GetOrderedMetaBlocks(round uint64) ([]*hashAndHdr, error) { @@ -299,9 +299,8 @@ func (sp *shardProcessor) RestoreMetaBlockIntoPool( func (sp *shardProcessor) GetAllMiniBlockDstMeFromMeta( round uint64, - metaHashes [][]byte, ) (map[string][]byte, error) { - return sp.getAllMiniBlockDstMeFromMeta(round, metaHashes) + return sp.getAllMiniBlockDstMeFromMeta(round) } func (sp *shardProcessor) IsMiniBlockProcessed(metaBlockHash []byte, miniBlockHash []byte) bool { @@ -311,3 +310,21 @@ func (sp *shardProcessor) IsMiniBlockProcessed(metaBlockHash []byte, miniBlockHa func (sp *shardProcessor) AddProcessedMiniBlock(metaBlockHash []byte, miniBlockHash []byte) { sp.addProcessedMiniBlock(metaBlockHash, miniBlockHash) } + +func (sp *shardProcessor) SetHdrForCurrentBlock(headerHash []byte, headerHandler data.HeaderHandler, usedInBlock bool) { + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() + sp.hdrsForCurrBlock.hdrHashAndInfo[string(headerHash)] = &hdrInfo{hdr: headerHandler, usedInBlock: usedInBlock} + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() +} + +func (sp *shardProcessor) SetMissingHdrsForCurrentBlock(missingHdrs uint32) { + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() + sp.hdrsForCurrBlock.missingHdrs = missingHdrs + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() +} + +func (sp *shardProcessor) SetMissingFinalHdrsForCurrentBlock(missingFinalHdrs uint32) { + sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() + sp.hdrsForCurrBlock.missingFinalHdrs = missingFinalHdrs + sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() +} diff --git a/process/block/shardblock.go b/process/block/shardblock.go index c5942747cab..3dbf5d3712f 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -44,7 +44,7 @@ type shardProcessor struct { blocksTracker process.BlocksTracker metaBlockFinality int - chRcvAllMetaHdrs chan bool + chRcvAllMetaHdrs chan bool hdrsForCurrBlock hdrForBlock currHighestMetaHdrNonce uint64 @@ -324,35 +324,22 @@ func (sp *shardProcessor) checkMetaHeadersValidityAndFinality() error { return err } - currAddedMetaHdrs := make([]*block.MetaBlock, 0) - - sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() - for _, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { - if !hdrInfo.usedInBlock { - continue - } - - metaHdr, ok := hdrInfo.hdr.(*block.MetaBlock) - if !ok { - sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return process.ErrWrongTypeAssertion - } - - currAddedMetaHdrs = append(currAddedMetaHdrs, metaHdr) + usedMetaHdrs, err := sp.sortHdrsForCurrentBlock(true) + if err != nil { + return err } - sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - if len(currAddedMetaHdrs) == 0 { + if len(usedMetaHdrs) == 0 { return nil } - if len(currAddedMetaHdrs) > 1 { - sort.Slice(currAddedMetaHdrs, func(i, j int) bool { - return currAddedMetaHdrs[i].Nonce < currAddedMetaHdrs[j].Nonce + if len(usedMetaHdrs) > 1 { + sort.Slice(usedMetaHdrs, func(i, j int) bool { + return usedMetaHdrs[i].Nonce < usedMetaHdrs[j].Nonce }) } - for _, metaHdr := range currAddedMetaHdrs { + for _, metaHdr := range usedMetaHdrs { err = sp.isHdrConstructionValid(metaHdr, tmpNotedHdr) if err != nil { return err @@ -375,7 +362,7 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error return process.ErrNilBlockHeader } - sortedMetaHdrs, err := sp.getFinalityAttestingHeaders(header, process.MetaBlockFinality) + finalMetaHdrs, err := sp.sortHdrsForCurrentBlock(false) if err != nil { return err } @@ -383,20 +370,20 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error lastVerifiedHdr := header // verify if there are "K" block after current to make this one final nextBlocksVerified := 0 - for _, tmpHdr := range sortedMetaHdrs { + for _, metaHdr := range finalMetaHdrs { if nextBlocksVerified >= sp.metaBlockFinality { break } // found a header with the next nonce - if tmpHdr.hdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { - err = sp.isHdrConstructionValid(tmpHdr.hdr, lastVerifiedHdr) + if metaHdr.Nonce == lastVerifiedHdr.GetNonce()+1 { + err := sp.isHdrConstructionValid(metaHdr, lastVerifiedHdr) if err != nil { log.Debug(err.Error()) continue } - lastVerifiedHdr = tmpHdr.hdr + lastVerifiedHdr = metaHdr nextBlocksVerified += 1 } } @@ -409,52 +396,52 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error return nil } -func (sp *shardProcessor) getFinalityAttestingHeaders( - highestNonceHdr data.HeaderHandler, - finality uint64, -) ([]*hashAndHdr, error) { - - if highestNonceHdr == nil || highestNonceHdr.IsInterfaceNil() { - return nil, process.ErrNilBlockHeader - } - - metaBlockPool := sp.dataPool.MetaBlocks() - if metaBlockPool == nil { - return nil, process.ErrNilMetaBlockPool - } - - orderedMetaBlocks := make([]*hashAndHdr, 0) - // get keys and arrange them into shards - for _, key := range metaBlockPool.Keys() { - val, _ := metaBlockPool.Peek(key) - if val == nil { - continue - } - - hdr, ok := val.(*block.MetaBlock) - if !ok { - continue - } - - isHdrNonceLowerOrEqualThanHighestNonce := hdr.GetNonce() <= highestNonceHdr.GetNonce() - isHdrNonceHigherThanFinalNonce := hdr.GetNonce() > highestNonceHdr.GetNonce()+finality - - if isHdrNonceLowerOrEqualThanHighestNonce || - isHdrNonceHigherThanFinalNonce { - continue - } - - orderedMetaBlocks = append(orderedMetaBlocks, &hashAndHdr{hdr: hdr, hash: key}) - } - - if len(orderedMetaBlocks) > 1 { - sort.Slice(orderedMetaBlocks, func(i, j int) bool { - return orderedMetaBlocks[i].hdr.GetNonce() < orderedMetaBlocks[j].hdr.GetNonce() - }) - } - - return orderedMetaBlocks, nil -} +//func (sp *shardProcessor) getFinalityAttestingHeaders( +// highestNonceHdr data.HeaderHandler, +// finality uint64, +//) ([]*hashAndHdr, error) { +// +// if highestNonceHdr == nil || highestNonceHdr.IsInterfaceNil() { +// return nil, process.ErrNilBlockHeader +// } +// +// metaBlockPool := sp.dataPool.MetaBlocks() +// if metaBlockPool == nil { +// return nil, process.ErrNilMetaBlockPool +// } +// +// orderedMetaBlocks := make([]*hashAndHdr, 0) +// // get keys and arrange them into shards +// for _, key := range metaBlockPool.Keys() { +// val, _ := metaBlockPool.Peek(key) +// if val == nil { +// continue +// } +// +// hdr, ok := val.(*block.MetaBlock) +// if !ok { +// continue +// } +// +// isHdrNonceLowerOrEqualThanHighestNonce := hdr.GetNonce() <= highestNonceHdr.GetNonce() +// isHdrNonceHigherThanFinalNonce := hdr.GetNonce() > highestNonceHdr.GetNonce()+finality +// +// if isHdrNonceLowerOrEqualThanHighestNonce || +// isHdrNonceHigherThanFinalNonce { +// continue +// } +// +// orderedMetaBlocks = append(orderedMetaBlocks, &hashAndHdr{hdr: hdr, hash: key}) +// } +// +// if len(orderedMetaBlocks) > 1 { +// sort.Slice(orderedMetaBlocks, func(i, j int) bool { +// return orderedMetaBlocks[i].hdr.GetNonce() < orderedMetaBlocks[j].hdr.GetNonce() +// }) +// } +// +// return orderedMetaBlocks, nil +//} // check if header has the same miniblocks as presented in body func (sp *shardProcessor) checkHeaderBodyCorrelation(hdr *block.Header, body block.Body) error { @@ -624,37 +611,8 @@ func (sp *shardProcessor) restoreMetaBlockIntoPool(miniBlockHashes map[string]ui } } - //for miniBlockHash := range miniBlockHashes { - // sp.removeProcessedMiniBlock([]byte(miniBlockHash)) - //} - - //TODO: Replace this for with the commented one above - for _, metaBlockKey := range metaBlockPool.Keys() { - if len(miniBlockHashes) == 0 { - break - } - metaBlock, ok := metaBlockPool.Peek(metaBlockKey) - if !ok { - log.Error(process.ErrNilMetaBlockHeader.Error()) - continue - } - - hdr, ok := metaBlock.(data.HeaderHandler) - if !ok { - metaBlockPool.Remove(metaBlockKey) - log.Error(process.ErrWrongTypeAssertion.Error()) - continue - } - - crossMiniBlockHashes := hdr.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) - for key := range miniBlockHashes { - _, ok = crossMiniBlockHashes[key] - if !ok { - continue - } - - sp.removeProcessedMiniBlock(metaBlockKey, []byte(key)) - } + for miniBlockHash := range miniBlockHashes { + sp.removeProcessedMiniBlock([]byte(miniBlockHash)) } return nil @@ -939,7 +897,7 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) log.Debug(fmt.Sprintf("cross mini blocks in body: %d\n", len(miniBlockHashes))) - processedMetaHeaders, processedCrossMiniBlocksHashes, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) + processedMetaBlocks, processedCrossMiniBlocksHashes, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) if err != nil { return nil, err } @@ -965,7 +923,7 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return processedMetaHeaders, nil + return processedMetaBlocks, nil } // getProcessedMetaBlocks returns all the meta blocks fully processed @@ -1058,6 +1016,12 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() + if len(processedMetaHdrs) > 1 { + sort.Slice(processedMetaHdrs, func(i, j int) bool { + return processedMetaHdrs[i].GetNonce() < processedMetaHdrs[j].GetNonce() + }) + } + return processedMetaHdrs, processedCrossMiniBlocksHashes, nil } @@ -1150,14 +1114,14 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { return } - metaBlock, ok := obj.(*block.MetaBlock) + metaBlock, ok := obj.(data.HeaderHandler) if !ok { return } log.Debug(fmt.Sprintf("received metablock with hash %s and nonce %d from network\n", core.ToB64(metaBlockHash), - metaBlock.Nonce)) + metaBlock.GetNonce())) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() @@ -1167,8 +1131,8 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)].hdr = metaBlock sp.hdrsForCurrBlock.missingHdrs-- - if metaBlock.Nonce > sp.currHighestMetaHdrNonce { - sp.currHighestMetaHdrNonce = metaBlock.Nonce + if metaBlock.GetNonce() > sp.currHighestMetaHdrNonce { + sp.currHighestMetaHdrNonce = metaBlock.GetNonce() } } @@ -1577,7 +1541,7 @@ func (sp *shardProcessor) createMiniBlocks( maxTxSpaceRemained := int32(maxItemsInBlock) - int32(txs) maxMbSpaceRemained := sp.getMaxMiniBlocksSpaceRemained( maxItemsInBlock, - uint32(len(destMeMiniBlocks)+hdrs), + uint32(len(destMeMiniBlocks))+hdrs, uint32(len(miniBlocks))) if maxTxSpaceRemained > 0 && maxMbSpaceRemained > 0 { @@ -1647,29 +1611,7 @@ func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round sp.appStatusHandler.SetUInt64Value(core.MetricNumTxInBlock, uint64(totalTxCount)) sp.appStatusHandler.SetUInt64Value(core.MetricNumMiniBlocks, uint64(len(body))) - sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() - usedMetaHdrsInfo := make([]*nonceAndHashInfo, 0) - for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { - if !hdrInfo.usedInBlock { - continue - } - - usedMetaHdrsInfo = append(usedMetaHdrsInfo, &nonceAndHashInfo{nonce: hdrInfo.hdr.GetNonce(), hash: []byte(metaBlockHash)}) - } - sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - - if len(usedMetaHdrsInfo) > 1 { - sort.Slice(usedMetaHdrsInfo, func(i, j int) bool { - return usedMetaHdrsInfo[i].nonce < usedMetaHdrsInfo[j].nonce - }) - } - - usedMetaHdrsHashes := make([][]byte, len(usedMetaHdrsInfo)) - for i := 0; i < len(usedMetaHdrsInfo); i++ { - usedMetaHdrsHashes[i] = usedMetaHdrsInfo[i].hash - } - - header.MetaBlockHashes = usedMetaHdrsHashes + header.MetaBlockHashes = sp.sortHdrsHashesForCurrentBlock(true) sp.blockSizeThrottler.Add( round, @@ -1774,27 +1716,14 @@ func (sp *shardProcessor) addProcessedMiniBlock(metaBlockHash []byte, miniBlockH sp.mutProcessedMiniBlocks.Unlock() } -//func (sp *shardProcessor) removeProcessedMiniBlock(miniBlockHash []byte) { -// sp.mutProcessedMiniBlocks.Lock() -// for _, miniBlocksProcessed := range sp.processedMiniBlocks { -// _, isProcessed := miniBlocksProcessed[string(miniBlockHash)] -// if isProcessed { -// delete(miniBlocksProcessed, string(miniBlockHash)) -// } -// } -// sp.mutProcessedMiniBlocks.Unlock() -//} - -//TODO: Replace this method with the commented one above -func (sp *shardProcessor) removeProcessedMiniBlock(metaBlockHash []byte, miniBlockHash []byte) { +func (sp *shardProcessor) removeProcessedMiniBlock(miniBlockHash []byte) { sp.mutProcessedMiniBlocks.Lock() - miniBlocksProcessed, ok := sp.processedMiniBlocks[string(metaBlockHash)] - if !ok { - sp.mutProcessedMiniBlocks.Unlock() - return + for _, miniBlocksProcessed := range sp.processedMiniBlocks { + _, isProcessed := miniBlocksProcessed[string(miniBlockHash)] + if isProcessed { + delete(miniBlocksProcessed, string(miniBlockHash)) + } } - - delete(miniBlocksProcessed, string(miniBlockHash)) sp.mutProcessedMiniBlocks.Unlock() } @@ -1847,3 +1776,51 @@ func (sp *shardProcessor) CreateBlockStarted() { sp.hdrsForCurrBlock.hdrHashAndInfo = make(map[string]*hdrInfo) sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() } + +func (sp *shardProcessor) sortHdrsForCurrentBlock(usedInBlock bool) ([]*block.MetaBlock, error) { + hdrsForCurrentBlock := make([]*block.MetaBlock, 0) + + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() + for _, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if hdrInfo.usedInBlock != usedInBlock { + continue + } + + metaHdr, ok := hdrInfo.hdr.(*block.MetaBlock) + if !ok { + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() + return nil, process.ErrWrongTypeAssertion + } + + hdrsForCurrentBlock = append(hdrsForCurrentBlock, metaHdr) + } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() + + return hdrsForCurrentBlock, nil +} + +func (sp *shardProcessor) sortHdrsHashesForCurrentBlock(usedInBlock bool) [][]byte { + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() + hdrsForCurrentBlockInfo := make([]*nonceAndHashInfo, 0) + for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { + if hdrInfo.usedInBlock != usedInBlock { + continue + } + + hdrsForCurrentBlockInfo = append(hdrsForCurrentBlockInfo, &nonceAndHashInfo{nonce: hdrInfo.hdr.GetNonce(), hash: []byte(metaBlockHash)}) + } + sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() + + if len(hdrsForCurrentBlockInfo) > 1 { + sort.Slice(hdrsForCurrentBlockInfo, func(i, j int) bool { + return hdrsForCurrentBlockInfo[i].nonce < hdrsForCurrentBlockInfo[j].nonce + }) + } + + hdrsHashesForCurrentBlock := make([][]byte, len(hdrsForCurrentBlockInfo)) + for i := 0; i < len(hdrsForCurrentBlockInfo); i++ { + hdrsHashesForCurrentBlock[i] = hdrsForCurrentBlockInfo[i].hash + } + + return hdrsHashesForCurrentBlock +} diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index 673f0add7fe..48d720a0837 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -1422,30 +1422,30 @@ func TestShardProcessor_CheckMetaHeadersValidityAndFinalityShouldPass(t *testing prevMeta := genesisBlocks[sharding.MetachainShardId] prevHash, _ = core.CalculateHash(marshalizer, hasher, prevMeta) - meta := &block.MetaBlock{ + meta1 := &block.MetaBlock{ Nonce: 1, ShardInfo: shardHdrs, Round: 1, PrevHash: prevHash, PrevRandSeed: prevMeta.GetRandSeed(), } - metaBytes, _ := marshalizer.Marshal(meta) - metaHash := hasher.Compute(string(metaBytes)) - hdr.MetaBlockHashes = append(hdr.MetaBlockHashes, metaHash) + metaBytes, _ := marshalizer.Marshal(meta1) + metaHash1 := hasher.Compute(string(metaBytes)) + hdr.MetaBlockHashes = append(hdr.MetaBlockHashes, metaHash1) - tdp.MetaBlocks().Put(metaHash, meta) + tdp.MetaBlocks().Put(metaHash1, meta1) - prevHash, _ = core.CalculateHash(marshalizer, hasher, meta) - meta = &block.MetaBlock{ + prevHash, _ = core.CalculateHash(marshalizer, hasher, meta1) + meta2 := &block.MetaBlock{ Nonce: 2, ShardInfo: make([]block.ShardData, 0), Round: 2, PrevHash: prevHash, } - metaBytes, _ = marshalizer.Marshal(meta) - metaHash = hasher.Compute(string(metaBytes)) + metaBytes, _ = marshalizer.Marshal(meta2) + metaHash2 := hasher.Compute(string(metaBytes)) - tdp.MetaBlocks().Put(metaHash, meta) + tdp.MetaBlocks().Put(metaHash2, meta2) arguments := CreateMockArgumentsMultiShard() arguments.DataPool = tdp arguments.Hasher = hasher @@ -1454,33 +1454,22 @@ func TestShardProcessor_CheckMetaHeadersValidityAndFinalityShouldPass(t *testing sp, _ := blproc.NewShardProcessor(arguments) hdr.Round = 4 - err := sp.CheckMetaHeadersValidityAndFinality(&hdr) + sp.SetHdrForCurrentBlock(metaHash1, meta1, true) + sp.SetHdrForCurrentBlock(metaHash2, meta2, false) + + err := sp.CheckMetaHeadersValidityAndFinality() assert.Nil(t, err) } -func TestShardProcessor_CheckMetaHeadersValidityAndFinalityShouldErr(t *testing.T) { +func TestShardProcessor_CheckMetaHeadersValidityAndFinalityShouldReturnNilWhenNoMetaBlocksAreUsed(t *testing.T) { t.Parallel() - mbHdrs := make([]block.MiniBlockHeader, 0) - rootHash := []byte("rootHash") - txHash := []byte("txhash1") - txHashes := make([][]byte, 0) - txHashes = append(txHashes, txHash) - tdp := mock.NewPoolsHolderMock() genesisBlocks := createGenesisBlocks(mock.NewMultiShardsCoordinatorMock(3)) sp, _ := blproc.NewShardProcessorEmptyWith3shards(tdp, genesisBlocks) - lastHdr := genesisBlocks[0] - prevHash, _ := core.CalculateHash(&mock.MarshalizerMock{}, &mock.HasherMock{}, lastHdr) - - randSeed := []byte("rand seed") - hdr := initBlockHeader(prevHash, randSeed, rootHash, mbHdrs) - - hdr.MetaBlockHashes = append(hdr.MetaBlockHashes, []byte("meta")) - hdr.Round = 0 - err := sp.CheckMetaHeadersValidityAndFinality(&hdr) - assert.Equal(t, err, process.ErrNilMetaBlockHeader) + err := sp.CheckMetaHeadersValidityAndFinality() + assert.Nil(t, err) } //------- CommitBlock @@ -2953,20 +2942,23 @@ func TestShardProcessor_GetProcessedMetaBlockFromPoolShouldWork(t *testing.T) { } //put 3 metablocks in pool - mb1Hash := []byte("meta block 1") + metaBlockHash1 := []byte("meta block 1") + metaBlock1 := createDummyMetaBlock(destShardId, destShards[0], miniblockHashes[0], miniblockHashes[1]) dataPool.MetaBlocks().Put( - mb1Hash, - createDummyMetaBlock(destShardId, destShards[0], miniblockHashes[0], miniblockHashes[1]), + metaBlockHash1, + metaBlock1, ) - mb2Hash := []byte("meta block 2") + metaBlockHash2 := []byte("meta block 2") + metaBlock2 := createDummyMetaBlock(destShardId, destShards[1], miniblockHashes[2], miniblockHashes[3]) dataPool.MetaBlocks().Put( - mb2Hash, - createDummyMetaBlock(destShardId, destShards[1], miniblockHashes[2], miniblockHashes[3]), + metaBlockHash2, + metaBlock2, ) - mb3Hash := []byte("meta block 3") + metaBlockHash3 := []byte("meta block 3") + metaBlock3 := createDummyMetaBlock(destShardId, destShards[2], miniblockHashes[4], miniblockHashes[5]) dataPool.MetaBlocks().Put( - mb3Hash, - createDummyMetaBlock(destShardId, destShards[2], miniblockHashes[4], miniblockHashes[5]), + metaBlockHash3, + metaBlock3, ) shardCoordinator := mock.NewMultipleShardsCoordinatorMock() @@ -2991,6 +2983,10 @@ func TestShardProcessor_GetProcessedMetaBlockFromPoolShouldWork(t *testing.T) { arguments.StartHeaders = createGenesisBlocks(shardCoordinator) bp, _ := blproc.NewShardProcessor(arguments) + bp.SetHdrForCurrentBlock(metaBlockHash1, metaBlock1, true) + bp.SetHdrForCurrentBlock(metaBlockHash2, metaBlock2, true) + bp.SetHdrForCurrentBlock(metaBlockHash3, metaBlock3, true) + //create mini block headers with first 3 miniblocks from miniblocks var mbHeaders := []block.MiniBlockHeader{ {Hash: miniblockHashes[0]}, @@ -2999,9 +2995,9 @@ func TestShardProcessor_GetProcessedMetaBlockFromPoolShouldWork(t *testing.T) { } hashes := [][]byte{ - mb1Hash, - mb2Hash, - mb3Hash, + metaBlockHash1, + metaBlockHash2, + metaBlockHash3, } blockHeader := &block.Header{MetaBlockHashes: hashes, MiniBlockHeaders: mbHeaders} @@ -3010,11 +3006,11 @@ func TestShardProcessor_GetProcessedMetaBlockFromPoolShouldWork(t *testing.T) { assert.Nil(t, err) //check WasMiniBlockProcessed for remaining metablocks - assert.True(t, bp.IsMiniBlockProcessed(mb2Hash, miniblockHashes[2])) - assert.False(t, bp.IsMiniBlockProcessed(mb2Hash, miniblockHashes[3])) + assert.True(t, bp.IsMiniBlockProcessed(metaBlockHash2, miniblockHashes[2])) + assert.False(t, bp.IsMiniBlockProcessed(metaBlockHash2, miniblockHashes[3])) - assert.False(t, bp.IsMiniBlockProcessed(mb3Hash, miniblockHashes[4])) - assert.False(t, bp.IsMiniBlockProcessed(mb3Hash, miniblockHashes[5])) + assert.False(t, bp.IsMiniBlockProcessed(metaBlockHash3, miniblockHashes[4])) + assert.False(t, bp.IsMiniBlockProcessed(metaBlockHash3, miniblockHashes[5])) } func TestBlockProcessor_RestoreBlockIntoPoolsShouldErrNilBlockHeader(t *testing.T) { @@ -3391,6 +3387,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { // wrong hdr type in pool and defer called dataPool.MetaBlocks().Put(currHash, shardHdr) + sp.SetHdrForCurrentBlock(currHash, shardHdr, true) hashes := make([][]byte, 0) hashes = append(hashes, currHash) @@ -3413,6 +3410,10 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { dataPool.MetaBlocks().Put(currHash, currHdr) dataPool.MetaBlocks().Put(prevHash, prevHdr) + sp.CreateBlockStarted() + sp.SetHdrForCurrentBlock(currHash, currHdr, true) + sp.SetHdrForCurrentBlock(prevHash, prevHdr, true) + hashes = make([][]byte, 0) hashes = append(hashes, currHash) hashes = append(hashes, prevHash) @@ -3573,6 +3574,9 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNotAllMBFinished(t *tes dataPool.MetaBlocks().Put(currHash, currHdr) dataPool.MetaBlocks().Put(prevHash, prevHdr) + sp.SetHdrForCurrentBlock(currHash, currHdr, true) + sp.SetHdrForCurrentBlock(prevHash, prevHdr, true) + hashes := make([][]byte, 0) hashes = append(hashes, currHash) hashes = append(hashes, prevHash) @@ -3718,6 +3722,9 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrAllMBFinished(t *testin PrevHash: currHash, Nonce: 47}) + sp.SetHdrForCurrentBlock(currHash, currHdr, true) + sp.SetHdrForCurrentBlock(prevHash, prevHdr, true) + hashes := make([][]byte, 0) hashes = append(hashes, currHash) hashes = append(hashes, prevHash) @@ -3925,54 +3932,22 @@ func TestShardPreprocessor_getAllMiniBlockDstMeFromMetaShouldPass(t *testing.T) } shardHdrs := make([]block.ShardData, 0) shardHdrs = append(shardHdrs, shardHeader) + metaBlock := &block.MetaBlock{Nonce: 1, Round: 1, ShardInfo: shardHdrs} idp := initDataPool([]byte("tx_hash1")) - idp.MetaBlocksCalled = func() storage.Cacher { - return &mock.CacherStub{ - GetCalled: func(key []byte) (value interface{}, ok bool) { - if reflect.DeepEqual(key, []byte("tx1_hash")) { - return &transaction.Transaction{Nonce: 10}, true - } - return nil, false - }, - KeysCalled: func() [][]byte { - return nil - }, - LenCalled: func() int { - return 0 - }, - PeekCalled: func(key []byte) (value interface{}, ok bool) { - return &block.MetaBlock{ - Nonce: 1, - Round: 1, - ShardInfo: shardHdrs, - }, true - }, - PutCalled: func(key []byte, value interface{}) (evicted bool) { - return true - }, - RegisterHandlerCalled: func(i func(key []byte)) {}, - } - } arguments := CreateMockArgumentsMultiShard() arguments.DataPool = idp sp, _ := blproc.NewShardProcessor(arguments) - meta := block.MetaBlock{ - Nonce: 0, - ShardInfo: make([]block.ShardData, 0), - } - - metaBytes, _ := marshalizer.Marshal(meta) + metaBytes, _ := marshalizer.Marshal(metaBlock) hasher.ComputeCalled = func(s string) []byte { return []byte("cool") } metaHash := hasher.Compute(string(metaBytes)) - metablockHashes := make([][]byte, 0) - metablockHashes = append(metablockHashes, metaHash) + sp.SetHdrForCurrentBlock(metaHash, metaBlock, true) - orderedMetaBlocks, err := sp.GetAllMiniBlockDstMeFromMeta(1, metablockHashes) + orderedMetaBlocks, err := sp.GetAllMiniBlockDstMeFromMeta(1) assert.Equal(t, 1, len(orderedMetaBlocks)) assert.Equal(t, orderedMetaBlocks[""], metaHash) From 946d6b2616fe7ccb24aed1c3fc4888a070fa1333 Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Thu, 3 Oct 2019 20:26:19 +0300 Subject: [PATCH 06/10] * Fixed unit tests --- cmd/node/config/config.toml | 2 +- .../block/executingRewardMiniblocks_test.go | 18 ++-- integrationTests/testProcessorNode.go | 3 + process/block/shardblock.go | 85 ++++--------------- process/block/shardblock_test.go | 23 ++--- process/mock/headerHandlerStub.go | 50 +++++------ 6 files changed, 63 insertions(+), 118 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 7b037ab49cb..80160628fa6 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -154,7 +154,7 @@ Type = "LRU" [TxBlockBodyDataPool] - Size = 100 + Size = 300 Type = "LRU" [StateBlockBodyDataPool] diff --git a/integrationTests/multiShard/block/executingRewardMiniblocks_test.go b/integrationTests/multiShard/block/executingRewardMiniblocks_test.go index c0ab6298109..2d4cf4e7a91 100644 --- a/integrationTests/multiShard/block/executingRewardMiniblocks_test.go +++ b/integrationTests/multiShard/block/executingRewardMiniblocks_test.go @@ -19,9 +19,12 @@ import ( "github.com/stretchr/testify/assert" ) -func getRewardValue() uint32 { - //TODO: this should be read from protocol config - return uint32(1000) +func getRewardValue(node *integrationTests.TestProcessorNode) uint64 { + return node.EconomicsData.RewardsValue() +} + +func getLeaderPercentage(node *integrationTests.TestProcessorNode) float64 { + return node.EconomicsData.LeaderPercentage() } func TestExecuteBlocksWithTransactionsAndCheckRewards(t *testing.T) { @@ -324,14 +327,14 @@ func verifyRewardsForMetachain( mapRewardsForMeta map[string]uint32, nodes map[uint32][]*integrationTests.TestProcessorNode, ) { - rewardValue := getRewardValue() + rewardValue := getRewardValue(nodes[0][0]) for metaAddr, numOfTimesRewarded := range mapRewardsForMeta { addrContainer, _ := integrationTests.TestAddressConverter.CreateAddressFromPublicKeyBytes([]byte(metaAddr)) acc, err := nodes[0][0].AccntState.GetExistingAccount(addrContainer) assert.Nil(t, err) - expectedBalance := big.NewInt(int64(numOfTimesRewarded * rewardValue)) + expectedBalance := big.NewInt(int64(uint64(numOfTimesRewarded) * rewardValue)) assert.Equal(t, expectedBalance, acc.(*state.Account).Balance) } } @@ -344,9 +347,8 @@ func verifyRewardsForShards( gasPrice uint64, gasLimit uint64, ) { - rewardValue := getRewardValue() - // TODO: fee percentage should be read from protocol config - feePerTxForLeader := gasPrice * gasLimit / 2 + rewardValue := getRewardValue(nodesMap[0][0]) + feePerTxForLeader := float64(gasPrice) * float64(gasLimit) * getLeaderPercentage(nodesMap[0][0]) for address, nbRewards := range mapRewardsForAddress { addrContainer, _ := integrationTests.TestAddressConverter.CreateAddressFromPublicKeyBytes([]byte(address)) diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index b5a46498d13..48dfb7606f0 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -108,6 +108,7 @@ type TestProcessorNode struct { ScProcessor process.SmartContractProcessor RewardsProcessor process.RewardTransactionProcessor PreProcessorsContainer process.PreProcessorsContainer + EconomicsData *economics.EconomicsData ForkDetector process.ForkDetector BlockProcessor process.BlockProcessor @@ -348,6 +349,8 @@ func (tpn *TestProcessorNode) initInnerProcessors() { }, ) + tpn.EconomicsData = economicsData + interimProcFactory, _ := shard.NewIntermediateProcessorsContainerFactory( tpn.ShardCoordinator, TestMarshalizer, diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 349a4e9a563..520f6c078fa 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -328,12 +328,6 @@ func (sp *shardProcessor) checkMetaHeadersValidityAndFinality() error { return nil } - if len(usedMetaHdrs) > 1 { - sort.Slice(usedMetaHdrs, func(i, j int) bool { - return usedMetaHdrs[i].Nonce < usedMetaHdrs[j].Nonce - }) - } - for _, metaHdr := range usedMetaHdrs { err = sp.isHdrConstructionValid(metaHdr, tmpNotedHdr) if err != nil { @@ -391,53 +385,6 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error return nil } -//func (sp *shardProcessor) getFinalityAttestingHeaders( -// highestNonceHdr data.HeaderHandler, -// finality uint64, -//) ([]*hashAndHdr, error) { -// -// if highestNonceHdr == nil || highestNonceHdr.IsInterfaceNil() { -// return nil, process.ErrNilBlockHeader -// } -// -// metaBlockPool := sp.dataPool.MetaBlocks() -// if metaBlockPool == nil { -// return nil, process.ErrNilMetaBlockPool -// } -// -// orderedMetaBlocks := make([]*hashAndHdr, 0) -// // get keys and arrange them into shards -// for _, key := range metaBlockPool.Keys() { -// val, _ := metaBlockPool.Peek(key) -// if val == nil { -// continue -// } -// -// hdr, ok := val.(*block.MetaBlock) -// if !ok { -// continue -// } -// -// isHdrNonceLowerOrEqualThanHighestNonce := hdr.GetNonce() <= highestNonceHdr.GetNonce() -// isHdrNonceHigherThanFinalNonce := hdr.GetNonce() > highestNonceHdr.GetNonce()+finality -// -// if isHdrNonceLowerOrEqualThanHighestNonce || -// isHdrNonceHigherThanFinalNonce { -// continue -// } -// -// orderedMetaBlocks = append(orderedMetaBlocks, &hashAndHdr{hdr: hdr, hash: key}) -// } -// -// if len(orderedMetaBlocks) > 1 { -// sort.Slice(orderedMetaBlocks, func(i, j int) bool { -// return orderedMetaBlocks[i].hdr.GetNonce() < orderedMetaBlocks[j].hdr.GetNonce() -// }) -// } -// -// return orderedMetaBlocks, nil -//} - // check if header has the same miniblocks as presented in body func (sp *shardProcessor) checkHeaderBodyCorrelation(hdr *block.Header, body block.Body) error { mbHashesFromHdr := make(map[string]*block.MiniBlockHeader) @@ -1083,40 +1030,30 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { return } - //metaHdrsNoncesCache := sp.dataPool.HeadersNonces() - //if metaHdrsNoncesCache == nil && sp.metaBlockFinality > 0 { - // return - //} - // - //miniBlksCache := sp.dataPool.MiniBlocks() - //if miniBlksCache == nil || miniBlksCache.IsInterfaceNil() { - // return - //} - obj, ok := metaBlockPool.Peek(metaBlockHash) if !ok { return } - metaBlock, ok := obj.(data.HeaderHandler) + metaBlock, ok := obj.(*block.MetaBlock) if !ok { return } log.Debug(fmt.Sprintf("received metablock with hash %s and nonce %d from network\n", core.ToB64(metaBlockHash), - metaBlock.GetNonce())) + metaBlock.Nonce)) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() if sp.hdrsForCurrBlock.missingHdrs > 0 || sp.hdrsForCurrBlock.missingFinalHdrs > 0 { hdrInfoForHash := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] if hdrInfoForHash != nil && (hdrInfoForHash.hdr == nil || hdrInfoForHash.hdr.IsInterfaceNil()) { - sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)].hdr = metaBlock + hdrInfoForHash.hdr = metaBlock sp.hdrsForCurrBlock.missingHdrs-- - if metaBlock.GetNonce() > sp.currHighestMetaHdrNonce { - sp.currHighestMetaHdrNonce = metaBlock.GetNonce() + if metaBlock.Nonce > sp.currHighestMetaHdrNonce { + sp.currHighestMetaHdrNonce = metaBlock.Nonce } } @@ -1134,7 +1071,8 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { missingFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - if missingHdrs == 0 && missingFinalHdrs == 0 { + allMissingNeededHdrsReceived := missingHdrs == 0 && missingFinalHdrs == 0 + if allMissingNeededHdrsReceived { sp.chRcvAllMetaHdrs <- true } } else { @@ -1780,12 +1718,19 @@ func (sp *shardProcessor) sortHdrsForCurrentBlock(usedInBlock bool) ([]*block.Me } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() + if len(hdrsForCurrentBlock) > 1 { + sort.Slice(hdrsForCurrentBlock, func(i, j int) bool { + return hdrsForCurrentBlock[i].Nonce < hdrsForCurrentBlock[j].Nonce + }) + } + return hdrsForCurrentBlock, nil } func (sp *shardProcessor) sortHdrsHashesForCurrentBlock(usedInBlock bool) [][]byte { - sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() hdrsForCurrentBlockInfo := make([]*nonceAndHashInfo, 0) + + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { if hdrInfo.usedInBlock != usedInBlock { continue diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index 87d21157841..0da42d6b202 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -2466,19 +2466,22 @@ func TestShardProcessor_ReceivedMetaBlockShouldRequestMissingMiniBlocks(t *testi miniBlockHash2 := []byte("miniblock hash 2") miniBlockHash3 := []byte("miniblock hash 3") - metaBlock := mock.HeaderHandlerStub{ - GetMiniBlockHeadersWithDstCalled: func(destId uint32) map[string]uint32 { - return map[string]uint32{ - string(miniBlockHash1): 0, - string(miniBlockHash2): 0, - string(miniBlockHash3): 0, - } - }, - } + metaBlock := &block.MetaBlock{ + Nonce: 1, + Round: 1, + ShardInfo: []block.ShardData{ + block.ShardData{ + ShardId: 1, + ShardMiniBlockHeaders: []block.ShardMiniBlockHeader{ + block.ShardMiniBlockHeader{Hash: miniBlockHash1, SenderShardId: 1, ReceiverShardId: 0}, + block.ShardMiniBlockHeader{Hash: miniBlockHash2, SenderShardId: 1, ReceiverShardId: 0}, + block.ShardMiniBlockHeader{Hash: miniBlockHash3, SenderShardId: 1, ReceiverShardId: 0}, + }}, + }} //put this metaBlock inside datapool metaBlockHash := []byte("metablock hash") - dataPool.MetaBlocks().Put(metaBlockHash, &metaBlock) + dataPool.MetaBlocks().Put(metaBlockHash, metaBlock) //put the existing miniblock inside datapool dataPool.MiniBlocks().Put(miniBlockHash1, &block.MiniBlock{}) diff --git a/process/mock/headerHandlerStub.go b/process/mock/headerHandlerStub.go index 41f496d4bd9..b35061cb422 100644 --- a/process/mock/headerHandlerStub.go +++ b/process/mock/headerHandlerStub.go @@ -4,26 +4,10 @@ type HeaderHandlerStub struct { GetMiniBlockHeadersWithDstCalled func(destId uint32) map[string]uint32 } -func (hhs *HeaderHandlerStub) GetShardID() uint32 { - return 1 -} - -func (hhs *HeaderHandlerStub) GetNonce() uint64 { - return 1 -} - func (hhs *HeaderHandlerStub) GetEpoch() uint32 { panic("implement me") } -func (hhs *HeaderHandlerStub) GetRound() uint64 { - return 1 -} - -func (hhs *HeaderHandlerStub) GetTimeStamp() uint64 { - panic("implement me") -} - func (hhs *HeaderHandlerStub) GetRootHash() []byte { panic("implement me") } @@ -48,6 +32,10 @@ func (hhs *HeaderHandlerStub) GetSignature() []byte { panic("implement me") } +func (hhs *HeaderHandlerStub) GetTimeStamp() uint64 { + panic("implement me") +} + func (hhs *HeaderHandlerStub) GetTxCount() uint32 { panic("implement me") } @@ -96,16 +84,28 @@ func (hhs *HeaderHandlerStub) SetTxCount(txCount uint32) { panic("implement me") } -func (hhs *HeaderHandlerStub) GetMiniBlockHeadersWithDst(destId uint32) map[string]uint32 { - return hhs.GetMiniBlockHeadersWithDstCalled(destId) +func (hhs *HeaderHandlerStub) ItemsInBody() uint32 { + panic("implement me") } -func (hhs *HeaderHandlerStub) GetMiniBlockProcessed(hash []byte) bool { +func (hhs *HeaderHandlerStub) ItemsInHeader() uint32 { panic("implement me") } -func (hhs *HeaderHandlerStub) SetMiniBlockProcessed(hash []byte, processed bool) { - panic("implement me") +func (hhs *HeaderHandlerStub) GetShardID() uint32 { + return 1 +} + +func (hhs *HeaderHandlerStub) GetNonce() uint64 { + return 1 +} + +func (hhs *HeaderHandlerStub) GetRound() uint64 { + return 1 +} + +func (hhs *HeaderHandlerStub) GetMiniBlockHeadersWithDst(destId uint32) map[string]uint32 { + return hhs.GetMiniBlockHeadersWithDstCalled(destId) } // IsInterfaceNil returns true if there is no value under the interface @@ -115,11 +115,3 @@ func (hhs *HeaderHandlerStub) IsInterfaceNil() bool { } return false } - -func (hhs *HeaderHandlerStub) ItemsInHeader() uint32 { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) ItemsInBody() uint32 { - panic("implement me") -} From 0043f843933fef5d57b14ee773eb718e3bca9f37 Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Thu, 3 Oct 2019 20:44:20 +0300 Subject: [PATCH 07/10] * Fixed condition on remained space --- process/block/shardblock.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 520f6c078fa..c283161cfc0 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -1466,16 +1466,14 @@ func (sp *shardProcessor) createMiniBlocks( uint32(len(destMeMiniBlocks))+hdrs, uint32(len(miniBlocks))) - if maxTxSpaceRemained > 0 && maxMbSpaceRemained > 0 { - mbFromMe := sp.txCoordinator.CreateMbsAndProcessTransactionsFromMe( - uint32(maxTxSpaceRemained), - uint32(maxMbSpaceRemained), - round, - haveTime) + mbFromMe := sp.txCoordinator.CreateMbsAndProcessTransactionsFromMe( + uint32(maxTxSpaceRemained), + uint32(maxMbSpaceRemained), + round, + haveTime) - if len(mbFromMe) > 0 { - miniBlocks = append(miniBlocks, mbFromMe...) - } + if len(mbFromMe) > 0 { + miniBlocks = append(miniBlocks, mbFromMe...) } log.Info(fmt.Sprintf("creating mini blocks has been finished: created %d mini blocks\n", len(miniBlocks))) From 6b76dbc91aa02ab2333ddfbd0d3ddf93fd181271 Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Fri, 4 Oct 2019 11:23:25 +0300 Subject: [PATCH 08/10] * Fixed condition on getProcessedMetaBlocksFromMiniBlocks * Changed a print from Info to Debug --- process/block/preprocess/transactions.go | 2 +- process/block/shardblock.go | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/process/block/preprocess/transactions.go b/process/block/preprocess/transactions.go index ade91636526..02c71b686df 100644 --- a/process/block/preprocess/transactions.go +++ b/process/block/preprocess/transactions.go @@ -491,7 +491,7 @@ func (txs *transactions) CreateAndProcessMiniBlock( timeAfter := time.Now() if err != nil { - log.Info(err.Error()) + log.Debug(err.Error()) return nil, err } diff --git a/process/block/shardblock.go b/process/block/shardblock.go index c283161cfc0..dc7fbf996bd 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -871,17 +871,6 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlocks( usedMiniBlocks []*block.MiniBlock, ) ([]data.HeaderHandler, error) { - nrMiniBlocksUsed := len(usedMiniBlocks) - - sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() - nrMetaBlocksUsed := len(sp.hdrsForCurrBlock.hdrHashAndInfo) - sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - - if nrMiniBlocksUsed == 0 || nrMetaBlocksUsed == 0 { - // not an error, it can happen that no metablock hdr or no miniblock is used. - return make([]data.HeaderHandler, 0), nil - } - miniBlockHashes := make(map[int][]byte, 0) for i := 0; i < len(usedMiniBlocks); i++ { if usedMiniBlocks[i].SenderShardID == sp.shardCoordinator.SelfId() { From 3ccc0d5f71c600ebab62143baba3e8a6a3cb5c6c Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Fri, 4 Oct 2019 11:37:21 +0300 Subject: [PATCH 09/10] * Fixed bad renaming after refactor has been used --- core/computers.go | 31 +++--- core/computers_test.go | 56 +++++++--- process/block/baseProcess.go | 8 +- process/block/displayBlock.go | 2 +- process/block/export_test.go | 12 -- process/block/interceptedBlockHeader.go | 10 +- process/block/interceptedMetaBlockHeader.go | 8 +- process/block/metablock.go | 24 ++-- process/block/metablock_test.go | 28 ++--- process/block/shardblock.go | 4 +- process/block/shardblock_test.go | 37 ++++--- process/mock/headerHandlerStub.go | 117 -------------------- process/throttle/block.go | 4 +- process/throttle/block_test.go | 10 +- 14 files changed, 125 insertions(+), 226 deletions(-) delete mode 100644 process/mock/headerHandlerStub.go diff --git a/core/computers.go b/core/computers.go index c6c7b47c08f..e06d1742b98 100644 --- a/core/computers.go +++ b/core/computers.go @@ -1,32 +1,33 @@ package core -import ( - "bytes" -) - -// Max returns the maximum number between two given -func Max(a int32, b int32) int32 { +// MaxInt32 returns the maximum number between two given +func MaxInt32(a int32, b int32) int32 { if a > b { return a } return b } -// Min returns the minimum number between two given -func Min(a int32, b int32) int32 { +// MinInt32 returns the minimum number between two given +func MinInt32(a int32, b int32) int32 { if a < b { return a } return b } -// IsHashInList signals if the given hash exists in the given list of hashes -func IsHashInList(hash []byte, hashes [][]byte) bool { - for i := 0; i < len(hashes); i++ { - if bytes.Equal(hash, hashes[i]) { - return true - } +// MaxUint32 returns the maximum number between two given +func MaxUint32(a uint32, b uint32) uint32 { + if a > b { + return a } + return b +} - return false +// MinUint32 returns the minimum number between two given +func MinUint32(a uint32, b uint32) uint32 { + if a < b { + return a + } + return b } diff --git a/core/computers_test.go b/core/computers_test.go index 3a08d506bab..8b26be785c9 100644 --- a/core/computers_test.go +++ b/core/computers_test.go @@ -7,26 +7,50 @@ import ( "github.com/stretchr/testify/assert" ) -func TestMaxShouldReturnA(t *testing.T) { - a := int32(11) - b := int32(10) - assert.Equal(t, a, core.Max(a, b)) +func TestMaxInt32ShouldReturnA(t *testing.T) { + a := int32(-1) + b := int32(-2) + assert.Equal(t, a, core.MaxInt32(a, b)) } -func TestMaxShouldReturnB(t *testing.T) { - a := int32(10) - b := int32(11) - assert.Equal(t, b, core.Max(a, b)) +func TestMaxInt32ShouldReturnB(t *testing.T) { + a := int32(-2) + b := int32(-1) + assert.Equal(t, b, core.MaxInt32(a, b)) } -func TestMinShouldReturnB(t *testing.T) { - a := int32(11) - b := int32(10) - assert.Equal(t, b, core.Min(a, b)) +func TestMinInt32ShouldReturnB(t *testing.T) { + a := int32(-1) + b := int32(-2) + assert.Equal(t, b, core.MinInt32(a, b)) } -func TestMinShouldReturnA(t *testing.T) { - a := int32(10) - b := int32(11) - assert.Equal(t, a, core.Min(a, b)) +func TestMinInt32ShouldReturnA(t *testing.T) { + a := int32(-2) + b := int32(-1) + assert.Equal(t, a, core.MinInt32(a, b)) +} + +func TestMaxUint32ShouldReturnA(t *testing.T) { + a := uint32(11) + b := uint32(10) + assert.Equal(t, a, core.MaxUint32(a, b)) +} + +func TestMaxUint32ShouldReturnB(t *testing.T) { + a := uint32(10) + b := uint32(11) + assert.Equal(t, b, core.MaxUint32(a, b)) +} + +func TestMinUint32ShouldReturnB(t *testing.T) { + a := uint32(11) + b := uint32(10) + assert.Equal(t, b, core.MinUint32(a, b)) +} + +func TestMinUint32ShouldReturnA(t *testing.T) { + a := uint32(10) + b := uint32(11) + assert.Equal(t, a, core.MinUint32(a, b)) } diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 17cd7ee2b4f..8413b239092 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -86,7 +86,7 @@ func (bp *baseProcessor) RevertAccountState() { } } -// AddLastNotarizedHdr adds the last notarized hdr +// AddLastNotarizedHdr adds the last notarized header func (bp *baseProcessor) AddLastNotarizedHdr(shardId uint32, processedHdr data.HeaderHandler) { bp.mutNotarizedHdrs.Lock() bp.notarizedHdrs[shardId] = append(bp.notarizedHdrs[shardId], processedHdr) @@ -210,7 +210,7 @@ func (bp *baseProcessor) isHdrConstructionValid(currHdr, prevHdr data.HeaderHand } //TODO: add verification if rand seed was correctly computed add other verification - //TODO: check here if the 2 hdr blocks were correctly signed and the consensus group was correctly elected + //TODO: check here if the 2 header blocks were correctly signed and the consensus group was correctly elected if prevHdr.GetRound() >= currHdr.GetRound() { log.Debug(fmt.Sprintf("round does not match in shard %d: local block round is %d and node received block with round %d\n", currHdr.GetShardID(), prevHdr.GetRound(), currHdr.GetRound())) @@ -355,8 +355,8 @@ func (bp *baseProcessor) getLastNotarizedHdr(shardId uint32) (data.HeaderHandler } // SetLastNotarizedHeadersSlice sets the headers blocks in notarizedHdrs for every shard -// This is done when starting a new epoch so metachain can use it when validating next shard hdr blocks -// and shard can validate the next meta hdr +// This is done when starting a new epoch so metachain can use it when validating next shard header blocks +// and shard can validate the next meta header func (bp *baseProcessor) setLastNotarizedHeadersSlice(startHeaders map[uint32]data.HeaderHandler) error { //TODO: protect this to be called only once at genesis time //TODO: do this on constructor as it is a must to for blockprocessor to work diff --git a/process/block/displayBlock.go b/process/block/displayBlock.go index 285556f6635..24e8db47eed 100644 --- a/process/block/displayBlock.go +++ b/process/block/displayBlock.go @@ -229,7 +229,7 @@ func DisplayLastNotarized( shardId uint32) { if lastNotarizedHdrForShard == nil || lastNotarizedHdrForShard.IsInterfaceNil() { - log.Error("last notarized hdr for shard is nil") + log.Error("last notarized header for shard is nil") return } diff --git a/process/block/export_test.go b/process/block/export_test.go index c0496fe2139..65a18b778e1 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -315,15 +315,3 @@ func (sp *shardProcessor) SetHdrForCurrentBlock(headerHash []byte, headerHandler sp.hdrsForCurrBlock.hdrHashAndInfo[string(headerHash)] = &hdrInfo{hdr: headerHandler, usedInBlock: usedInBlock} sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() } - -func (sp *shardProcessor) SetMissingHdrsForCurrentBlock(missingHdrs uint32) { - sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() - sp.hdrsForCurrBlock.missingHdrs = missingHdrs - sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() -} - -func (sp *shardProcessor) SetMissingFinalHdrsForCurrentBlock(missingFinalHdrs uint32) { - sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() - sp.hdrsForCurrBlock.missingFinalHdrs = missingFinalHdrs - sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() -} diff --git a/process/block/interceptedBlockHeader.go b/process/block/interceptedBlockHeader.go index baadd92362d..b1493158f5b 100644 --- a/process/block/interceptedBlockHeader.go +++ b/process/block/interceptedBlockHeader.go @@ -38,17 +38,17 @@ func NewInterceptedHeader( } } -// SetHash sets the hash of this hdr. The hash will also be the ID of this object +// SetHash sets the hash of this header. The hash will also be the ID of this object func (inHdr *InterceptedHeader) SetHash(hash []byte) { inHdr.hash = hash } -// Hash gets the hash of this hdr +// Hash gets the hash of this header func (inHdr *InterceptedHeader) Hash() []byte { return inHdr.hash } -// Shard returns the shard ID for which this hdr is addressed +// Shard returns the shard ID for which this header is addressed func (inHdr *InterceptedHeader) Shard() uint32 { return inHdr.ShardId } @@ -63,7 +63,7 @@ func (inHdr *InterceptedHeader) GetUnderlyingObject() interface{} { return inHdr.Header } -// IntegrityAndValidity checks the integrity and validity of a block hdr wrapper +// IntegrityAndValidity checks the integrity and validity of a block header wrapper func (inHdr *InterceptedHeader) IntegrityAndValidity(coordinator sharding.Coordinator) error { err := inHdr.Integrity(coordinator) if err != nil { @@ -144,7 +144,7 @@ func (inHdr *InterceptedHeader) VerifySig() error { return err } - // get marshalled block hdr without signature and bitmap + // get marshalled block header without signature and bitmap // as this is the message that was signed headerCopy := *inHdr.Header headerCopy.Signature = nil diff --git a/process/block/interceptedMetaBlockHeader.go b/process/block/interceptedMetaBlockHeader.go index 010606a2858..b0fbcdf0227 100644 --- a/process/block/interceptedMetaBlockHeader.go +++ b/process/block/interceptedMetaBlockHeader.go @@ -38,12 +38,12 @@ func NewInterceptedMetaHeader( } } -// SetHash sets the hash of this hdr. The hash will also be the ID of this object +// SetHash sets the hash of this header. The hash will also be the ID of this object func (imh *InterceptedMetaHeader) SetHash(hash []byte) { imh.hash = hash } -// Hash gets the hash of this hdr +// Hash gets the hash of this header func (imh *InterceptedMetaHeader) Hash() []byte { return imh.hash } @@ -53,7 +53,7 @@ func (imh *InterceptedMetaHeader) GetMetaHeader() *block.MetaBlock { return imh.MetaBlock } -// IntegrityAndValidity checks the integrity and validity of a block hdr wrapper +// IntegrityAndValidity checks the integrity and validity of a block header wrapper func (imh *InterceptedMetaHeader) IntegrityAndValidity(coordinator sharding.Coordinator) error { err := imh.Integrity(coordinator) if err != nil { @@ -136,7 +136,7 @@ func (imh *InterceptedMetaHeader) VerifySig() error { return err } - // get marshalled block hdr without signature and bitmap + // get marshalled block header without signature and bitmap // as this is the message that was signed headerCopy := *imh.MetaBlock headerCopy.Signature = nil diff --git a/process/block/metablock.go b/process/block/metablock.go index 676a5d88958..8a10f9a8d34 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -147,7 +147,7 @@ func (mp *metaProcessor) ProcessBlock( err := mp.checkBlockValidity(chainHandler, headerHandler, bodyHandler) if err != nil { if err == process.ErrBlockHashDoesNotMatch { - log.Info(fmt.Sprintf("requested missing meta hdr with hash %s for shard %d\n", + log.Info(fmt.Sprintf("requested missing meta header with hash %s for shard %d\n", core.ToB64(headerHandler.GetPrevHash()), headerHandler.GetShardID())) @@ -743,7 +743,7 @@ func (mp *metaProcessor) checkShardHeadersFinality(header *block.MetaBlock, high break } - // found a hdr with the next nonce + // found a header with the next nonce tmpHdr := sortedHdrPerShard[shId][i] if tmpHdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { err := mp.isHdrConstructionValid(tmpHdr, lastVerifiedHdr) @@ -841,7 +841,7 @@ func (mp *metaProcessor) isShardHeaderValidFinal(currHdr *block.Header, lastHdr return true, hdrIds } - // found a hdr with the next nonce + // found a header with the next nonce tmpHdr := sortedShardHdrs[i] if tmpHdr.GetNonce() == lastVerifiedHdr.GetNonce()+1 { err := mp.isHdrConstructionValid(tmpHdr, lastVerifiedHdr) @@ -862,7 +862,7 @@ func (mp *metaProcessor) isShardHeaderValidFinal(currHdr *block.Header, lastHdr return false, nil } -// receivedHeader is a call back function which is called when a new hdr +// receivedHeader is a call back function which is called when a new header // is added in the headers pool func (mp *metaProcessor) receivedHeader(headerHash []byte) { shardHdrsCache := mp.dataPool.ShardHeaders() @@ -885,7 +885,7 @@ func (mp *metaProcessor) receivedHeader(headerHash []byte) { return } - log.Debug(fmt.Sprintf("received hdr with hash %s and nonce %d from network\n", + log.Debug(fmt.Sprintf("received header with hash %s and nonce %d from network\n", core.ToB64(headerHash), header.GetNonce())) @@ -925,7 +925,7 @@ func (mp *metaProcessor) receivedHeader(headerHash []byte) { } // requestFinalMissingHeaders requests the headers needed to accept the current selected headers for processing the -// current block. It requests the nextKValidity headers greater than the highest shard hdr, for each shard, related +// current block. It requests the nextKValidity headers greater than the highest shard header, for each shard, related // to the block which should be processed func (mp *metaProcessor) requestFinalMissingHeaders() uint32 { requestedBlockHeaders := uint32(0) @@ -1071,7 +1071,7 @@ func (mp *metaProcessor) createShardInfo( log.Info(fmt.Sprintf("creating shard info has been started: have %d hdrs in pool\n", len(orderedHdrs))) - // save last committed hdr for verification + // save last committed header for verification mp.mutNotarizedHdrs.RLock() if mp.notarizedHdrs == nil { mp.mutNotarizedHdrs.RUnlock() @@ -1178,9 +1178,9 @@ func (mp *metaProcessor) createPeerInfo() ([]block.PeerData, error) { return peerInfo, nil } -// CreateBlockHeader creates a miniblock hdr list given a block body +// CreateBlockHeader creates a miniblock header list given a block body func (mp *metaProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round uint64, haveTime func() bool) (data.HeaderHandler, error) { - log.Debug(fmt.Sprintf("started creating block hdr in round %d\n", round)) + log.Debug(fmt.Sprintf("started creating block header in round %d\n", round)) // TODO: add PrevRandSeed and RandSeed when BLS signing is completed header := &block.MetaBlock{ ShardInfo: make([]block.ShardData, 0), @@ -1210,7 +1210,7 @@ func (mp *metaProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round u mp.blockSizeThrottler.Add( round, - uint32(core.Max(int32(header.ItemsInBody()), int32(header.ItemsInHeader())))) + core.MaxUint32(header.ItemsInBody(), header.ItemsInHeader())) return header, nil } @@ -1233,7 +1233,7 @@ func (mp *metaProcessor) MarshalizedDataToBroadcast( mrsData := make(map[uint32][]byte) mrsTxs := make(map[string][][]byte) - // send headers which can validate the current hdr + // send headers which can validate the current header return mrsData, mrsTxs, nil } @@ -1357,7 +1357,7 @@ func (mp *metaProcessor) DecodeBlockBody(dta []byte) data.BodyHandler { return &body } -// DecodeBlockHeader method decodes block hdr from a given byte array +// DecodeBlockHeader method decodes block header from a given byte array func (mp *metaProcessor) DecodeBlockHeader(dta []byte) data.HeaderHandler { if dta == nil { return nil diff --git a/process/block/metablock_test.go b/process/block/metablock_test.go index e614803bf4d..271413ff620 100644 --- a/process/block/metablock_test.go +++ b/process/block/metablock_test.go @@ -901,7 +901,7 @@ func TestMetaProcessor_CommitBlockOkValsShouldWork(t *testing.T) { assert.Nil(t, err) assert.True(t, removeHdrWasCalled) assert.True(t, forkDetectorAddCalled) - //this should sleep as there is an async call to display current hdr and block in CommitBlock + //this should sleep as there is an async call to display current header and block in CommitBlock time.Sleep(time.Second) } @@ -1440,7 +1440,7 @@ func TestMetaProcessor_CreateShardInfoShouldWorkHdrsAdded(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1464,7 +1464,7 @@ func TestMetaProcessor_CreateShardInfoShouldWorkHdrsAdded(t *testing.T) { pool.ShardHeaders().Put(hdrHash1, headers[0]) pool.ShardHeaders().Put(hdrHash11, headers[1]) - // hdr shard 1 + // header shard 1 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(1).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1488,7 +1488,7 @@ func TestMetaProcessor_CreateShardInfoShouldWorkHdrsAdded(t *testing.T) { pool.ShardHeaders().Put(hdrHash2, headers[2]) pool.ShardHeaders().Put(hdrHash22, headers[3]) - // hdr shard 2 + // header shard 2 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(2).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1608,7 +1608,7 @@ func TestMetaProcessor_CreateShardInfoEmptyBlockHDRRoundTooHigh(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1632,7 +1632,7 @@ func TestMetaProcessor_CreateShardInfoEmptyBlockHDRRoundTooHigh(t *testing.T) { pool.ShardHeaders().Put(hdrHash1, headers[0]) pool.ShardHeaders().Put(hdrHash11, headers[1]) - // hdr shard 1 + // header shard 1 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(1).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1656,7 +1656,7 @@ func TestMetaProcessor_CreateShardInfoEmptyBlockHDRRoundTooHigh(t *testing.T) { pool.ShardHeaders().Put(hdrHash2, headers[2]) pool.ShardHeaders().Put(hdrHash22, headers[3]) - // hdr shard 2 + // header shard 2 prevHash, _ = mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(2).(*block.Header)) headers = append(headers, &block.Header{ Round: 10, @@ -1817,7 +1817,7 @@ func TestMetaProcessor_CreateLastNotarizedHdrs(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -1847,13 +1847,13 @@ func TestMetaProcessor_CreateLastNotarizedHdrs(t *testing.T) { shDataPrev := block.ShardData{ShardId: 0, HeaderHash: prevHash} metaHdr.ShardInfo = append(metaHdr.ShardInfo, shDataPrev) - // test hdr not in pool and defer called + // test header not in pool and defer called err := mp.SaveLastNotarizedHeader(metaHdr) assert.Equal(t, process.ErrMissingHeader, err) notarizedHdrs = mp.NotarizedHdrs() assert.Equal(t, firstNonce, mp.LastNotarizedHdrForShard(currHdr.ShardId).GetNonce()) - // wrong hdr type in pool and defer called + // wrong header type in pool and defer called pool.ShardHeaders().Put(currHash, metaHdr) pool.ShardHeaders().Put(prevHash, prevHdr) @@ -1911,7 +1911,7 @@ func TestMetaProcessor_CheckShardHeadersValidity(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -2131,7 +2131,7 @@ func TestMetaProcessor_CheckShardHeadersFinality(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -2245,7 +2245,7 @@ func TestMetaProcessor_IsHdrConstructionValid(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, @@ -2354,7 +2354,7 @@ func TestMetaProcessor_IsShardHeaderValidFinal(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := mp.ComputeHeaderHash(mp.LastNotarizedHdrForShard(0).(*block.Header)) prevHdr := &block.Header{ Round: 10, diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 462da745f06..7a18d9e0757 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -1554,7 +1554,7 @@ func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round sp.blockSizeThrottler.Add( round, - uint32(core.Max(int32(header.ItemsInBody()), int32(header.ItemsInHeader())))) + core.MaxUint32(header.ItemsInBody(), header.ItemsInHeader())) return header, nil } @@ -1701,7 +1701,7 @@ func (sp *shardProcessor) getMaxMiniBlocksSpaceRemained( ) int32 { mbSpaceRemainedInBlock := int32(maxItemsInBlock) - int32(itemsAddedInBlock) mbSpaceRemainedInCache := int32(core.MaxMiniBlocksInBlock) - int32(miniBlocksAddedInBlock) - maxMbSpaceRemained := core.Min(mbSpaceRemainedInBlock, mbSpaceRemainedInCache) + maxMbSpaceRemained := core.MinInt32(mbSpaceRemainedInBlock, mbSpaceRemainedInCache) return maxMbSpaceRemained } diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index 7a5758a5229..28c273114e7 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -1721,7 +1721,7 @@ func TestShardProcessor_CommitBlockNoTxInPoolShouldErr(t *testing.T) { txHash := []byte("txHash") rootHash := []byte("root hash") - hdrHash := []byte("hdr hash") + hdrHash := []byte("header hash") hdr := &block.Header{ Nonce: 1, Round: 1, @@ -1803,7 +1803,7 @@ func TestShardProcessor_CommitBlockOkValsShouldWork(t *testing.T) { txHash := []byte("tx_hash1") rootHash := []byte("root hash") - hdrHash := []byte("hdr hash") + hdrHash := []byte("header hash") randSeed := []byte("rand seed") prevHdr := &block.Header{ @@ -1897,7 +1897,7 @@ func TestShardProcessor_CommitBlockCallsIndexerMethods(t *testing.T) { txHash := []byte("tx_hash1") rootHash := []byte("root hash") - hdrHash := []byte("hdr hash") + hdrHash := []byte("header hash") randSeed := []byte("rand seed") prevHdr := &block.Header{ @@ -2115,7 +2115,7 @@ func TestNode_ComputeNewNoncePrevHashShouldWork(t *testing.T) { } hasher.ComputeCalled = func(s string) []byte { if s == "hdrHeaderMarshalized" { - return []byte("hdr hash") + return []byte("header hash") } if s == "txBlockBodyMarshalized" { return []byte("tx block body hash") @@ -2542,13 +2542,16 @@ func TestShardProcessor_ReceivedMetaBlockNoMissingMiniBlocksShouldPass(t *testin miniBlockHash1 := []byte("miniblock hash 1 found in cache") - metaBlock := mock.HeaderHandlerStub{ - GetMiniBlockHeadersWithDstCalled: func(destId uint32) map[string]uint32 { - return map[string]uint32{ - string(miniBlockHash1): 0, - } - }, - } + metaBlock := &block.MetaBlock{ + Nonce: 1, + Round: 1, + ShardInfo: []block.ShardData{ + block.ShardData{ + ShardId: 1, + ShardMiniBlockHeaders: []block.ShardMiniBlockHeader{ + block.ShardMiniBlockHeader{Hash: miniBlockHash1, SenderShardId: 1, ReceiverShardId: 0}, + }}, + }} //put this metaBlock inside datapool metaBlockHash := []byte("metablock hash") @@ -3179,7 +3182,7 @@ func TestShardProcessor_IsHdrConstructionValid(t *testing.T) { //put the existing headers inside datapool - //hdr shard 0 + //header shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, @@ -3288,7 +3291,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { RandSeed: prevRandSeed} notarizedHdrs[sharding.MetachainShardId] = append(notarizedHdrs[sharding.MetachainShardId], lastHdr) - //hdr shard 0 + //header shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, @@ -3313,7 +3316,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { mbHeaders := make([]block.MiniBlockHeader, 0) blockHeader := &block.Header{} - // test hdr not in pool and defer called + // test header not in pool and defer called processedMetaHdrs, err := sp.GetProcessedMetaBlocksFromHeader(blockHeader) assert.Nil(t, err) @@ -3328,7 +3331,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { assert.Equal(t, firstNonce, sp.LastNotarizedHdrForShard(sharding.MetachainShardId).GetNonce()) assert.Equal(t, 0, len(processedMetaHdrs)) - // wrong hdr type in pool and defer called + // wrong header type in pool and defer called dataPool.MetaBlocks().Put(currHash, shardHdr) sp.SetHdrForCurrentBlock(currHash, shardHdr, true) @@ -3480,7 +3483,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNotAllMBFinished(t *tes miniBlocks := make([]block.MiniBlock, 0) miniBlocks = append(miniBlocks, miniblock1, miniblock2) - //hdr shard 0 + //header shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, @@ -3615,7 +3618,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrAllMBFinished(t *testin miniBlocks := make([]block.MiniBlock, 0) miniBlocks = append(miniBlocks, miniblock1, miniblock2) - //hdr shard 0 + //header shard 0 prevHash, _ := sp.ComputeHeaderHash(sp.LastNotarizedHdrForShard(sharding.MetachainShardId).(*block.MetaBlock)) prevHdr := &block.MetaBlock{ Round: 10, diff --git a/process/mock/headerHandlerStub.go b/process/mock/headerHandlerStub.go deleted file mode 100644 index b35061cb422..00000000000 --- a/process/mock/headerHandlerStub.go +++ /dev/null @@ -1,117 +0,0 @@ -package mock - -type HeaderHandlerStub struct { - GetMiniBlockHeadersWithDstCalled func(destId uint32) map[string]uint32 -} - -func (hhs *HeaderHandlerStub) GetEpoch() uint32 { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetRootHash() []byte { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetPrevHash() []byte { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetPrevRandSeed() []byte { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetRandSeed() []byte { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetPubKeysBitmap() []byte { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetSignature() []byte { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetTimeStamp() uint64 { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetTxCount() uint32 { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetNonce(n uint64) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetEpoch(e uint32) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetRound(r uint64) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetTimeStamp(ts uint64) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetRootHash(rHash []byte) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetPrevHash(pvHash []byte) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetPrevRandSeed(pvRandSeed []byte) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetRandSeed(randSeed []byte) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetPubKeysBitmap(pkbm []byte) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetSignature(sg []byte) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) SetTxCount(txCount uint32) { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) ItemsInBody() uint32 { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) ItemsInHeader() uint32 { - panic("implement me") -} - -func (hhs *HeaderHandlerStub) GetShardID() uint32 { - return 1 -} - -func (hhs *HeaderHandlerStub) GetNonce() uint64 { - return 1 -} - -func (hhs *HeaderHandlerStub) GetRound() uint64 { - return 1 -} - -func (hhs *HeaderHandlerStub) GetMiniBlockHeadersWithDst(destId uint32) map[string]uint32 { - return hhs.GetMiniBlockHeadersWithDstCalled(destId) -} - -// IsInterfaceNil returns true if there is no value under the interface -func (hhs *HeaderHandlerStub) IsInterfaceNil() bool { - if hhs == nil { - return true - } - return false -} diff --git a/process/throttle/block.go b/process/throttle/block.go index bf7c7fe553e..f5f37147c98 100644 --- a/process/throttle/block.go +++ b/process/throttle/block.go @@ -112,7 +112,7 @@ func (bst *blockSizeThrottle) getMaxItemsWhenSucceed(lastActionMaxItems uint32) return noOfMaxItemsUsedWithoutSucceed } - increasedNoOfItems := uint32(core.Max(1, int32(float32(noOfMaxItemsUsedWithoutSucceed-lastActionMaxItems)*jumpAboveFactor))) + increasedNoOfItems := core.MaxUint32(1, uint32(float32(noOfMaxItemsUsedWithoutSucceed-lastActionMaxItems)*jumpAboveFactor)) return lastActionMaxItems + increasedNoOfItems } @@ -136,7 +136,7 @@ func (bst *blockSizeThrottle) getMaxItemsWhenNotSucceed(lastActionMaxItems uint3 return noOfMaxItemsUsedWithSucceed } - decreasedNoOfItems := uint32(core.Max(1, int32(float32(lastActionMaxItems-noOfMaxItemsUsedWithSucceed)*jumpBelowFactor))) + decreasedNoOfItems := core.MaxUint32(1, uint32(float32(lastActionMaxItems-noOfMaxItemsUsedWithSucceed)*jumpBelowFactor)) return lastActionMaxItems - decreasedNoOfItems } diff --git a/process/throttle/block_test.go b/process/throttle/block_test.go index 732ca9c29e3..de7527c3680 100644 --- a/process/throttle/block_test.go +++ b/process/throttle/block_test.go @@ -134,7 +134,7 @@ func TestBlockSizeThrottle_ComputeMaxItemsShouldSetMaxItemsToMinItemsInBlockWhen func TestBlockSizeThrottle_ComputeMaxItemsShouldSetMaxItemsToADecreasedValueWhenLastActionNotSucceed(t *testing.T) { bst, _ := throttle.NewBlockSizeThrottle() - lastActionMaxItems1 := uint32(core.Max(12000, process.MinItemsInBlock)) + lastActionMaxItems1 := core.MaxUint32(12000, process.MinItemsInBlock) bst.SetMaxItems(lastActionMaxItems1) bst.Add(2, 0) bst.SetSucceed(2, false) @@ -143,7 +143,7 @@ func TestBlockSizeThrottle_ComputeMaxItemsShouldSetMaxItemsToADecreasedValueWhen assert.Equal(t, decreasedValue, bst.MaxItemsToAdd()) bst.SetSucceed(2, true) - lastActionMaxItems2 := uint32(core.Max(14000, process.MinItemsInBlock)) + lastActionMaxItems2 := core.MaxUint32(14000, process.MinItemsInBlock) bst.SetMaxItems(lastActionMaxItems2) bst.Add(3, 0) bst.SetSucceed(3, false) @@ -179,12 +179,12 @@ func TestBlockSizeThrottle_GetMaxItemsWhenSucceedShouldReturnNoOfMaxItemsUsedWit func TestBlockSizeThrottle_GetMaxItemsWhenSucceedShouldIncreaseMaxItemsWithAtLeastOneUnit(t *testing.T) { bst, _ := throttle.NewBlockSizeThrottle() - maxItemsUsedWithoutSucceed := uint32(core.Min(process.MinItemsInBlock+1, process.MaxItemsInBlock)) + maxItemsUsedWithoutSucceed := core.MinUint32(process.MinItemsInBlock+1, process.MaxItemsInBlock) bst.SetMaxItems(maxItemsUsedWithoutSucceed) bst.Add(2, 0) maxItemsWhenSucceed := bst.GetMaxItemsWhenSucceed(process.MinItemsInBlock) - assert.Equal(t, uint32(core.Min(process.MinItemsInBlock+1, process.MaxItemsInBlock)), maxItemsWhenSucceed) + assert.Equal(t, core.MinUint32(process.MinItemsInBlock+1, process.MaxItemsInBlock), maxItemsWhenSucceed) } func TestBlockSizeThrottle_GetMaxItemsWhenSucceedShouldIncreaseMaxItems(t *testing.T) { @@ -258,7 +258,7 @@ func TestBlockSizeThrottle_GetMaxItemsWhenNotSucceedShouldDecreaseMaxItemsWithAt func TestBlockSizeThrottle_GetMaxItemsWhenNotSucceedShouldDecreaseMaxItems(t *testing.T) { bst, _ := throttle.NewBlockSizeThrottle() - maxItemsUsedWithSucceed := uint32(core.Max(7000, process.MinItemsInBlock)) + maxItemsUsedWithSucceed := core.MaxUint32(7000, process.MinItemsInBlock) bst.SetMaxItems(maxItemsUsedWithSucceed) bst.Add(2, 0) bst.SetSucceed(2, true) From 140578d836590e70e613b7769833a55465c485cf Mon Sep 17 00:00:00 2001 From: Sebastian Marian Date: Fri, 4 Oct 2019 20:06:29 +0300 Subject: [PATCH 10/10] * Fixed after review --- core/computers.go | 8 +- process/block/export_test.go | 20 ++-- process/block/shardblock.go | 179 +++++++++++++++++-------------- process/block/shardblock_test.go | 20 ++-- process/common.go | 11 ++ process/common_test.go | 19 ++++ process/interface.go | 2 +- 7 files changed, 160 insertions(+), 99 deletions(-) diff --git a/core/computers.go b/core/computers.go index e06d1742b98..d04b880699f 100644 --- a/core/computers.go +++ b/core/computers.go @@ -1,6 +1,6 @@ package core -// MaxInt32 returns the maximum number between two given +// MaxInt32 returns the maximum of two given numbers func MaxInt32(a int32, b int32) int32 { if a > b { return a @@ -8,7 +8,7 @@ func MaxInt32(a int32, b int32) int32 { return b } -// MinInt32 returns the minimum number between two given +// MinInt32 returns the minimum of two given numbers func MinInt32(a int32, b int32) int32 { if a < b { return a @@ -16,7 +16,7 @@ func MinInt32(a int32, b int32) int32 { return b } -// MaxUint32 returns the maximum number between two given +// MaxUint32 returns the maximum of two given numbers func MaxUint32(a uint32, b uint32) uint32 { if a > b { return a @@ -24,7 +24,7 @@ func MaxUint32(a uint32, b uint32) uint32 { return b } -// MinUint32 returns the minimum number between two given +// MinUint32 returns the minimum of two given numbers func MinUint32(a uint32, b uint32) uint32 { if a < b { return a diff --git a/process/block/export_test.go b/process/block/export_test.go index 08856ae8b10..1e4b5b3db2e 100644 --- a/process/block/export_test.go +++ b/process/block/export_test.go @@ -44,8 +44,8 @@ func (sp *shardProcessor) CreateMiniBlocks(noShards uint32, maxItemsInBlock uint return sp.createMiniBlocks(noShards, maxItemsInBlock, round, haveTime) } -func (sp *shardProcessor) GetProcessedMetaBlocksFromHeader(header *block.Header) ([]data.HeaderHandler, error) { - return sp.getProcessedMetaBlocksFromHeader(header) +func (sp *shardProcessor) GetOrderedProcessedMetaBlocksFromHeader(header *block.Header) ([]data.HeaderHandler, error) { + return sp.getOrderedProcessedMetaBlocksFromHeader(header) } func (sp *shardProcessor) RemoveProcessedMetaBlocksFromPool(processedMetaHdrs []data.HeaderHandler) error { @@ -245,8 +245,8 @@ func (sp *shardProcessor) GetHashAndHdrStruct(header data.HeaderHandler, hash [] return &hashAndHdr{header, hash} } -func (sp *shardProcessor) RequestFinalMissingHeaders() uint32 { - return sp.requestFinalMissingHeaders() +func (sp *shardProcessor) RequestMissingFinalityAttestingHeaders() uint32 { + return sp.requestMissingFinalityAttestingHeaders() } func (sp *shardProcessor) CheckMetaHeadersValidityAndFinality() error { @@ -270,8 +270,8 @@ func (bp *baseProcessor) SetBlockSizeThrottler(blockSizeThrottler process.BlockS bp.blockSizeThrottler = blockSizeThrottler } -func (sp *shardProcessor) SetCurrHighestMetaHdrNonce(value uint64) { - sp.currHighestMetaHdrNonce = value +func (sp *shardProcessor) SetHighestHdrNonceForCurrentBlock(value uint64) { + sp.hdrsForCurrBlock.highestHdrNonce = value } func (sp *shardProcessor) DisplayLogInfo( @@ -324,3 +324,11 @@ func (sp *shardProcessor) CalculateRoundDuration( ) uint64 { return sp.calculateRoundDuration(lastBlockTimestamp, currentBlockTimestamp, lastBlockRound, currentBlockRound) } + +func (sp *shardProcessor) CreateBlockStarted() { + sp.createBlockStarted() +} + +func (sp *shardProcessor) AddProcessedCrossMiniBlocksFromHeader(header *block.Header) error { + return sp.addProcessedCrossMiniBlocksFromHeader(header) +} diff --git a/process/block/shardblock.go b/process/block/shardblock.go index 92457724ea6..b5e3c76b3f8 100644 --- a/process/block/shardblock.go +++ b/process/block/shardblock.go @@ -32,10 +32,11 @@ type hdrInfo struct { } type hdrForBlock struct { - missingHdrs uint32 - missingFinalHdrs uint32 - mutHdrsForBlock sync.RWMutex - hdrHashAndInfo map[string]*hdrInfo + missingHdrs uint32 + missingFinalityAttestingHdrs uint32 + highestHdrNonce uint64 + mutHdrsForBlock sync.RWMutex + hdrHashAndInfo map[string]*hdrInfo } // shardProcessor implements shardProcessor interface and actually it tries to execute block @@ -44,9 +45,8 @@ type shardProcessor struct { dataPool dataRetriever.PoolsHolder metaBlockFinality int - chRcvAllMetaHdrs chan bool - hdrsForCurrBlock hdrForBlock - currHighestMetaHdrNonce uint64 + chRcvAllMetaHdrs chan bool + hdrsForCurrBlock hdrForBlock processedMiniBlocks map[string]map[string]struct{} mutProcessedMiniBlocks sync.RWMutex @@ -205,9 +205,9 @@ func (sp *shardProcessor) ProcessBlock( return err } - sp.CreateBlockStarted() + sp.createBlockStarted() sp.txCoordinator.RequestBlockTransactions(body) - requestedMetaHdrs, requestedFinalMetaHdrs := sp.requestMetaHeaders(header) + requestedMetaHdrs, requestedFinalityAttestingMetaHdrs := sp.requestMetaHeaders(header) if haveTime() < 0 { return process.ErrTimeIsOut @@ -218,14 +218,17 @@ func (sp *shardProcessor) ProcessBlock( return err } - if requestedMetaHdrs > 0 || requestedFinalMetaHdrs > 0 { - log.Info(fmt.Sprintf("requested %d missing meta headers and %d final meta headers\n", requestedMetaHdrs, requestedFinalMetaHdrs)) + if requestedMetaHdrs > 0 || requestedFinalityAttestingMetaHdrs > 0 { + log.Info(fmt.Sprintf("requested %d missing meta headers and %d finality attesting meta headers\n", + requestedMetaHdrs, + requestedFinalityAttestingMetaHdrs)) + err = sp.waitForMetaHdrHashes(haveTime()) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() missingHdrs := sp.hdrsForCurrBlock.missingHdrs sp.hdrsForCurrBlock.missingHdrs = 0 - sp.hdrsForCurrBlock.missingFinalHdrs = 0 + sp.hdrsForCurrBlock.missingFinalityAttestingHdrs = 0 sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() if requestedMetaHdrs > 0 { @@ -261,7 +264,7 @@ func (sp *shardProcessor) ProcessBlock( } }() - processedMetaHdrs, err := sp.getProcessedMetaBlocksFromMiniBlocks(body) + processedMetaHdrs, err := sp.getOrderedProcessedMetaBlocksFromMiniBlocks(body) if err != nil { return err } @@ -320,7 +323,7 @@ func (sp *shardProcessor) checkMetaHeadersValidityAndFinality() error { return err } - usedMetaHdrs, err := sp.sortHdrsForCurrentBlock(true) + usedMetaHdrs, err := sp.sortMetaHeadersForCurrentBlockByNonce(true) if err != nil { return err } @@ -352,7 +355,7 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error return process.ErrNilBlockHeader } - finalMetaHdrs, err := sp.sortHdrsForCurrentBlock(false) + finalityAttestingMetaHdrs, err := sp.sortMetaHeadersForCurrentBlockByNonce(false) if err != nil { return err } @@ -360,14 +363,14 @@ func (sp *shardProcessor) checkMetaHdrFinality(header data.HeaderHandler) error lastVerifiedHdr := header // verify if there are "K" block after current to make this one final nextBlocksVerified := 0 - for _, metaHdr := range finalMetaHdrs { + for _, metaHdr := range finalityAttestingMetaHdrs { if nextBlocksVerified >= sp.metaBlockFinality { break } // found a header with the next nonce if metaHdr.Nonce == lastVerifiedHdr.GetNonce()+1 { - err := sp.isHdrConstructionValid(metaHdr, lastVerifiedHdr) + err = sp.isHdrConstructionValid(metaHdr, lastVerifiedHdr) if err != nil { log.Debug(err.Error()) continue @@ -629,7 +632,7 @@ func (sp *shardProcessor) restoreMetaBlockIntoPool(miniBlockHashes map[string]ui // as long as the transactions limit for the block has not been reached and there is still time to add transactions func (sp *shardProcessor) CreateBlockBody(round uint64, haveTime func() bool) (data.BodyHandler, error) { log.Debug(fmt.Sprintf("started creating block body in round %d\n", round)) - sp.CreateBlockStarted() + sp.createBlockStarted() sp.blockSizeThrottler.ComputeMaxItems() miniBlocks, err := sp.createMiniBlocks(sp.shardCoordinator.NumberOfShards(), sp.blockSizeThrottler.MaxItemsToAdd(), round, haveTime) @@ -722,7 +725,12 @@ func (sp *shardProcessor) CommitBlock( log.LogIfError(errNotCritical) } - processedMetaHdrs, err := sp.getProcessedMetaBlocksFromHeader(header) + processedMetaHdrs, err := sp.getOrderedProcessedMetaBlocksFromHeader(header) + if err != nil { + return err + } + + err = sp.addProcessedCrossMiniBlocksFromHeader(header) if err != nil { return err } @@ -824,9 +832,7 @@ func (sp *shardProcessor) getHighestHdrForOwnShardFromMetachain( ownShIdHdrs := make([]data.HeaderHandler, 0) - sort.Slice(processedHdrs, func(i, j int) bool { - return processedHdrs[i].GetNonce() < processedHdrs[j].GetNonce() - }) + process.SortHeadersByNonce(processedHdrs) for i := 0; i < len(processedHdrs); i++ { hdr, ok := processedHdrs[i].(*block.MetaBlock) @@ -846,9 +852,7 @@ func (sp *shardProcessor) getHighestHdrForOwnShardFromMetachain( ownShIdHdrs = append(ownShIdHdrs, &block.Header{}) } - sort.Slice(ownShIdHdrs, func(i, j int) bool { - return ownShIdHdrs[i].GetNonce() < ownShIdHdrs[j].GetNonce() - }) + process.SortHeadersByNonce(ownShIdHdrs) ownShIdHdrsHashes := make([][]byte, 0) for i := 0; i < len(ownShIdHdrs); i++ { @@ -891,8 +895,8 @@ func (sp *shardProcessor) getHighestHdrForShardFromMetachain(shardId uint32, hdr return ownShIdHdr, nil } -// getProcessedMetaBlocksFromHeader returns all the meta blocks fully processed -func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) ([]data.HeaderHandler, error) { +// getOrderedProcessedMetaBlocksFromHeader returns all the meta blocks fully processed +func (sp *shardProcessor) getOrderedProcessedMetaBlocksFromHeader(header *block.Header) ([]data.HeaderHandler, error) { if header == nil { return nil, process.ErrNilBlockHeader } @@ -904,11 +908,24 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) log.Debug(fmt.Sprintf("cross mini blocks in body: %d\n", len(miniBlockHashes))) - processedMetaBlocks, processedCrossMiniBlocksHashes, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) + processedMetaBlocks, err := sp.getOrderedProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) if err != nil { return nil, err } + return processedMetaBlocks, nil +} + +func (sp *shardProcessor) addProcessedCrossMiniBlocksFromHeader(header *block.Header) error { + if header == nil { + return process.ErrNilBlockHeader + } + + miniBlockHashes := make(map[int][]byte, 0) + for i := 0; i < len(header.MiniBlockHeaders); i++ { + miniBlockHashes[i] = header.MiniBlockHeaders[i].Hash + } + sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() for metaBlockHash, hdrInfo := range sp.hdrsForCurrBlock.hdrHashAndInfo { if !hdrInfo.usedInBlock { @@ -918,23 +935,28 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromHeader(header *block.Header) metaBlock, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return nil, process.ErrWrongTypeAssertion + return process.ErrWrongTypeAssertion } crossMiniBlockHashes := metaBlock.GetMiniBlockHeadersWithDst(sp.shardCoordinator.SelfId()) - for hash := range crossMiniBlockHashes { - if processedCrossMiniBlocksHashes[hash] { - sp.addProcessedMiniBlock([]byte(metaBlockHash), []byte(hash)) + for key, miniBlockHash := range miniBlockHashes { + _, ok = crossMiniBlockHashes[string(miniBlockHash)] + if !ok { + continue } + + sp.addProcessedMiniBlock([]byte(metaBlockHash), miniBlockHash) + + delete(miniBlockHashes, key) } } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return processedMetaBlocks, nil + return nil } -// getProcessedMetaBlocks returns all the meta blocks fully processed -func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlocks( +// getOrderedProcessedMetaBlocksFromMiniBlocks returns all the meta blocks fully processed ordered +func (sp *shardProcessor) getOrderedProcessedMetaBlocksFromMiniBlocks( usedMiniBlocks []*block.MiniBlock, ) ([]data.HeaderHandler, error) { @@ -954,14 +976,14 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlocks( } log.Debug(fmt.Sprintf("cross mini blocks in body: %d\n", len(miniBlockHashes))) - processedMetaBlocks, _, err := sp.getProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) + processedMetaBlocks, err := sp.getOrderedProcessedMetaBlocksFromMiniBlockHashes(miniBlockHashes) return processedMetaBlocks, err } -func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( +func (sp *shardProcessor) getOrderedProcessedMetaBlocksFromMiniBlockHashes( miniBlockHashes map[int][]byte, -) ([]data.HeaderHandler, map[string]bool, error) { +) ([]data.HeaderHandler, error) { processedMetaHdrs := make([]data.HeaderHandler, 0) processedCrossMiniBlocksHashes := make(map[string]bool) @@ -975,7 +997,7 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( metaBlock, ok := hdrInfo.hdr.(*block.MetaBlock) if !ok { sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - return nil, nil, process.ErrWrongTypeAssertion + return nil, process.ErrWrongTypeAssertion } log.Debug(fmt.Sprintf("meta header nonce: %d\n", metaBlock.Nonce)) @@ -1012,13 +1034,9 @@ func (sp *shardProcessor) getProcessedMetaBlocksFromMiniBlockHashes( } sp.hdrsForCurrBlock.mutHdrsForBlock.RUnlock() - if len(processedMetaHdrs) > 1 { - sort.Slice(processedMetaHdrs, func(i, j int) bool { - return processedMetaHdrs[i].GetNonce() < processedMetaHdrs[j].GetNonce() - }) - } + process.SortHeadersByNonce(processedMetaHdrs) - return processedMetaHdrs, processedCrossMiniBlocksHashes, nil + return processedMetaHdrs, nil } func (sp *shardProcessor) removeProcessedMetaBlocksFromPool(processedMetaHdrs []data.HeaderHandler) error { @@ -1102,33 +1120,36 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() - if sp.hdrsForCurrBlock.missingHdrs > 0 || sp.hdrsForCurrBlock.missingFinalHdrs > 0 { + haveMissingMetaHeaders := sp.hdrsForCurrBlock.missingHdrs > 0 || sp.hdrsForCurrBlock.missingFinalityAttestingHdrs > 0 + if haveMissingMetaHeaders { hdrInfoForHash := sp.hdrsForCurrBlock.hdrHashAndInfo[string(metaBlockHash)] - if hdrInfoForHash != nil && (hdrInfoForHash.hdr == nil || hdrInfoForHash.hdr.IsInterfaceNil()) { + receivedMissingMetaHeader := hdrInfoForHash != nil && (hdrInfoForHash.hdr == nil || hdrInfoForHash.hdr.IsInterfaceNil()) + if receivedMissingMetaHeader { hdrInfoForHash.hdr = metaBlock sp.hdrsForCurrBlock.missingHdrs-- - if metaBlock.Nonce > sp.currHighestMetaHdrNonce { - sp.currHighestMetaHdrNonce = metaBlock.Nonce + if metaBlock.Nonce > sp.hdrsForCurrBlock.highestHdrNonce { + sp.hdrsForCurrBlock.highestHdrNonce = metaBlock.Nonce } } + // attesting something if sp.hdrsForCurrBlock.missingHdrs == 0 { - missingFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs - sp.hdrsForCurrBlock.missingFinalHdrs = sp.requestFinalMissingHeaders() - if sp.hdrsForCurrBlock.missingFinalHdrs == 0 { - log.Info(fmt.Sprintf("received %d missing final meta headers\n", missingFinalHdrs)) + missingFinalityAttestingMetaHdrs := sp.hdrsForCurrBlock.missingFinalityAttestingHdrs + sp.hdrsForCurrBlock.missingFinalityAttestingHdrs = sp.requestMissingFinalityAttestingHeaders() + if sp.hdrsForCurrBlock.missingFinalityAttestingHdrs == 0 { + log.Info(fmt.Sprintf("received %d missing finality attesting meta headers\n", missingFinalityAttestingMetaHdrs)) } else { - log.Info(fmt.Sprintf("requested %d missing final meta headers\n", sp.hdrsForCurrBlock.missingFinalHdrs)) + log.Info(fmt.Sprintf("requested %d missing finality attesting meta headers\n", sp.hdrsForCurrBlock.missingFinalityAttestingHdrs)) } } - missingHdrs := sp.hdrsForCurrBlock.missingHdrs - missingFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs + missingMetaHdrs := sp.hdrsForCurrBlock.missingHdrs + missingFinalityAttestingMetaHdrs := sp.hdrsForCurrBlock.missingFinalityAttestingHdrs sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - allMissingNeededHdrsReceived := missingHdrs == 0 && missingFinalHdrs == 0 - if allMissingNeededHdrsReceived { + allMissingMetaHeadersReceived := missingMetaHdrs == 0 && missingFinalityAttestingMetaHdrs == 0 + if allMissingMetaHeadersReceived { sp.chRcvAllMetaHdrs <- true } } else { @@ -1149,13 +1170,13 @@ func (sp *shardProcessor) receivedMetaBlock(metaBlockHash []byte) { sp.txCoordinator.RequestMiniBlocks(metaBlock) } -// requestFinalMissingHeaders requests the headers needed to accept the current selected headers for processing the +// requestMissingFinalityAttestingHeaders requests the headers needed to accept the current selected headers for processing the // current block. It requests the metaBlockFinality headers greater than the highest meta header related to the block // which should be processed -func (sp *shardProcessor) requestFinalMissingHeaders() uint32 { +func (sp *shardProcessor) requestMissingFinalityAttestingHeaders() uint32 { requestedBlockHeaders := uint32(0) - for i := sp.currHighestMetaHdrNonce + 1; i <= sp.currHighestMetaHdrNonce+uint64(sp.metaBlockFinality); i++ { - if sp.currHighestMetaHdrNonce == uint64(0) { + for i := sp.hdrsForCurrBlock.highestHdrNonce + 1; i <= sp.hdrsForCurrBlock.highestHdrNonce+uint64(sp.metaBlockFinality); i++ { + if sp.hdrsForCurrBlock.highestHdrNonce == uint64(0) { continue } @@ -1192,19 +1213,18 @@ func (sp *shardProcessor) requestMetaHeaders(header *block.Header) (uint32, uint } if sp.hdrsForCurrBlock.missingHdrs == 0 { - sp.hdrsForCurrBlock.missingFinalHdrs = sp.requestFinalMissingHeaders() + sp.hdrsForCurrBlock.missingFinalityAttestingHdrs = sp.requestMissingFinalityAttestingHeaders() } requestedHdrs := sp.hdrsForCurrBlock.missingHdrs - requestedFinalHdrs := sp.hdrsForCurrBlock.missingFinalHdrs + requestedFinalityAttestingHdrs := sp.hdrsForCurrBlock.missingFinalityAttestingHdrs sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() - return requestedHdrs, requestedFinalHdrs + return requestedHdrs, requestedFinalityAttestingHdrs } func (sp *shardProcessor) computeMissingAndExistingMetaHeaders(header *block.Header) [][]byte { missingHeadersHashes := make([][]byte, 0) - sp.currHighestMetaHdrNonce = uint64(0) sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() for i := 0; i < len(header.MetaBlockHashes); i++ { @@ -1220,8 +1240,8 @@ func (sp *shardProcessor) computeMissingAndExistingMetaHeaders(header *block.Hea sp.hdrsForCurrBlock.hdrHashAndInfo[string(header.MetaBlockHashes[i])] = &hdrInfo{hdr: hdr, usedInBlock: true} - if hdr.Nonce > sp.currHighestMetaHdrNonce { - sp.currHighestMetaHdrNonce = hdr.Nonce + if hdr.Nonce > sp.hdrsForCurrBlock.highestHdrNonce { + sp.hdrsForCurrBlock.highestHdrNonce = hdr.Nonce } } sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() @@ -1495,12 +1515,12 @@ func (sp *shardProcessor) createMiniBlocks( return nil, process.ErrNilTransactionPool } - destMeMiniBlocks, txs, hdrs, err := sp.createAndProcessCrossMiniBlocksDstMe(noShards, maxItemsInBlock, round, haveTime) + destMeMiniBlocks, nbTxs, nbHdrs, err := sp.createAndProcessCrossMiniBlocksDstMe(noShards, maxItemsInBlock, round, haveTime) if err != nil { log.Info(err.Error()) } - processedMetaHdrs, errNotCritical := sp.getProcessedMetaBlocksFromMiniBlocks(destMeMiniBlocks) + processedMetaHdrs, errNotCritical := sp.getOrderedProcessedMetaBlocksFromMiniBlocks(destMeMiniBlocks) if errNotCritical != nil { log.Debug(errNotCritical.Error()) } @@ -1510,16 +1530,16 @@ func (sp *shardProcessor) createMiniBlocks( return nil, err } - log.Info(fmt.Sprintf("processed %d miniblocks and %d txs with destination in self shard\n", len(destMeMiniBlocks), txs)) + log.Info(fmt.Sprintf("processed %d miniblocks and %d txs with destination in self shard\n", len(destMeMiniBlocks), nbTxs)) if len(destMeMiniBlocks) > 0 { miniBlocks = append(miniBlocks, destMeMiniBlocks...) } - maxTxSpaceRemained := int32(maxItemsInBlock) - int32(txs) + maxTxSpaceRemained := int32(maxItemsInBlock) - int32(nbTxs) maxMbSpaceRemained := sp.getMaxMiniBlocksSpaceRemained( maxItemsInBlock, - uint32(len(destMeMiniBlocks))+hdrs, + uint32(len(destMeMiniBlocks))+nbHdrs, uint32(len(miniBlocks))) mbFromMe := sp.txCoordinator.CreateMbsAndProcessTransactionsFromMe( @@ -1587,7 +1607,7 @@ func (sp *shardProcessor) CreateBlockHeader(bodyHandler data.BodyHandler, round sp.appStatusHandler.SetUInt64Value(core.MetricNumTxInBlock, uint64(totalTxCount)) sp.appStatusHandler.SetUInt64Value(core.MetricNumMiniBlocks, uint64(len(body))) - header.MetaBlockHashes = sp.sortHdrsHashesForCurrentBlock(true) + header.MetaBlockHashes = sp.sortMetaHeaderHashesForCurrentBlockByNonce(true) sp.blockSizeThrottler.Add( round, @@ -1743,17 +1763,19 @@ func (sp *shardProcessor) getMaxMiniBlocksSpaceRemained( return maxMbSpaceRemained } -func (sp *shardProcessor) CreateBlockStarted() { +func (sp *shardProcessor) createBlockStarted() { sp.txCoordinator.CreateBlockStarted() sp.hdrsForCurrBlock.mutHdrsForBlock.Lock() sp.hdrsForCurrBlock.missingHdrs = 0 - sp.hdrsForCurrBlock.missingFinalHdrs = 0 + sp.hdrsForCurrBlock.missingFinalityAttestingHdrs = 0 + sp.hdrsForCurrBlock.highestHdrNonce = 0 sp.hdrsForCurrBlock.hdrHashAndInfo = make(map[string]*hdrInfo) sp.hdrsForCurrBlock.mutHdrsForBlock.Unlock() } -func (sp *shardProcessor) sortHdrsForCurrentBlock(usedInBlock bool) ([]*block.MetaBlock, error) { +//TODO: remove bool parameter and give instead the set to sort +func (sp *shardProcessor) sortMetaHeadersForCurrentBlockByNonce(usedInBlock bool) ([]*block.MetaBlock, error) { hdrsForCurrentBlock := make([]*block.MetaBlock, 0) sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() @@ -1781,7 +1803,8 @@ func (sp *shardProcessor) sortHdrsForCurrentBlock(usedInBlock bool) ([]*block.Me return hdrsForCurrentBlock, nil } -func (sp *shardProcessor) sortHdrsHashesForCurrentBlock(usedInBlock bool) [][]byte { +//TODO: remove bool parameter and give instead the set to sort +func (sp *shardProcessor) sortMetaHeaderHashesForCurrentBlockByNonce(usedInBlock bool) [][]byte { hdrsForCurrentBlockInfo := make([]*nonceAndHashInfo, 0) sp.hdrsForCurrBlock.mutHdrsForBlock.RLock() diff --git a/process/block/shardblock_test.go b/process/block/shardblock_test.go index f6c0a1d0db1..d1e8da10797 100644 --- a/process/block/shardblock_test.go +++ b/process/block/shardblock_test.go @@ -1344,8 +1344,8 @@ func TestShardProcessor_IsMetaHeaderFinalShouldPass(t *testing.T) { assert.True(t, res) } -//-------- requestFinalMissingHeaders -func TestShardProcessor_RequestFinalMissingHeaders(t *testing.T) { +//-------- requestMissingFinalityAttestingHeaders +func TestShardProcessor_RequestMissingFinalityAttestingHeaders(t *testing.T) { t.Parallel() tdp := mock.NewPoolsHolderMock() @@ -1353,8 +1353,8 @@ func TestShardProcessor_RequestFinalMissingHeaders(t *testing.T) { arguments.DataPool = tdp sp, _ := blproc.NewShardProcessor(arguments) - sp.SetCurrHighestMetaHdrNonce(1) - res := sp.RequestFinalMissingHeaders() + sp.SetHighestHdrNonceForCurrentBlock(1) + res := sp.RequestMissingFinalityAttestingHeaders() assert.Equal(t, res > 0, true) } @@ -2964,7 +2964,7 @@ func TestShardProcessor_GetProcessedMetaBlockFromPoolShouldWork(t *testing.T) { blockHeader := &block.Header{MetaBlockHashes: hashes, MiniBlockHeaders: mbHeaders} - _, err := bp.GetProcessedMetaBlocksFromHeader(blockHeader) + err := bp.AddProcessedCrossMiniBlocksFromHeader(blockHeader) assert.Nil(t, err) //check WasMiniBlockProcessed for remaining metablocks @@ -3317,7 +3317,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { blockHeader := &block.Header{} // test header not in pool and defer called - processedMetaHdrs, err := sp.GetProcessedMetaBlocksFromHeader(blockHeader) + processedMetaHdrs, err := sp.GetOrderedProcessedMetaBlocksFromHeader(blockHeader) assert.Nil(t, err) err = sp.SaveLastNotarizedHeader(sharding.MetachainShardId, processedMetaHdrs) @@ -3339,7 +3339,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { hashes = append(hashes, currHash) blockHeader = &block.Header{MetaBlockHashes: hashes, MiniBlockHeaders: mbHeaders} - processedMetaHdrs, err = sp.GetProcessedMetaBlocksFromHeader(blockHeader) + processedMetaHdrs, err = sp.GetOrderedProcessedMetaBlocksFromHeader(blockHeader) assert.Equal(t, process.ErrWrongTypeAssertion, err) err = sp.SaveLastNotarizedHeader(sharding.MetachainShardId, processedMetaHdrs) @@ -3365,7 +3365,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNoDstMB(t *testing.T) { hashes = append(hashes, prevHash) blockHeader = &block.Header{MetaBlockHashes: hashes, MiniBlockHeaders: mbHeaders} - processedMetaHdrs, err = sp.GetProcessedMetaBlocksFromHeader(blockHeader) + processedMetaHdrs, err = sp.GetOrderedProcessedMetaBlocksFromHeader(blockHeader) assert.Nil(t, err) err = sp.SaveLastNotarizedHeader(sharding.MetachainShardId, processedMetaHdrs) @@ -3520,7 +3520,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrNotAllMBFinished(t *tes hashes = append(hashes, prevHash) blockHeader := &block.Header{MetaBlockHashes: hashes, MiniBlockHeaders: mbHeaders} - processedMetaHdrs, err := sp.GetProcessedMetaBlocksFromHeader(blockHeader) + processedMetaHdrs, err := sp.GetOrderedProcessedMetaBlocksFromHeader(blockHeader) assert.Nil(t, err) err = sp.SaveLastNotarizedHeader(sharding.MetachainShardId, processedMetaHdrs) @@ -3660,7 +3660,7 @@ func TestShardProcessor_RemoveAndSaveLastNotarizedMetaHdrAllMBFinished(t *testin hashes = append(hashes, prevHash) blockHeader := &block.Header{MetaBlockHashes: hashes, MiniBlockHeaders: mbHeaders} - processedMetaHdrs, err := sp.GetProcessedMetaBlocksFromHeader(blockHeader) + processedMetaHdrs, err := sp.GetOrderedProcessedMetaBlocksFromHeader(blockHeader) assert.Nil(t, err) assert.Equal(t, 2, len(processedMetaHdrs)) diff --git a/process/common.go b/process/common.go index 5cca6b46cd1..840667a59df 100644 --- a/process/common.go +++ b/process/common.go @@ -1,6 +1,8 @@ package process import ( + "sort" + "github.com/ElrondNetwork/elrond-go/data" "github.com/ElrondNetwork/elrond-go/data/block" "github.com/ElrondNetwork/elrond-go/data/transaction" @@ -552,3 +554,12 @@ func getHeaderHashFromStorageWithNonce( return hash, nil } + +// SortHeadersByNonce will sort a given list of headers by nonce +func SortHeadersByNonce(headers []data.HeaderHandler) { + if len(headers) > 1 { + sort.Slice(headers, func(i, j int) bool { + return headers[i].GetNonce() < headers[j].GetNonce() + }) + } +} diff --git a/process/common_test.go b/process/common_test.go index c8baa447161..42bad1ed51f 100644 --- a/process/common_test.go +++ b/process/common_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/ElrondNetwork/elrond-go/data" "github.com/ElrondNetwork/elrond-go/data/block" "github.com/ElrondNetwork/elrond-go/data/transaction" "github.com/ElrondNetwork/elrond-go/dataRetriever" @@ -2110,3 +2111,21 @@ func TestGetTransactionHandlerFromStorageShouldWork(t *testing.T) { assert.Nil(t, err) assert.Equal(t, txFromPool, tx) } + +func TestSortHeadersByNonceShouldWork(t *testing.T) { + headers := []data.HeaderHandler{ + &block.Header{Nonce: 3}, + &block.Header{Nonce: 2}, + &block.Header{Nonce: 1}, + } + + assert.Equal(t, uint64(3), headers[0].GetNonce()) + assert.Equal(t, uint64(2), headers[1].GetNonce()) + assert.Equal(t, uint64(1), headers[2].GetNonce()) + + process.SortHeadersByNonce(headers) + + assert.Equal(t, uint64(1), headers[0].GetNonce()) + assert.Equal(t, uint64(2), headers[1].GetNonce()) + assert.Equal(t, uint64(3), headers[2].GetNonce()) +} diff --git a/process/interface.go b/process/interface.go index 3c124ceebbb..f0b6c932381 100644 --- a/process/interface.go +++ b/process/interface.go @@ -399,7 +399,7 @@ type PoolsCleaner interface { IsInterfaceNil() bool } -// InterceptorThrottler can determine if the a new go routine can start +// InterceptorThrottler can determine if a new go routine can start type InterceptorThrottler interface { CanProcess() bool StartProcessing()