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