@@ -68,8 +68,7 @@ type Downloader struct {
68
68
getBlock getBlockFn
69
69
70
70
// Status
71
- fetchingHashes int32
72
- downloadingBlocks int32
71
+ synchronizing int32
73
72
74
73
// Channels
75
74
newPeerCh chan * peer
@@ -120,43 +119,26 @@ func (d *Downloader) UnregisterPeer(id string) {
120
119
delete (d .peers , id )
121
120
}
122
121
123
- // SynchroniseWithPeer will select the peer and use it for synchronizing. If an empty string is given
122
+ // Synchronize will select the peer and use it for synchronizing. If an empty string is given
124
123
// it will use the best peer possible and synchronize if it's TD is higher than our own. If any of the
125
124
// checks fail an error will be returned. This method is synchronous
126
- func (d * Downloader ) Synchronise (id string , hash common.Hash ) error {
127
- // Make sure it's doing neither. Once done we can restart the
128
- // downloading process if the TD is higher. For now just get on
129
- // with whatever is going on. This prevents unnecessary switching.
130
- if d .isBusy () {
131
- return errBusy
125
+ func (d * Downloader ) Synchronize (id string , hash common.Hash ) error {
126
+ // Make sure only one goroutine is ever allowed past this point at once
127
+ if ! atomic .CompareAndSwapInt32 (& d .synchronizing , 0 , 1 ) {
128
+ return nil
132
129
}
130
+ defer atomic .StoreInt32 (& d .synchronizing , 0 )
133
131
134
- // When a synchronization attempt is made while the queue still
135
- // contains items we abort the sync attempt
136
- if done , pend := d .queue .Size (); done + pend > 0 {
132
+ // Abort if the queue still contains some leftover data
133
+ if _ , cached := d .queue .Size (); cached > 0 {
137
134
return errPendingQueue
138
135
}
139
-
140
- // Fetch the peer using the id or throw an error if the peer couldn't be found
136
+ // Retrieve the origin peer and initiate the downloading process
141
137
p := d .peers [id ]
142
138
if p == nil {
143
139
return errUnknownPeer
144
140
}
145
-
146
- // Get the hash from the peer and initiate the downloading progress.
147
- err := d .getFromPeer (p , hash , false )
148
- if err != nil {
149
- return err
150
- }
151
-
152
- return nil
153
- }
154
-
155
- // Done lets the downloader know that whatever previous hashes were taken
156
- // are processed. If the block count reaches zero and done is called
157
- // we reset the queue for the next batch of incoming hashes and blocks.
158
- func (d * Downloader ) Done () {
159
- d .queue .Done ()
141
+ return d .getFromPeer (p , hash , false )
160
142
}
161
143
162
144
// TakeBlocks takes blocks from the queue and yields them to the blockTaker handler
@@ -176,6 +158,7 @@ func (d *Downloader) Has(hash common.Hash) bool {
176
158
}
177
159
178
160
func (d * Downloader ) getFromPeer (p * peer , hash common.Hash , ignoreInitial bool ) (err error ) {
161
+
179
162
d .activePeer = p .id
180
163
defer func () {
181
164
// reset on error
@@ -184,7 +167,7 @@ func (d *Downloader) getFromPeer(p *peer, hash common.Hash, ignoreInitial bool)
184
167
}
185
168
}()
186
169
187
- glog .V (logger .Detail ).Infoln ("Synchronising with the network using:" , p .id )
170
+ glog .V (logger .Debug ).Infoln ("Synchronizing with the network using:" , p .id )
188
171
// Start the fetcher. This will block the update entirely
189
172
// interupts need to be send to the appropriate channels
190
173
// respectively.
@@ -200,20 +183,13 @@ func (d *Downloader) getFromPeer(p *peer, hash common.Hash, ignoreInitial bool)
200
183
return err
201
184
}
202
185
203
- glog .V (logger .Detail ).Infoln ("Sync completed" )
186
+ glog .V (logger .Debug ).Infoln ("Synchronization completed" )
204
187
205
188
return nil
206
189
}
207
190
208
191
// XXX Make synchronous
209
192
func (d * Downloader ) startFetchingHashes (p * peer , h common.Hash , ignoreInitial bool ) error {
210
- atomic .StoreInt32 (& d .fetchingHashes , 1 )
211
- defer atomic .StoreInt32 (& d .fetchingHashes , 0 )
212
-
213
- if d .queue .Has (h ) { // TODO: Is this possible? Shouldn't queue be empty for startFetchingHashes to be even called?
214
- return errAlreadyInPool
215
- }
216
-
217
193
glog .V (logger .Debug ).Infof ("Downloading hashes (%x) from %s" , h [:4 ], p .id )
218
194
219
195
start := time .Now ()
@@ -312,10 +288,8 @@ out:
312
288
}
313
289
314
290
func (d * Downloader ) startFetchingBlocks (p * peer ) error {
315
- glog .V (logger .Detail ).Infoln ("Downloading" , d .queue .Pending (), "block(s)" )
291
+ glog .V (logger .Debug ).Infoln ("Downloading" , d .queue .Pending (), "block(s)" )
316
292
317
- atomic .StoreInt32 (& d .downloadingBlocks , 1 )
318
- defer atomic .StoreInt32 (& d .downloadingBlocks , 0 )
319
293
// Defer the peer reset. This will empty the peer requested set
320
294
// and makes sure there are no lingering peers with an incorrect
321
295
// state
@@ -439,19 +413,3 @@ func (d *Downloader) AddHashes(id string, hashes []common.Hash) error {
439
413
440
414
return nil
441
415
}
442
-
443
- func (d * Downloader ) isFetchingHashes () bool {
444
- return atomic .LoadInt32 (& d .fetchingHashes ) == 1
445
- }
446
-
447
- func (d * Downloader ) isDownloadingBlocks () bool {
448
- return atomic .LoadInt32 (& d .downloadingBlocks ) == 1
449
- }
450
-
451
- func (d * Downloader ) isBusy () bool {
452
- return d .isFetchingHashes () || d .isDownloadingBlocks ()
453
- }
454
-
455
- func (d * Downloader ) IsBusy () bool {
456
- return d .isBusy ()
457
- }
0 commit comments