-
Notifications
You must be signed in to change notification settings - Fork 199
/
interceptedMiniblock.go
145 lines (117 loc) · 4.27 KB
/
interceptedMiniblock.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package interceptedBlocks
import (
"fmt"
"github.com/ElrondNetwork/elrond-go-core/core"
"github.com/ElrondNetwork/elrond-go-core/data/block"
"github.com/ElrondNetwork/elrond-go-core/hashing"
"github.com/ElrondNetwork/elrond-go-core/marshal"
"github.com/ElrondNetwork/elrond-go/process"
"github.com/ElrondNetwork/elrond-go/sharding"
)
var _ process.InterceptedData = (*InterceptedMiniblock)(nil)
// InterceptedMiniblock is a wrapper over a miniblock
type InterceptedMiniblock struct {
miniblock *block.MiniBlock
marshalizer marshal.Marshalizer
hasher hashing.Hasher
shardCoordinator sharding.Coordinator
hash []byte
isForCurrentShard bool
}
// NewInterceptedMiniblock creates a new instance of InterceptedMiniblock struct
func NewInterceptedMiniblock(arg *ArgInterceptedMiniblock) (*InterceptedMiniblock, error) {
err := checkMiniblockArgument(arg)
if err != nil {
return nil, err
}
miniblock, err := createMiniblock(arg.Marshalizer, arg.MiniblockBuff)
if err != nil {
return nil, err
}
inMiniblock := &InterceptedMiniblock{
miniblock: miniblock,
marshalizer: arg.Marshalizer,
hasher: arg.Hasher,
shardCoordinator: arg.ShardCoordinator,
}
inMiniblock.processFields(arg.MiniblockBuff)
return inMiniblock, nil
}
func createMiniblock(marshalizer marshal.Marshalizer, miniblockBuff []byte) (*block.MiniBlock, error) {
miniblock := &block.MiniBlock{}
err := marshalizer.Unmarshal(miniblock, miniblockBuff)
if err != nil {
return nil, err
}
return miniblock, nil
}
func (inMb *InterceptedMiniblock) processFields(mbBuff []byte) {
inMb.hash = inMb.hasher.Compute(string(mbBuff))
inMb.processIsForCurrentShard()
}
func (inMb *InterceptedMiniblock) processIsForCurrentShard() {
isForCurrentShardRecv := inMb.miniblock.ReceiverShardID == inMb.shardCoordinator.SelfId()
isForCurrentShardSender := inMb.miniblock.SenderShardID == inMb.shardCoordinator.SelfId()
isForAllShards := inMb.miniblock.ReceiverShardID == core.AllShardId
inMb.isForCurrentShard = isForCurrentShardRecv || isForCurrentShardSender || isForAllShards
}
// Hash gets the hash of this transaction block body
func (inMb *InterceptedMiniblock) Hash() []byte {
return inMb.hash
}
// Miniblock returns the miniblock held by this wrapper
func (inMb *InterceptedMiniblock) Miniblock() *block.MiniBlock {
return inMb.miniblock
}
// CheckValidity checks if the received tx block body is valid (not nil fields)
func (inMb *InterceptedMiniblock) CheckValidity() error {
return inMb.integrity()
}
// IsForCurrentShard returns true if at least one contained miniblock is for current shard
func (inMb *InterceptedMiniblock) IsForCurrentShard() bool {
return inMb.isForCurrentShard
}
// integrity checks the integrity of the tx block body
func (inMb *InterceptedMiniblock) integrity() error {
miniblock := inMb.miniblock
receiverNotCurrentShard := miniblock.ReceiverShardID >= inMb.shardCoordinator.NumberOfShards() &&
(miniblock.ReceiverShardID != core.MetachainShardId && miniblock.ReceiverShardID != core.AllShardId)
if receiverNotCurrentShard {
return process.ErrInvalidShardId
}
senderNotCurrentShard := miniblock.SenderShardID >= inMb.shardCoordinator.NumberOfShards() &&
miniblock.SenderShardID != core.MetachainShardId
if senderNotCurrentShard {
return process.ErrInvalidShardId
}
for _, txHash := range miniblock.TxHashes {
if txHash == nil {
return process.ErrNilTxHash
}
}
if len(miniblock.Reserved) > 0 {
return process.ErrReservedFieldNotSupportedYet
}
return nil
}
// Type returns the type of this intercepted data
func (inMb *InterceptedMiniblock) Type() string {
return "intercepted miniblock"
}
// String returns the transactions body's most important fields as string
func (inMb *InterceptedMiniblock) String() string {
return fmt.Sprintf("miniblock type=%s, numTxs=%d, sender shardid=%d, recv shardid=%d",
inMb.miniblock.Type.String(),
len(inMb.miniblock.TxHashes),
inMb.miniblock.SenderShardID,
inMb.miniblock.ReceiverShardID,
)
}
// Identifiers returns the identifiers used in requests
func (inMb *InterceptedMiniblock) Identifiers() [][]byte {
return [][]byte{inMb.hash}
}
// IsInterfaceNil returns true if there is no value under the interface
func (inMb *InterceptedMiniblock) IsInterfaceNil() bool {
return inMb == nil
}