Tests that block contents can be retrieved from a remote chain based on their hashes.
(t *testing.T)
| 221 | |
| 222 | // Tests that block contents can be retrieved from a remote chain based on their hashes. |
| 223 | func TestGetBlockBodies(t *testing.T) { |
| 224 | pm, _ := newTestProtocolManagerMust(t, syncer.MaxBlockFetch+15, nil, nil) |
| 225 | peer, _ := newTestPeer("peer", 64, pm, true) |
| 226 | defer peer.close() |
| 227 | |
| 228 | // Create a batch of tests for various scenarios |
| 229 | limit := syncer.MaxBlockFetch |
| 230 | tests := []struct { |
| 231 | random int // Number of blocks to fetch randomly from the chain |
| 232 | explicit []common.Hash // Explicitly requested blocks |
| 233 | available []bool // Availability of explicitly requested blocks |
| 234 | expected int // Total number of existing blocks to expect |
| 235 | }{ |
| 236 | {1, nil, nil, 1}, // A single random block should be retrievable |
| 237 | {10, nil, nil, 10}, // Multiple random blocks should be retrievable |
| 238 | {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable |
| 239 | {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned |
| 240 | {0, []common.Hash{pm.blockchain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable |
| 241 | {0, []common.Hash{pm.blockchain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable |
| 242 | {0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned |
| 243 | |
| 244 | // Existing and non-existing blocks interleaved should not cause problems |
| 245 | {0, []common.Hash{ |
| 246 | {}, |
| 247 | pm.blockchain.GetBlockByNumber(1).Hash(), |
| 248 | {}, |
| 249 | pm.blockchain.GetBlockByNumber(10).Hash(), |
| 250 | {}, |
| 251 | pm.blockchain.GetBlockByNumber(100).Hash(), |
| 252 | {}, |
| 253 | }, []bool{false, true, false, true, false, true, false}, 3}, |
| 254 | } |
| 255 | // Run each of the tests and verify the results against the chain |
| 256 | for i, tt := range tests { |
| 257 | // Collect the hashes to request, and the response to expect |
| 258 | hashes, seen := []common.Hash{}, make(map[int64]bool) |
| 259 | bodies := []*blockBody{} |
| 260 | |
| 261 | for j := 0; j < tt.random; j++ { |
| 262 | for { |
| 263 | num := rand.Int63n(int64(pm.blockchain.CurrentBlock().NumberU64())) |
| 264 | if !seen[num] { |
| 265 | seen[num] = true |
| 266 | |
| 267 | block := pm.blockchain.GetBlockByNumber(uint64(num)) |
| 268 | hashes = append(hashes, block.Hash()) |
| 269 | if len(bodies) < tt.expected { |
| 270 | bodies = append(bodies, &blockBody{Transactions: block.Transactions()}) |
| 271 | } |
| 272 | break |
| 273 | } |
| 274 | } |
| 275 | } |
| 276 | for j, hash := range tt.explicit { |
| 277 | hashes = append(hashes, hash) |
| 278 | if tt.available[j] && len(bodies) < tt.expected { |
| 279 | block := pm.blockchain.GetBlockByHash(hash) |
| 280 | bodies = append(bodies, &blockBody{Transactions: block.Transactions()}) |
nothing calls this directly
no test coverage detected