les, light: remove untrusted header retrieval in ODR (#21907)
* les, light: remove untrusted header retrieval in ODR * les: polish * light: check the hash equality in odr
This commit is contained in:
@ -17,6 +17,7 @@
|
||||
package les
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@ -200,14 +201,23 @@ func (h *clientHandler) handleMsg(p *serverPeer) error {
|
||||
p.fcServer.ReceivedReply(resp.ReqID, resp.BV)
|
||||
p.answeredRequest(resp.ReqID)
|
||||
|
||||
// Filter out any explicitly requested headers, deliver the rest to the downloader
|
||||
filter := len(headers) == 1
|
||||
if filter {
|
||||
headers = h.fetcher.deliverHeaders(p, resp.ReqID, resp.Headers)
|
||||
}
|
||||
if len(headers) != 0 || !filter {
|
||||
if err := h.downloader.DeliverHeaders(p.id, headers); err != nil {
|
||||
log.Debug("Failed to deliver headers", "err", err)
|
||||
// Filter out the explicitly requested header by the retriever
|
||||
if h.backend.retriever.requested(resp.ReqID) {
|
||||
deliverMsg = &Msg{
|
||||
MsgType: MsgBlockHeaders,
|
||||
ReqID: resp.ReqID,
|
||||
Obj: resp.Headers,
|
||||
}
|
||||
} else {
|
||||
// Filter out any explicitly requested headers, deliver the rest to the downloader
|
||||
filter := len(headers) == 1
|
||||
if filter {
|
||||
headers = h.fetcher.deliverHeaders(p, resp.ReqID, resp.Headers)
|
||||
}
|
||||
if len(headers) != 0 || !filter {
|
||||
if err := h.downloader.DeliverHeaders(p.id, headers); err != nil {
|
||||
log.Debug("Failed to deliver headers", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
case BlockBodiesMsg:
|
||||
@ -394,6 +404,42 @@ func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip
|
||||
return nil
|
||||
}
|
||||
|
||||
// RetrieveSingleHeaderByNumber requests a single header by the specified block
|
||||
// number. This function will wait the response until it's timeout or delivered.
|
||||
func (pc *peerConnection) RetrieveSingleHeaderByNumber(context context.Context, number uint64) (*types.Header, error) {
|
||||
reqID := genReqID()
|
||||
rq := &distReq{
|
||||
getCost: func(dp distPeer) uint64 {
|
||||
peer := dp.(*serverPeer)
|
||||
return peer.getRequestCost(GetBlockHeadersMsg, 1)
|
||||
},
|
||||
canSend: func(dp distPeer) bool {
|
||||
return dp.(*serverPeer) == pc.peer
|
||||
},
|
||||
request: func(dp distPeer) func() {
|
||||
peer := dp.(*serverPeer)
|
||||
cost := peer.getRequestCost(GetBlockHeadersMsg, 1)
|
||||
peer.fcServer.QueuedRequest(reqID, cost)
|
||||
return func() { peer.requestHeadersByNumber(reqID, number, 1, 0, false) }
|
||||
},
|
||||
}
|
||||
var header *types.Header
|
||||
if err := pc.handler.backend.retriever.retrieve(context, reqID, rq, func(peer distPeer, msg *Msg) error {
|
||||
if msg.MsgType != MsgBlockHeaders {
|
||||
return errInvalidMessageType
|
||||
}
|
||||
headers := msg.Obj.([]*types.Header)
|
||||
if len(headers) != 1 {
|
||||
return errInvalidEntryCount
|
||||
}
|
||||
header = headers[0]
|
||||
return nil
|
||||
}, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return header, nil
|
||||
}
|
||||
|
||||
// downloaderPeerNotify implements peerSetNotify
|
||||
type downloaderPeerNotify clientHandler
|
||||
|
||||
|
Reference in New Issue
Block a user