erigon-pulse/cmd/lightclient/sentinel/handlers/handlers.go
Mike Neuder 29ff8daa92
req/resp heartbeat handler modifications (#5859)
addressing some aspects of the req/resp portion of the CL spec:
https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#reqresp-interaction.

this PR does a few things: 
1. moves `blocksByRangeHandler` and `beaconBlocksByRootHandler` handlers
to a different file in the `handlers` package. these are going to be the
more complicated handlers so they will be better in their own files.
2. makes `pingHandler` a method on the `*ConsensusHandlers` receiver and
starts returning the sequence number instead of the request. (see
https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#ping
`Peers request and respond with their local metadata sequence number`).
3. adds a `goodbyeHandler` to respond with a status message of 1. (see
https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#goodbye).
4. makes `statusHandler` a method on the `*ConsensusHandlers` receiver.
(the rest of this handler is still not implemented.
5. refactored the `heartbeats_test` into a table driven test. this makes
the test much more readable:
https://dave.cheney.net/2019/05/07/prefer-table-driven-tests.
2022-10-25 19:30:11 +02:00

64 lines
2.3 KiB
Go

/*
Copyright 2022 Erigon-Lightclient contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handlers
import (
"github.com/ledgerwatch/erigon/cmd/lightclient/cltypes"
"github.com/ledgerwatch/erigon/cmd/lightclient/sentinel/communication/ssz_snappy"
"github.com/ledgerwatch/erigon/cmd/lightclient/sentinel/peers"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/protocol"
)
type ConsensusHandlers struct {
handlers map[protocol.ID]network.StreamHandler
host host.Host
peers *peers.Peers
metadata *cltypes.MetadataV2
}
const SuccessfulResponsePrefix = 0x00
var NoRequestHandlers = map[string]bool{
MetadataProtocolV1: true,
MetadataProtocolV2: true,
LightClientFinalityUpdateV1: true,
}
func NewConsensusHandlers(host host.Host, peers *peers.Peers, metadata *cltypes.MetadataV2) *ConsensusHandlers {
c := &ConsensusHandlers{
peers: peers,
host: host,
metadata: metadata,
}
c.handlers = map[protocol.ID]network.StreamHandler{
protocol.ID(PingProtocolV1): curryStreamHandler(ssz_snappy.NewStreamCodec, c.pingHandler),
protocol.ID(GoodbyeProtocolV1): curryStreamHandler(ssz_snappy.NewStreamCodec, c.goodbyeHandler),
protocol.ID(StatusProtocolV1): curryStreamHandler(ssz_snappy.NewStreamCodec, c.statusHandler),
protocol.ID(MetadataProtocolV1): curryStreamHandler(ssz_snappy.NewStreamCodec, c.metadataV1Handler),
protocol.ID(MetadataProtocolV2): curryStreamHandler(ssz_snappy.NewStreamCodec, c.metadataV2Handler),
protocol.ID(BeaconBlockByRangeProtocolV1): c.blocksByRangeHandler,
protocol.ID(BeaconBlockByRootProtocolV1): c.beaconBlocksByRootHandler,
}
return c
}
func (c *ConsensusHandlers) Start() {
for id, handler := range c.handlers {
c.host.SetStreamHandler(id, handler)
}
}