Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
2f4cbe22
Commit
2f4cbe22
authored
Jun 17, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth, eth/downloader: fix processing interrupt caused by temp cancel
parent
ae36beb3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
22 additions
and
24 deletions
+22
-24
downloader.go
eth/downloader/downloader.go
+19
-21
downloader_test.go
eth/downloader/downloader_test.go
+2
-2
sync.go
eth/sync.go
+1
-1
No files found.
eth/downloader/downloader.go
View file @
2f4cbe22
...
...
@@ -87,6 +87,8 @@ type Downloader struct {
checks
map
[
common
.
Hash
]
*
crossCheck
// Pending cross checks to verify a hash chain
banned
*
set
.
Set
// Set of hashes we've received and banned
interrupt
int32
// Atomic boolean to signal termination
// Statistics
importStart
time
.
Time
// Instance when the last blocks were taken from the cache
importQueue
[]
*
Block
// Previously taken blocks to check import progress
...
...
@@ -245,12 +247,6 @@ func (d *Downloader) synchronise(id string, hash common.Hash) error {
if
atomic
.
CompareAndSwapInt32
(
&
d
.
notified
,
0
,
1
)
{
glog
.
V
(
logger
.
Info
)
.
Infoln
(
"Block synchronisation started"
)
}
// Create cancel channel for aborting mid-flight
d
.
cancelLock
.
Lock
()
d
.
cancelCh
=
make
(
chan
struct
{})
d
.
cancelLock
.
Unlock
()
// Abort if the queue still contains some leftover data
if
_
,
cached
:=
d
.
queue
.
Size
();
cached
>
0
&&
d
.
queue
.
GetHeadBlock
()
!=
nil
{
return
errPendingQueue
...
...
@@ -260,12 +256,16 @@ func (d *Downloader) synchronise(id string, hash common.Hash) error {
d
.
peers
.
Reset
()
d
.
checks
=
make
(
map
[
common
.
Hash
]
*
crossCheck
)
// Create cancel channel for aborting mid-flight
d
.
cancelLock
.
Lock
()
d
.
cancelCh
=
make
(
chan
struct
{})
d
.
cancelLock
.
Unlock
()
// Retrieve the origin peer and initiate the downloading process
p
:=
d
.
peers
.
Peer
(
id
)
if
p
==
nil
{
return
errUnknownPeer
}
return
d
.
syncWithPeer
(
p
,
hash
)
}
...
...
@@ -282,7 +282,7 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash) (err error) {
defer
func
()
{
// reset on error
if
err
!=
nil
{
d
.
C
ancel
()
d
.
c
ancel
()
d
.
mux
.
Post
(
FailedEvent
{
err
})
}
else
{
d
.
mux
.
Post
(
DoneEvent
{})
...
...
@@ -301,9 +301,9 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash) (err error) {
return
nil
}
//
C
ancel cancels all of the operations and resets the queue. It returns true
//
c
ancel cancels all of the operations and resets the queue. It returns true
// if the cancel operation was completed.
func
(
d
*
Downloader
)
C
ancel
()
{
func
(
d
*
Downloader
)
c
ancel
()
{
// Close the current cancel channel
d
.
cancelLock
.
Lock
()
if
d
.
cancelCh
!=
nil
{
...
...
@@ -320,6 +320,12 @@ func (d *Downloader) Cancel() {
d
.
queue
.
Reset
()
}
// Terminate interrupts the downloader, canceling all pending operations.
func
(
d
*
Downloader
)
Terminate
()
{
atomic
.
StoreInt32
(
&
d
.
interrupt
,
1
)
d
.
cancel
()
}
// fetchHahes starts retrieving hashes backwards from a specific peer and hash,
// up until it finds a common ancestor. If the source peer times out, alternative
// ones are tried for continuation.
...
...
@@ -737,12 +743,6 @@ func (d *Downloader) process() (err error) {
atomic
.
StoreInt32
(
&
d
.
processing
,
0
)
}()
// Fetch the current cancel channel to allow termination
d
.
cancelLock
.
RLock
()
cancel
:=
d
.
cancelCh
d
.
cancelLock
.
RUnlock
()
// Repeat the processing as long as there are blocks to import
for
{
// Fetch the next batch of blocks
...
...
@@ -759,12 +759,10 @@ func (d *Downloader) process() (err error) {
// Actually import the blocks
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Inserting chain with %d blocks (#%v - #%v)
\n
"
,
len
(
blocks
),
blocks
[
0
]
.
RawBlock
.
Number
(),
blocks
[
len
(
blocks
)
-
1
]
.
RawBlock
.
Number
())
for
len
(
blocks
)
!=
0
{
// TODO: quit
for
len
(
blocks
)
!=
0
{
// Check for any termination requests
select
{
case
<-
cancel
:
if
atomic
.
LoadInt32
(
&
d
.
interrupt
)
==
1
{
return
errCancelChainImport
default
:
}
// Retrieve the first batch of blocks to insert
max
:=
int
(
math
.
Min
(
float64
(
len
(
blocks
)),
float64
(
maxBlockProcess
)))
...
...
@@ -777,7 +775,7 @@ func (d *Downloader) process() (err error) {
if
err
!=
nil
{
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Block #%d import failed: %v"
,
raw
[
index
]
.
NumberU64
(),
err
)
d
.
dropPeer
(
blocks
[
index
]
.
OriginPeer
)
d
.
C
ancel
()
d
.
c
ancel
()
return
errCancelChainImport
}
blocks
=
blocks
[
max
:
]
...
...
eth/downloader/downloader_test.go
View file @
2f4cbe22
...
...
@@ -247,7 +247,7 @@ func TestCancel(t *testing.T) {
tester
.
newPeer
(
"peer"
,
hashes
,
blocks
)
// Make sure canceling works with a pristine downloader
tester
.
downloader
.
C
ancel
()
tester
.
downloader
.
c
ancel
()
hashCount
,
blockCount
:=
tester
.
downloader
.
queue
.
Size
()
if
hashCount
>
0
||
blockCount
>
0
{
t
.
Errorf
(
"block or hash count mismatch: %d hashes, %d blocks, want 0"
,
hashCount
,
blockCount
)
...
...
@@ -256,7 +256,7 @@ func TestCancel(t *testing.T) {
if
err
:=
tester
.
sync
(
"peer"
);
err
!=
nil
{
t
.
Fatalf
(
"failed to synchronise blocks: %v"
,
err
)
}
tester
.
downloader
.
C
ancel
()
tester
.
downloader
.
c
ancel
()
hashCount
,
blockCount
=
tester
.
downloader
.
queue
.
Size
()
if
hashCount
>
0
||
blockCount
>
0
{
t
.
Errorf
(
"block or hash count mismatch: %d hashes, %d blocks, want 0"
,
hashCount
,
blockCount
)
...
...
eth/sync.go
View file @
2f4cbe22
...
...
@@ -251,7 +251,7 @@ func (pm *ProtocolManager) fetcher() {
// downloading hashes and blocks as well as retrieving cached ones.
func
(
pm
*
ProtocolManager
)
syncer
()
{
// Abort any pending syncs if we terminate
defer
pm
.
downloader
.
Cancel
()
defer
pm
.
downloader
.
Terminate
()
forceSync
:=
time
.
Tick
(
forceSyncCycle
)
for
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment