-
Notifications
You must be signed in to change notification settings - Fork 199
/
interceptedTxBlock.go
132 lines (108 loc) · 3.89 KB
/
interceptedTxBlock.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
package interceptedBlocks
import (
"github.com/ElrondNetwork/elrond-go/data/block"
"github.com/ElrondNetwork/elrond-go/hashing"
"github.com/ElrondNetwork/elrond-go/marshal"
"github.com/ElrondNetwork/elrond-go/process"
"github.com/ElrondNetwork/elrond-go/sharding"
)
// InterceptedTxBlockBody is a wrapper over a slice of miniblocks which contains transactions.
type InterceptedTxBlockBody struct {
txBlockBody block.Body
marshalizer marshal.Marshalizer
hasher hashing.Hasher
shardCoordinator sharding.Coordinator
hash []byte
isForCurrentShard bool
}
// NewInterceptedTxBlockBody creates a new instance of InterceptedTxBlockBody struct
func NewInterceptedTxBlockBody(arg *ArgInterceptedTxBlockBody) (*InterceptedTxBlockBody, error) {
err := checkTxBlockBodyArgument(arg)
if err != nil {
return nil, err
}
txBlockBody, err := createTxBlockBody(arg.Marshalizer, arg.TxBlockBodyBuff)
if err != nil {
return nil, err
}
inTxBody := &InterceptedTxBlockBody{
txBlockBody: txBlockBody,
marshalizer: arg.Marshalizer,
hasher: arg.Hasher,
shardCoordinator: arg.ShardCoordinator,
}
inTxBody.processFields(arg.TxBlockBodyBuff)
return inTxBody, nil
}
func createTxBlockBody(marshalizer marshal.Marshalizer, txBlockBodyBuff []byte) (block.Body, error) {
txBlockBody := make(block.Body, 0)
err := marshalizer.Unmarshal(&txBlockBody, txBlockBodyBuff)
if err != nil {
return nil, err
}
return txBlockBody, nil
}
func (inTxBody *InterceptedTxBlockBody) processFields(txBuff []byte) {
inTxBody.hash = inTxBody.hasher.Compute(string(txBuff))
inTxBody.processIsForCurrentShard()
}
func (inTxBody *InterceptedTxBlockBody) processIsForCurrentShard() {
inTxBody.isForCurrentShard = false
for _, miniblock := range inTxBody.txBlockBody {
inTxBody.isForCurrentShard = inTxBody.isMiniblockForCurrentShard(miniblock)
if inTxBody.isForCurrentShard {
return
}
}
}
func (inTxBody *InterceptedTxBlockBody) isMiniblockForCurrentShard(miniblock *block.MiniBlock) bool {
isForCurrentShardRecv := miniblock.ReceiverShardID == inTxBody.shardCoordinator.SelfId()
isForCurrentShardSender := miniblock.SenderShardID == inTxBody.shardCoordinator.SelfId()
return isForCurrentShardRecv || isForCurrentShardSender
}
// Hash gets the hash of this transaction block body
func (inTxBody *InterceptedTxBlockBody) Hash() []byte {
return inTxBody.hash
}
// TxBlockBody returns the block body held by this wrapper
func (inTxBody *InterceptedTxBlockBody) TxBlockBody() block.Body {
return inTxBody.txBlockBody
}
// CheckValidity checks if the received tx block body is valid (not nil fields)
func (inTxBody *InterceptedTxBlockBody) CheckValidity() error {
return inTxBody.integrity()
}
// IsForCurrentShard returns true if at least one contained miniblock is for current shard
func (inTxBody *InterceptedTxBlockBody) IsForCurrentShard() bool {
return inTxBody.isForCurrentShard
}
// integrity checks the integrity of the tx block body
func (inTxBody *InterceptedTxBlockBody) integrity() error {
for _, miniBlock := range inTxBody.txBlockBody {
if miniBlock.TxHashes == nil {
return process.ErrNilTxHashes
}
if miniBlock.ReceiverShardID >= inTxBody.shardCoordinator.NumberOfShards() &&
miniBlock.ReceiverShardID != sharding.MetachainShardId {
return process.ErrInvalidShardId
}
if miniBlock.SenderShardID >= inTxBody.shardCoordinator.NumberOfShards() &&
miniBlock.SenderShardID != sharding.MetachainShardId {
return process.ErrInvalidShardId
}
for _, txHash := range miniBlock.TxHashes {
if txHash == nil {
return process.ErrNilTxHash
}
}
}
return nil
}
// Type returns the type of this intercepted data
func (inTxBody *InterceptedTxBlockBody) Type() string {
return "intercepted block body"
}
// IsInterfaceNil returns true if there is no value under the interface
func (inTxBody *InterceptedTxBlockBody) IsInterfaceNil() bool {
return inTxBody == nil
}