(msg p2p.Msg, p *peer)
| 416 | } |
| 417 | |
| 418 | func (pm *ProtocolManager) handleSyncMsg(msg p2p.Msg, p *peer) error { |
| 419 | // Handle the message depending on its contents |
| 420 | switch { |
| 421 | case msg.Code == StatusMsg: |
| 422 | // Status messages should never arrive after the handshake |
| 423 | return errResp(ErrExtraStatusMsg, "uncontrolled status message") |
| 424 | |
| 425 | // Block header query, collect the requested headers and reply |
| 426 | case msg.Code == GetBlockHeadersMsg: |
| 427 | // Decode the complex header query |
| 428 | var query getBlockHeadersData |
| 429 | if err := msg.Decode(&query); err != nil { |
| 430 | return errResp(ErrDecode, "%v: %v", msg, err) |
| 431 | } |
| 432 | |
| 433 | log.Debug("received GetBlockHeadersMsg", "hash", query.Origin.Hash.Hex(), "number", query.Origin.Number) |
| 434 | |
| 435 | hashMode := query.Origin.Hash != (common.Hash{}) |
| 436 | first := true |
| 437 | maxNonCanonical := uint64(100) |
| 438 | |
| 439 | // Gather headers until the fetch or network limits is reached |
| 440 | var ( |
| 441 | bytes common.StorageSize |
| 442 | headers []*types.Header |
| 443 | unknown bool |
| 444 | ) |
| 445 | for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit && len(headers) < syncer.MaxHeaderFetch { |
| 446 | // Retrieve the next header satisfying the query |
| 447 | var origin *types.Header |
| 448 | if hashMode { |
| 449 | if first { |
| 450 | first = false |
| 451 | origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash) |
| 452 | if origin != nil { |
| 453 | query.Origin.Number = origin.Number.Uint64() |
| 454 | } |
| 455 | } else { |
| 456 | origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number) |
| 457 | } |
| 458 | } else { |
| 459 | origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number) |
| 460 | } |
| 461 | if origin == nil { |
| 462 | break |
| 463 | } |
| 464 | headers = append(headers, origin) |
| 465 | bytes += estHeaderRlpSize |
| 466 | |
| 467 | // Advance to the next header of the query |
| 468 | switch { |
| 469 | case hashMode && query.Reverse: |
| 470 | // Hash based traversal towards the genesis block |
| 471 | ancestor := query.Skip + 1 |
| 472 | if ancestor == 0 { |
| 473 | unknown = true |
| 474 | } else { |
| 475 | query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical) |
no test coverage detected