New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hardfork: execute pending txs in correct order #2471
Merged
LucianMincu
merged 4 commits into
development
from
Hardfork-execute-pending-txs-in-correct-order
Nov 18, 2020
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
9264c15
* Implemented a fix in Hardfork mechanism, which would execute all pe…
SebastianMarian 86b3e32
* Fixed after review
SebastianMarian d51971a
Merge branch 'development' into Hardfork-execute-pending-txs-in-corre…
SebastianMarian de32108
* Added unit tests
SebastianMarian File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package update | ||
|
||
import ( | ||
"github.com/ElrondNetwork/elrond-go/data" | ||
"github.com/ElrondNetwork/elrond-go/data/block" | ||
) | ||
|
||
// TxInfo defines the structure which hold the tx info | ||
type TxInfo struct { | ||
MbHash []byte | ||
TxHash []byte | ||
Tx data.TransactionHandler | ||
} | ||
|
||
// GetPendingMiniBlocks get all the pending miniBlocks from epoch start metaBlock and unFinished metaBlocks | ||
func GetPendingMiniBlocks( | ||
epochStartMetaBlock *block.MetaBlock, | ||
unFinishedMetaBlocksMap map[string]*block.MetaBlock, | ||
) ([]block.MiniBlockHeader, error) { | ||
|
||
if epochStartMetaBlock == nil { | ||
return nil, ErrNilEpochStartMetaBlock | ||
} | ||
if unFinishedMetaBlocksMap == nil { | ||
return nil, ErrNilUnFinishedMetaBlocksMap | ||
} | ||
|
||
pendingMiniBlocks := make([]block.MiniBlockHeader, 0) | ||
nonceToHashMap := createNonceToHashMap(unFinishedMetaBlocksMap) | ||
|
||
for _, shardData := range epochStartMetaBlock.EpochStart.LastFinalizedHeaders { | ||
computedPendingMiniBlocks, err := computePendingMiniBlocksFromUnFinishedMetaBlocks( | ||
shardData, | ||
unFinishedMetaBlocksMap, | ||
nonceToHashMap, | ||
epochStartMetaBlock.GetNonce(), | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
pendingMiniBlocks = append(pendingMiniBlocks, computedPendingMiniBlocks...) | ||
} | ||
|
||
return pendingMiniBlocks, nil | ||
} | ||
|
||
// createNonceToHashMap creates a map of nonce to hash from all the given metaBlocks | ||
func createNonceToHashMap(unFinishedMetaBlocks map[string]*block.MetaBlock) map[uint64]string { | ||
nonceToHashMap := make(map[uint64]string, len(unFinishedMetaBlocks)) | ||
for metaBlockHash, metaBlock := range unFinishedMetaBlocks { | ||
nonceToHashMap[metaBlock.GetNonce()] = metaBlockHash | ||
} | ||
|
||
return nonceToHashMap | ||
} | ||
|
||
// computePendingMiniBlocksFromUnFinishedMetaBlocks computes all the pending miniBlocks from unFinished metaBlocks | ||
func computePendingMiniBlocksFromUnFinishedMetaBlocks( | ||
epochStartShardData block.EpochStartShardData, | ||
unFinishedMetaBlocks map[string]*block.MetaBlock, | ||
nonceToHashMap map[uint64]string, | ||
epochStartMetaBlockNonce uint64, | ||
) ([]block.MiniBlockHeader, error) { | ||
pendingMiniBlocks := make([]block.MiniBlockHeader, 0) | ||
pendingMiniBlocks = append(pendingMiniBlocks, epochStartShardData.PendingMiniBlockHeaders...) | ||
|
||
firstPendingMetaBlock, ok := unFinishedMetaBlocks[string(epochStartShardData.FirstPendingMetaBlock)] | ||
if !ok { | ||
return nil, ErrWrongUnFinishedMetaHdrsMap | ||
} | ||
|
||
firstUnFinishedMetaBlockNonce := firstPendingMetaBlock.GetNonce() | ||
for nonce := firstUnFinishedMetaBlockNonce + 1; nonce <= epochStartMetaBlockNonce; nonce++ { | ||
metaBlockHash, exists := nonceToHashMap[nonce] | ||
if !exists { | ||
return nil, ErrWrongUnFinishedMetaHdrsMap | ||
} | ||
|
||
metaBlock, exists := unFinishedMetaBlocks[metaBlockHash] | ||
if !exists { | ||
return nil, ErrWrongUnFinishedMetaHdrsMap | ||
} | ||
|
||
pendingMiniBlocksFromMetaBlock := getAllMiniBlocksWithDst(metaBlock, epochStartShardData.ShardID) | ||
pendingMiniBlocks = append(pendingMiniBlocks, pendingMiniBlocksFromMetaBlock...) | ||
} | ||
|
||
return pendingMiniBlocks, nil | ||
} | ||
|
||
// getAllMiniBlocksWithDst returns all miniBlock headers with the given destination from the given metaBlock | ||
func getAllMiniBlocksWithDst(metaBlock *block.MetaBlock, destShardID uint32) []block.MiniBlockHeader { | ||
mbHdrs := make([]block.MiniBlockHeader, 0) | ||
for i := 0; i < len(metaBlock.ShardInfo); i++ { | ||
if metaBlock.ShardInfo[i].ShardID == destShardID { | ||
continue | ||
} | ||
|
||
for _, mbHdr := range metaBlock.ShardInfo[i].ShardMiniBlockHeaders { | ||
if mbHdr.ReceiverShardID == destShardID && mbHdr.SenderShardID != destShardID { | ||
mbHdrs = append(mbHdrs, mbHdr) | ||
} | ||
} | ||
} | ||
|
||
for _, mbHdr := range metaBlock.MiniBlockHeaders { | ||
if mbHdr.ReceiverShardID == destShardID && mbHdr.SenderShardID != destShardID { | ||
mbHdrs = append(mbHdrs, mbHdr) | ||
} | ||
} | ||
|
||
return mbHdrs | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as we have to take into account all shard ID value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually core.AllShardId refers to PeerBlock right now, and PendingTransactionProcessor does not know to process this type of miniblock. More than this, in the commented code above from line 49 this type of miniblock was also avoided in the original code. Actually, the whole file is just a copy-paste of the original one with slightly renaming here and there. We should discuss/analyze if this type of miniblock which could appear only in the start of epoch metablock (hardfork meta block) should be executed or not in the import phase or it would be executed in a normal way afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, more mental mapping to have as to not use core.AllShardId on miniblocks other than peer miniblocks because there are some edgecases.