diff options
Diffstat (limited to 'eth/downloader/downloader_test.go')
-rw-r--r-- | eth/downloader/downloader_test.go | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 8299dd62c..61fc7827b 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -97,8 +97,18 @@ func newTester() *downloadTester { } // sync starts synchronizing with a remote peer, blocking until it completes. -func (dl *downloadTester) sync(id string) error { - err := dl.downloader.synchronise(id, dl.peerHashes[id][0]) +func (dl *downloadTester) sync(id string, td *big.Int) error { + hash := dl.peerHashes[id][0] + + // If no particular TD was requested, load from the peer's blockchain + if td == nil { + td = big.NewInt(1) + if block, ok := dl.peerBlocks[id][hash]; ok { + td = block.Td + } + } + err := dl.downloader.synchronise(id, hash, td) + for { // If the queue is empty and processing stopped, break hashes, blocks := dl.downloader.queue.Size() @@ -261,7 +271,7 @@ func TestSynchronisation60(t *testing.T) { tester.newPeer("peer", eth60, hashes, blocks) // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("peer"); err != nil { + if err := tester.sync("peer", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != targetBlocks+1 { @@ -281,7 +291,7 @@ func TestCanonicalSynchronisation61(t *testing.T) { tester.newPeer("peer", eth61, hashes, blocks) // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("peer"); err != nil { + if err := tester.sync("peer", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != targetBlocks+1 { @@ -312,7 +322,7 @@ func testThrottling(t *testing.T, protocol int) { // Start a synchronisation concurrently errc := make(chan error) go func() { - errc <- tester.sync("peer") + errc <- tester.sync("peer", nil) }() // Iteratively take some blocks, always checking the retrieval count for len(tester.ownBlocks) < targetBlocks+1 { @@ -361,14 +371,14 @@ func TestForkedSynchronisation61(t *testing.T) { tester.newPeer("fork B", eth61, hashesB, blocksB) // Synchronise with the peer and make sure all blocks were retrieved - if err := tester.sync("fork A"); err != nil { + if err := tester.sync("fork A", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != common+fork+1 { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, common+fork+1) } // Synchronise with the second peer and make sure that fork is pulled too - if err := tester.sync("fork B"); err != nil { + if err := tester.sync("fork B", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != common+2*fork+1 { @@ -411,7 +421,7 @@ func testCancel(t *testing.T, protocol int) { t.Errorf("block or hash count mismatch: %d hashes, %d blocks, want 0", hashCount, blockCount) } // Synchronise with the peer, but cancel afterwards - if err := tester.sync("peer"); err != nil { + if err := tester.sync("peer", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } tester.downloader.cancel() @@ -438,14 +448,14 @@ func testMultiSynchronisation(t *testing.T, protocol int) { } // Synchronise with the middle peer and make sure half of the blocks were retrieved id := fmt.Sprintf("peer #%d", targetPeers/2) - if err := tester.sync(id); err != nil { + if err := tester.sync(id, nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != len(tester.peerHashes[id]) { t.Fatalf("synchronised block mismatch: have %v, want %v", imported, len(tester.peerHashes[id])) } // Synchronise with the best peer and make sure everything is retrieved - if err := tester.sync("peer #0"); err != nil { + if err := tester.sync("peer #0", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != targetBlocks+1 { @@ -469,7 +479,7 @@ func TestSlowSynchronisation60(t *testing.T) { // Try to sync with the peers (pull hashes from fast) start := time.Now() - if err := tester.sync("fast"); err != nil { + if err := tester.sync("fast", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if imported := len(tester.ownBlocks); imported != targetBlocks+1 { @@ -497,14 +507,14 @@ func TestNonExistingParentAttack60(t *testing.T) { tester.newPeer("attack", eth60, hashes, blocks) // Try and sync with the malicious node and check that it fails - if err := tester.sync("attack"); err == nil { + if err := tester.sync("attack", nil); err == nil { t.Fatalf("block synchronization succeeded") } if tester.hasBlock(hashes[0]) { t.Fatalf("tester accepted unknown-parent block: %v", blocks[hashes[0]]) } // Try to synchronize with the valid chain and make sure it succeeds - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } if !tester.hasBlock(tester.peerHashes["valid"][0]) { @@ -525,7 +535,7 @@ func TestRepeatingHashAttack60(t *testing.T) { // TODO: Is this thing valid?? // Try and sync with the malicious node errc := make(chan error) go func() { - errc <- tester.sync("attack") + errc <- tester.sync("attack", nil) }() // Make sure that syncing returns and does so with a failure select { @@ -537,7 +547,7 @@ func TestRepeatingHashAttack60(t *testing.T) { // TODO: Is this thing valid?? } } // Ensure that a valid chain can still pass sync - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -555,11 +565,11 @@ func TestNonExistingBlockAttack60(t *testing.T) { tester.newPeer("attack", eth60, hashes, blocks) // Try and sync with the malicious node and check that it fails - if err := tester.sync("attack"); err != errPeersUnavailable { + if err := tester.sync("attack", nil); err != errPeersUnavailable { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errPeersUnavailable) } // Ensure that a valid chain can still pass sync - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -583,11 +593,11 @@ func TestInvalidHashOrderAttack60(t *testing.T) { tester.newPeer("attack", eth60, hashes, blocks) // Try and sync with the malicious node and check that it fails - if err := tester.sync("attack"); err != errInvalidChain { + if err := tester.sync("attack", nil); err != errInvalidChain { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errInvalidChain) } // Ensure that a valid chain can still pass sync - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -611,11 +621,11 @@ func TestMadeupHashChainAttack60(t *testing.T) { tester.newPeer("attack", eth60, randomHashes, nil) // Try and sync with the malicious node and check that it fails - if err := tester.sync("attack"); err != errCrossCheckFailed { + if err := tester.sync("attack", nil); err != errCrossCheckFailed { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errCrossCheckFailed) } // Ensure that a valid chain can still pass sync - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -636,7 +646,7 @@ func TestMadeupHashChainDrippingAttack60(t *testing.T) { // Try and sync with the attacker, one hash at a time tester.maxHashFetch = 1 tester.newPeer("attack", eth60, randomHashes, nil) - if err := tester.sync("attack"); err != errStallingPeer { + if err := tester.sync("attack", nil); err != errStallingPeer { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errStallingPeer) } } @@ -659,7 +669,7 @@ func TestMadeupBlockChainAttack60(t *testing.T) { // Try and sync with the malicious node and check that it fails tester := newTester() tester.newPeer("attack", eth60, gapped, blocks) - if err := tester.sync("attack"); err != errCrossCheckFailed { + if err := tester.sync("attack", nil); err != errCrossCheckFailed { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errCrossCheckFailed) } // Ensure that a valid chain can still pass sync @@ -667,7 +677,7 @@ func TestMadeupBlockChainAttack60(t *testing.T) { crossCheckCycle = defaultCrossCheckCycle tester.newPeer("valid", eth60, hashes, blocks) - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -690,7 +700,7 @@ func TestBannedChainStarvationAttack60(t *testing.T) { // the head of the invalid chain is blocked too. for banned := tester.downloader.banned.Size(); ; { // Try to sync with the attacker, check hash chain failure - if err := tester.sync("attack"); err != errInvalidChain { + if err := tester.sync("attack", nil); err != errInvalidChain { if tester.downloader.banned.Has(forkHashes[0]) && err == errBannedHead { break } @@ -711,7 +721,7 @@ func TestBannedChainStarvationAttack60(t *testing.T) { t.Fatalf("banned attacker registered: %v", peer) } // Ensure that a valid chain can still pass sync - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -743,7 +753,7 @@ func TestBannedChainMemoryExhaustionAttack60(t *testing.T) { // the head of the invalid chain is blocked too. for { // Try to sync with the attacker, check hash chain failure - if err := tester.sync("attack"); err != errInvalidChain { + if err := tester.sync("attack", nil); err != errInvalidChain { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errInvalidChain) } // Short circuit if the entire chain was banned. @@ -754,7 +764,7 @@ func TestBannedChainMemoryExhaustionAttack60(t *testing.T) { if bans := tester.downloader.banned.Size(); bans > maxBannedHashes { t.Fatalf("ban cap exceeded: have %v, want max %v", bans, maxBannedHashes) } - for hash, _ := range core.BadHashes { + for hash := range core.BadHashes { if !tester.downloader.banned.Has(hash) { t.Fatalf("hard coded ban evacuated: %x", hash) } @@ -764,7 +774,7 @@ func TestBannedChainMemoryExhaustionAttack60(t *testing.T) { MaxBlockFetch = defaultMaxBlockFetch maxBannedHashes = defaultMaxBannedHashes - if err := tester.sync("valid"); err != nil { + if err := tester.sync("valid", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } } @@ -790,7 +800,7 @@ func TestOverlappingDeliveryAttack60(t *testing.T) { return rawGetBlocks(append(request, hashes[0])) } // Test that synchronisation can complete, check for import success - if err := tester.sync("attack"); err != nil { + if err := tester.sync("attack", nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } start := time.Now() @@ -807,7 +817,7 @@ func TestOverlappingDeliveryAttack60(t *testing.T) { func TestHighTDStarvationAttack61(t *testing.T) { tester := newTester() tester.newPeer("attack", eth61, []common.Hash{genesis.Hash()}, nil) - if err := tester.sync("attack"); err != errStallingPeer { + if err := tester.sync("attack", big.NewInt(1000000)); err != errStallingPeer { t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errStallingPeer) } } @@ -849,7 +859,7 @@ func TestHashAttackerDropping(t *testing.T) { // Simulate a synchronisation and check the required result tester.downloader.synchroniseMock = func(string, common.Hash) error { return tt.result } - tester.downloader.Synchronise(id, genesis.Hash()) + tester.downloader.Synchronise(id, genesis.Hash(), big.NewInt(1000)) if _, ok := tester.peerHashes[id]; !ok != tt.drop { t.Errorf("test %d: peer drop mismatch for %v: have %v, want %v", i, tt.result, !ok, tt.drop) } |