-
Notifications
You must be signed in to change notification settings - Fork 211
/
wire_types.go
139 lines (115 loc) · 3.99 KB
/
wire_types.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
package fetch
import (
"fmt"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/datastore"
"github.com/spacemeshos/go-spacemesh/log"
"github.com/spacemeshos/go-spacemesh/p2p"
)
//go:generate scalegen
const MaxHashesInReq = 100
// RequestMessage is sent to the peer for hash query.
type RequestMessage struct {
Hint datastore.Hint `scale:"max=256"` // TODO(mafa): covert to an enum
Hash types.Hash32
}
// ResponseMessage is sent to the node as a response.
type ResponseMessage struct {
Hash types.Hash32
Data []byte `scale:"max=3200000"` // 100_000 ATXIDs at 32 bytes each is the expected maximum size
}
// RequestBatch is a batch of requests and a hash of all requests as ID.
type RequestBatch struct {
ID types.Hash32
Requests []RequestMessage `scale:"max=1000"` // depends on fetch config `BatchSize` which defaults to 20, more than 1000 seems unlikely
}
// ResponseBatch is the response struct send for a RequestBatch. the ResponseBatch ID must be the same
// as stated in RequestBatch even if not all Data is present.
type ResponseBatch struct {
ID types.Hash32
Responses []ResponseMessage `scale:"max=1000"` // depends on fetch config `BatchSize` which defaults to 20, more than 1000 seems unlikely
}
// MeshHashRequest is used by ForkFinder to request the hashes of layers from
// a peer to find the layer at which a divergence occurred in the local mesh of
// the node.
//
// From and To define the beginning and end layer to request. By defines the
// increment between layers to limit the number of hashes in the response,
// e.g. 2 means only every other hash is requested. The number of hashes in
// the response is limited by `fetch.MaxHashesInReq`.
type MeshHashRequest struct {
From, To types.LayerID
Step uint32
}
func NewMeshHashRequest(from, to types.LayerID) *MeshHashRequest {
diff := to.Difference(from)
delta := diff/uint32(MaxHashesInReq-1) + 1
return &MeshHashRequest{
From: from,
To: to,
Step: delta,
}
}
func (r *MeshHashRequest) Count() uint {
diff := r.To.Difference(r.From)
count := uint(diff/r.Step + 1)
if diff%r.Step != 0 {
// last layer is not a multiple of Step size, so we need to add it
count++
}
return count
}
func (r *MeshHashRequest) Validate() error {
if r.Step == 0 {
return fmt.Errorf("%w: By must not be zero", errBadRequest)
}
if r.To.Before(r.From) {
return fmt.Errorf("%w: To before From", errBadRequest)
}
if r.Count() > MaxHashesInReq {
return fmt.Errorf("%w: number of layers requested exceeds maximum for one request", errBadRequest)
}
return nil
}
func (r *MeshHashRequest) MarshalLogObject(encoder log.ObjectEncoder) error {
encoder.AddUint32("from", r.From.Uint32())
encoder.AddUint32("to", r.To.Uint32())
encoder.AddUint32("by", r.Step)
return nil
}
type MeshHashes struct {
Hashes []types.Hash32 `scale:"max=1000"` // depends on syncer Config `MaxHashesInReq`, defaults to 100, 1000 is a safe upper bound
}
type MaliciousIDs struct {
NodeIDs []types.NodeID `scale:"max=100000"` // max. expected number of ATXs per epoch is 100_000
}
type EpochData struct {
AtxIDs []types.ATXID `scale:"max=100000"` // max. expected number of ATXs per epoch is 100_000
}
// LayerData is the data response for a given layer ID.
type LayerData struct {
Ballots []types.BallotID `scale:"max=500"` // expected are 50 proposals per layer + safety margin
}
// LayerOpinion is the response for opinion for a given layer.
type LayerOpinion struct {
PrevAggHash types.Hash32
Cert *types.Certificate
peer p2p.Peer
}
// SetPeer ...
func (lo *LayerOpinion) SetPeer(p p2p.Peer) {
lo.peer = p
}
// Peer ...
func (lo *LayerOpinion) Peer() p2p.Peer {
return lo.peer
}
// MarshalLogObject implements logging encoder for LayerOpinion.
func (lo *LayerOpinion) MarshalLogObject(encoder log.ObjectEncoder) error {
encoder.AddString("peer", lo.peer.String())
encoder.AddString("prev_hash", lo.PrevAggHash.String())
if lo.Cert != nil {
encoder.AddString("cert_block_id", lo.Cert.BlockID.String())
}
return nil
}