@@ -4,19 +4,14 @@ import (
4
4
"context"
5
5
"errors"
6
6
"fmt"
7
- "sync"
8
7
9
8
"github.com/jonboulle/clockwork"
10
- "github.com/libp2p/go-libp2p/core/host"
11
9
"go.uber.org/zap"
12
10
"golang.org/x/sync/errgroup"
13
11
14
12
"github.com/spacemeshos/go-spacemesh/common/types"
15
- "github.com/spacemeshos/go-spacemesh/fetch"
16
13
"github.com/spacemeshos/go-spacemesh/fetch/peers"
17
14
"github.com/spacemeshos/go-spacemesh/p2p"
18
- "github.com/spacemeshos/go-spacemesh/p2p/pubsub"
19
- "github.com/spacemeshos/go-spacemesh/p2p/server"
20
15
"github.com/spacemeshos/go-spacemesh/sql"
21
16
"github.com/spacemeshos/go-spacemesh/sql/expr"
22
17
"github.com/spacemeshos/go-spacemesh/sync2/dbset"
@@ -26,18 +21,17 @@ import (
26
21
"github.com/spacemeshos/go-spacemesh/system"
27
22
)
28
23
29
- const (
30
- proto = "sync/2"
31
- )
32
-
33
24
type ATXHandler struct {
34
25
logger * zap.Logger
35
26
f Fetcher
36
27
clock clockwork.Clock
37
28
cfg Config
38
29
}
39
30
40
- var _ multipeer.SyncKeyHandler = & ATXHandler {}
31
+ var (
32
+ _ multipeer.SyncKeyHandler = & ATXHandler {}
33
+ _ Handler [types.ATXID ] = & ATXHandler {}
34
+ )
41
35
42
36
func NewATXHandler (
43
37
logger * zap.Logger ,
@@ -56,72 +50,14 @@ func NewATXHandler(
56
50
}
57
51
}
58
52
59
- type commitState struct {
60
- state map [types.ATXID ]uint
61
- total int
62
- numDownloaded int
63
- items []types.ATXID
53
+ func (h * ATXHandler ) Register (peer p2p.Peer , k rangesync.KeyBytes ) types.ATXID {
54
+ id := types .BytesToATXID (k )
55
+ h .f .RegisterPeerHashes (peer , []types.Hash32 {id .Hash32 ()})
56
+ return id
64
57
}
65
58
66
- func (h * ATXHandler ) setupState (
67
- peer p2p.Peer ,
68
- base rangesync.OrderedSet ,
69
- received rangesync.SeqResult ,
70
- ) (* commitState , error ) {
71
- state := make (map [types.ATXID ]uint )
72
- for k := range received .Seq {
73
- found , err := base .Has (k )
74
- if err != nil {
75
- return nil , fmt .Errorf ("check if ATX exists: %w" , err )
76
- }
77
- if found {
78
- continue
79
- }
80
- id := types .BytesToATXID (k )
81
- h .f .RegisterPeerHashes (peer , []types.Hash32 {id .Hash32 ()})
82
- state [id ] = 0
83
- }
84
- if err := received .Error (); err != nil {
85
- return nil , fmt .Errorf ("get item: %w" , err )
86
- }
87
- return & commitState {
88
- state : state ,
89
- total : len (state ),
90
- items : make ([]types.ATXID , 0 , h .cfg .BatchSize ),
91
- }, nil
92
- }
93
-
94
- func (h * ATXHandler ) getAtxs (ctx context.Context , cs * commitState ) (bool , error ) {
95
- cs .items = cs .items [:0 ] // reuse the slice to reduce allocations
96
- for id := range cs .state {
97
- cs .items = append (cs .items , id )
98
- if uint (len (cs .items )) == h .cfg .BatchSize {
99
- break
100
- }
101
- }
102
- someSucceeded := false
103
- var mtx sync.Mutex
104
- err := h .f .GetAtxs (ctx , cs .items , system .WithATXCallback (func (id types.ATXID , err error ) {
105
- mtx .Lock ()
106
- defer mtx .Unlock ()
107
- switch {
108
- case err == nil :
109
- cs .numDownloaded ++
110
- someSucceeded = true
111
- delete (cs .state , id )
112
- case errors .Is (err , pubsub .ErrValidationReject ):
113
- h .logger .Debug ("failed to download ATX" ,
114
- zap .String ("atx" , id .ShortString ()), zap .Error (err ))
115
- delete (cs .state , id )
116
- case cs .state [id ] >= h .cfg .MaxAttempts - 1 :
117
- h .logger .Debug ("failed to download ATX: max attempts reached" ,
118
- zap .String ("atx" , id .ShortString ()))
119
- delete (cs .state , id )
120
- default :
121
- cs .state [id ]++
122
- }
123
- }))
124
- return someSucceeded , err
59
+ func (h * ATXHandler ) Get (ctx context.Context , ids []types.ATXID , callback func (types.ATXID , error )) error {
60
+ return h .f .GetAtxs (ctx , ids , system .WithATXCallback (callback ))
125
61
}
126
62
127
63
func (h * ATXHandler ) Commit (
@@ -132,46 +68,11 @@ func (h *ATXHandler) Commit(
132
68
) error {
133
69
h .logger .Debug ("begin atx commit" )
134
70
defer h .logger .Debug ("end atx commit" )
135
- cs , err := h . setupState ( peer , base , received )
71
+ cs , err := NewCommitState ( h . logger , h , h . clock , peer , base , received , h . cfg )
136
72
if err != nil {
137
73
return err
138
74
}
139
- startTime := h .clock .Now ()
140
- batchAttemptsRemaining := h .cfg .MaxBatchRetries
141
- for len (cs .state ) > 0 {
142
- someSucceeded , err := h .getAtxs (ctx , cs )
143
- batchErr := & fetch.BatchError {}
144
- switch {
145
- case err == nil :
146
- case errors .Is (err , context .Canceled ):
147
- return err
148
- case ! errors .As (err , & batchErr ):
149
- h .logger .Debug ("failed to download ATXs" , zap .Error (err ))
150
- }
151
- if ! someSucceeded {
152
- if batchAttemptsRemaining == 0 {
153
- return errors .New ("failed to download ATXs: max batch retries reached" )
154
- }
155
- batchAttemptsRemaining --
156
- h .logger .Debug ("failed to download any ATXs: will retry batch" ,
157
- zap .Uint ("remaining" , batchAttemptsRemaining ),
158
- zap .Duration ("delay" , h .cfg .FailedBatchDelay ))
159
- select {
160
- case <- ctx .Done ():
161
- return ctx .Err ()
162
- case <- h .clock .After (h .cfg .FailedBatchDelay ):
163
- continue
164
- }
165
- }
166
-
167
- batchAttemptsRemaining = h .cfg .MaxBatchRetries
168
- elapsed := h .clock .Since (startTime )
169
- h .logger .Debug ("fetched atxs" ,
170
- zap .Int ("total" , cs .total ),
171
- zap .Int ("downloaded" , cs .numDownloaded ),
172
- zap .Float64 ("rate per sec" , float64 (cs .numDownloaded )/ elapsed .Seconds ()))
173
- }
174
- return nil
75
+ return cs .Commit (ctx )
175
76
}
176
77
177
78
type MultiEpochATXSyncer struct {
@@ -221,7 +122,7 @@ func (s *MultiEpochATXSyncer) load(newEpoch types.EpochID) error {
221
122
if epoch == newEpoch {
222
123
cfg = s .newCfg
223
124
}
224
- hs , err := s .hss .CreateHashSync (name , cfg , epoch )
125
+ hs , err := s .hss .CreateATXSync (name , cfg , epoch )
225
126
if err != nil {
226
127
return fmt .Errorf ("create ATX syncer for epoch %d: %w" , epoch , err )
227
128
}
@@ -307,12 +208,6 @@ func NewATXSyncer(
307
208
return NewP2PHashSync (logger , d , name , curSet , 32 , peers , handler , cfg , enableActiveSync )
308
209
}
309
210
310
- func NewDispatcher (logger * zap.Logger , host host.Host , opts []server.Opt ) * rangesync.Dispatcher {
311
- d := rangesync .NewDispatcher (logger )
312
- d .SetupServer (host , proto , opts ... )
313
- return d
314
- }
315
-
316
211
type ATXSyncSource struct {
317
212
logger * zap.Logger
318
213
d * rangesync.Dispatcher
@@ -335,7 +230,7 @@ func NewATXSyncSource(
335
230
return & ATXSyncSource {logger : logger , d : d , db : db , f : f , peers : peers , enableActiveSync : enableActiveSync }
336
231
}
337
232
338
- // CreateHashSync implements HashSyncSource.
339
- func (as * ATXSyncSource ) CreateHashSync (name string , cfg Config , epoch types.EpochID ) (HashSync , error ) {
233
+ // CreateATXSync implements HashSyncSource.
234
+ func (as * ATXSyncSource ) CreateATXSync (name string , cfg Config , epoch types.EpochID ) (HashSync , error ) {
340
235
return NewATXSyncer (as .logger .Named (name ), as .d , name , cfg , as .db , as .f , as .peers , epoch , as .enableActiveSync )
341
236
}
0 commit comments