-
Notifications
You must be signed in to change notification settings - Fork 198
/
common.go
114 lines (94 loc) · 3.62 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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
}