Tests that if blocks are announced by multiple peers (or even the same buggy peer), they will only get downloaded at most once.
(t *testing.T)
| 289 | // Tests that if blocks are announced by multiple peers (or even the same buggy |
| 290 | // peer), they will only get downloaded at most once. |
| 291 | func TestConcurrentAnnouncements(t *testing.T) { |
| 292 | // Create a chain of blocks to import |
| 293 | targetBlocks := 4 * hashLimit |
| 294 | hashes, blocks := makeChain(targetBlocks, 0, genesis) |
| 295 | |
| 296 | // Assemble a tester with a built in counter for the requests |
| 297 | tester := newTester() |
| 298 | firstHeaderFetcher := tester.makeHeaderFetcher("first", blocks, -gatherSlack) |
| 299 | firstBodyFetcher := tester.makeBodyFetcher("first", blocks, 0) |
| 300 | secondHeaderFetcher := tester.makeHeaderFetcher("second", blocks, -gatherSlack) |
| 301 | secondBodyFetcher := tester.makeBodyFetcher("second", blocks, 0) |
| 302 | |
| 303 | counter := uint32(0) |
| 304 | firstHeaderWrapper := func(hash common.Hash) error { |
| 305 | atomic.AddUint32(&counter, 1) |
| 306 | return firstHeaderFetcher(hash) |
| 307 | } |
| 308 | secondHeaderWrapper := func(hash common.Hash) error { |
| 309 | atomic.AddUint32(&counter, 1) |
| 310 | return secondHeaderFetcher(hash) |
| 311 | } |
| 312 | // Iteratively announce blocks until all are imported |
| 313 | imported := make(chan *types.Block) |
| 314 | tester.fetcher.importedHook = func(block *types.Block) { imported <- block } |
| 315 | |
| 316 | for i := len(hashes) - 2; i >= 0; i-- { |
| 317 | tester.fetcher.Notify("first", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), firstHeaderWrapper, firstBodyFetcher) |
| 318 | tester.fetcher.Notify("second", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout+time.Millisecond), secondHeaderWrapper, secondBodyFetcher) |
| 319 | tester.fetcher.Notify("second", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout-time.Millisecond), secondHeaderWrapper, secondBodyFetcher) |
| 320 | verifyImportEvent(t, imported, true) |
| 321 | } |
| 322 | verifyImportDone(t, imported) |
| 323 | |
| 324 | // Make sure no blocks were retrieved twice |
| 325 | if int(counter) != targetBlocks { |
| 326 | t.Fatalf("retrieval count mismatch: have %v, want %v", counter, targetBlocks) |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | // Tests that announcements arriving while a previous is being fetched still |
| 331 | // results in a valid import. |
nothing calls this directly
no test coverage detected