eth/downloader: add a test for detecting missing blocks
This commit is contained in:
parent
cd2fb09051
commit
366e9627e8
@ -2,7 +2,6 @@ package downloader
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -398,8 +397,7 @@ out:
|
|||||||
// and all failed throw an error
|
// and all failed throw an error
|
||||||
if d.queue.InFlight() == 0 {
|
if d.queue.InFlight() == 0 {
|
||||||
d.queue.Reset()
|
d.queue.Reset()
|
||||||
|
return errPeersUnavailable
|
||||||
return fmt.Errorf("%v peers available = %d. total peers = %d. hashes needed = %d", errPeersUnavailable, len(idlePeers), d.peers.Len(), d.queue.Pending())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if d.queue.InFlight() == 0 {
|
} else if d.queue.InFlight() == 0 {
|
||||||
|
@ -106,11 +106,12 @@ func (dl *downloadTester) getHashes(hash common.Hash) error {
|
|||||||
|
|
||||||
func (dl *downloadTester) getBlocks(id string) func([]common.Hash) error {
|
func (dl *downloadTester) getBlocks(id string) func([]common.Hash) error {
|
||||||
return func(hashes []common.Hash) error {
|
return func(hashes []common.Hash) error {
|
||||||
blocks := make([]*types.Block, len(hashes))
|
blocks := make([]*types.Block, 0, len(hashes))
|
||||||
for i, hash := range hashes {
|
for _, hash := range hashes {
|
||||||
blocks[i] = dl.blocks[hash]
|
if block, ok := dl.blocks[hash]; ok {
|
||||||
|
blocks = append(blocks, block)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go dl.downloader.DeliverBlocks(id, blocks)
|
go dl.downloader.DeliverBlocks(id, blocks)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -341,7 +342,7 @@ func TestNonExistingParentAttack(t *testing.T) {
|
|||||||
// loop indefinitely.
|
// loop indefinitely.
|
||||||
func TestRepeatingHashAttack(t *testing.T) {
|
func TestRepeatingHashAttack(t *testing.T) {
|
||||||
// Create a valid chain, but drop the last link
|
// Create a valid chain, but drop the last link
|
||||||
hashes := createHashes(1000, 1)
|
hashes := createHashes(0, 1000)
|
||||||
blocks := createBlocksFromHashes(hashes)
|
blocks := createBlocksFromHashes(hashes)
|
||||||
|
|
||||||
hashes = hashes[:len(hashes)-1]
|
hashes = hashes[:len(hashes)-1]
|
||||||
@ -365,3 +366,20 @@ func TestRepeatingHashAttack(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that if a malicious peers returns a non-existent block hash, it should
|
||||||
|
// eventually time out and the sync reattempted.
|
||||||
|
func TestNonExistingBlockAttack(t *testing.T) {
|
||||||
|
// Create a valid chain, but forge the last link
|
||||||
|
hashes := createHashes(0, 10)
|
||||||
|
blocks := createBlocksFromHashes(hashes)
|
||||||
|
|
||||||
|
hashes[len(hashes)/2] = unknownHash
|
||||||
|
|
||||||
|
// Try and sync with the malicious node and check that it fails
|
||||||
|
tester := newTester(t, hashes, blocks)
|
||||||
|
tester.newPeer("attack", big.NewInt(10000), hashes[0])
|
||||||
|
if err := tester.sync("attack", hashes[0]); err != errPeersUnavailable {
|
||||||
|
t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errPeersUnavailable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user