Add support for eth/67 (#4564)

* Add eth/67

* Listen to eth/66 on a separate port

* Fix compilation error

* Fix cfg66.ListenAddr

* Update erigon ports in README

* Expose port 30304 in docker

* P2pProtocolVersionFlag instead of second sentry

* Remove "66 by default" from usage

* Small comment
This commit is contained in:
Andrew Ashikhmin 2022-07-08 11:14:16 +02:00 committed by GitHub
parent 9f5b401547
commit eec5fa4d41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 83 additions and 33 deletions

View File

@ -393,12 +393,12 @@ Detailed explanation: [./docs/programmers_guide/db_faq.md](./docs/programmers_gu
| Port | Protocol | Purpose | Expose |
|:-----:|:---------:|:----------------------:|:-------:|
| 30303 | TCP & UDP | eth/66 peering | Public |
| 30303 | TCP & UDP | eth/66 or 67 peering | Public |
| 9090 | TCP | gRPC Connections | Private |
| 42069 | TCP & UDP | Snap sync (Bittorrent) | Public |
| 6060 | TCP | Metrics or Pprof | Private |
Typically, 30303 and 30304 are exposed to the internet to allow incoming peering connections. 9090 is exposed only
Typically, 30303 is exposed to the internet to allow incoming peering connections. 9090 is exposed only
internally for rpcdaemon or other connections, (e.g. rpcdaemon -> erigon).
#### `RPC` ports

View File

@ -4,6 +4,11 @@ import (
"context"
"crypto/ecdsa"
"fmt"
"math/big"
"net"
"strings"
"time"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/core/forkid"
"github.com/ledgerwatch/erigon/crypto"
@ -12,10 +17,6 @@ import (
"github.com/ledgerwatch/erigon/p2p/rlpx"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/rlp"
"math/big"
"net"
"strings"
"time"
)
// https://github.com/ethereum/devp2p/blob/master/rlpx.md#p2p-capability
@ -240,6 +241,7 @@ func makeOurHelloMessage(myPrivateKey *ecdsa.PrivateKey) HelloMessage {
{Name: eth.ProtocolName, Version: 64},
{Name: eth.ProtocolName, Version: 65},
{Name: eth.ProtocolName, Version: eth.ETH66},
{Name: eth.ProtocolName, Version: eth.ETH67},
}
return HelloMessage{

View File

@ -8,7 +8,6 @@ import (
"github.com/ledgerwatch/erigon/cmd/sentry/sentry"
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon/common/paths"
"github.com/ledgerwatch/erigon/eth/protocols/eth"
"github.com/ledgerwatch/erigon/internal/debug"
"github.com/ledgerwatch/erigon/node/nodecfg/datadir"
node2 "github.com/ledgerwatch/erigon/turbo/node"
@ -27,7 +26,7 @@ var (
trustedPeers []string // trusted peers
discoveryDNS []string
nodiscover bool // disable sentry's discovery mechanism
protocol string
protocol int
netRestrict string // CIDR to restrict peering to
maxPeers int
maxPendPeers int
@ -45,7 +44,7 @@ func init() {
rootCmd.Flags().StringSliceVar(&trustedPeers, utils.TrustedPeersFlag.Name, []string{}, utils.TrustedPeersFlag.Usage)
rootCmd.Flags().StringSliceVar(&discoveryDNS, utils.DNSDiscoveryFlag.Name, []string{}, utils.DNSDiscoveryFlag.Usage)
rootCmd.Flags().BoolVar(&nodiscover, utils.NoDiscoverFlag.Name, false, utils.NoDiscoverFlag.Usage)
rootCmd.Flags().StringVar(&protocol, "p2p.protocol", "eth66", "eth66")
rootCmd.Flags().IntVar(&protocol, utils.P2pProtocolVersionFlag.Name, utils.P2pProtocolVersionFlag.Value, utils.P2pProtocolVersionFlag.Usage)
rootCmd.Flags().StringVar(&netRestrict, utils.NetrestrictFlag.Name, utils.NetrestrictFlag.Value, utils.NetrestrictFlag.Usage)
rootCmd.Flags().IntVar(&maxPeers, utils.MaxPeersFlag.Name, utils.MaxPeersFlag.Value, utils.MaxPeersFlag.Usage)
rootCmd.Flags().IntVar(&maxPendPeers, utils.MaxPendingPeersFlag.Name, utils.MaxPendingPeersFlag.Value, utils.MaxPendingPeersFlag.Usage)
@ -68,8 +67,6 @@ var rootCmd = &cobra.Command{
debug.Exit()
},
RunE: func(cmd *cobra.Command, args []string) error {
p := eth.ETH66
dirs := datadir.New(datadirCli)
nodeConfig := node2.NewNodeConfig()
p2pConfig, err := utils.NewP2PConfig(
@ -83,13 +80,13 @@ var rootCmd = &cobra.Command{
staticPeers,
trustedPeers,
uint(port),
uint(p),
uint(protocol),
)
if err != nil {
return err
}
return sentry.Sentry(cmd.Context(), dirs, sentryAddr, discoveryDNS, p2pConfig, uint(p), healthCheck)
return sentry.Sentry(cmd.Context(), dirs, sentryAddr, discoveryDNS, p2pConfig, uint(protocol), healthCheck)
},
}

View File

@ -54,7 +54,7 @@ func (cs *MultiClient) PropagateNewBlockHashes(ctx context.Context, announces []
switch sentry.Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
if req66 == nil {
req66 = &proto_sentry.OutboundMessageData{
Id: proto_sentry.MessageId_NEW_BLOCK_HASHES_66,
@ -95,7 +95,7 @@ func (cs *MultiClient) BroadcastNewBlock(ctx context.Context, block *types.Block
switch sentry.Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
if req66 == nil {
req66 = &proto_sentry.SendMessageToRandomPeersRequest{
MaxPeers: 1024,
@ -153,7 +153,7 @@ func (cs *MultiClient) BroadcastLocalPooledTxs(ctx context.Context, txs []common
}
switch sentry.Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
if req66 == nil {
req66 = &proto_sentry.OutboundMessageData{
Id: proto_sentry.MessageId_NEW_POOLED_TRANSACTION_HASHES_66,
@ -213,7 +213,7 @@ func (cs *MultiClient) BroadcastRemotePooledTxs(ctx context.Context, txs []commo
switch sentry.Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
if req66 == nil {
req66 = &proto_sentry.SendMessageToRandomPeersRequest{
MaxPeers: 1024,
@ -264,7 +264,7 @@ func (cs *MultiClient) PropagatePooledTxsToPeersList(ctx context.Context, peers
for _, peer := range peers {
switch sentry.Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
req66 := &proto_sentry.SendMessageByIdRequest{
PeerId: peer,
Data: &proto_sentry.OutboundMessageData{

View File

@ -44,7 +44,7 @@ func (cs *MultiClient) SendBodyRequest(ctx context.Context, req *bodydownload.Bo
}
switch cs.sentries[i].Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
//log.Info(fmt.Sprintf("Sending body request for %v", req.BlockNums))
var bytes []byte
var err error
@ -85,7 +85,7 @@ func (cs *MultiClient) SendHeaderRequest(ctx context.Context, req *headerdownloa
continue
}
switch cs.sentries[i].Protocol() {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
//log.Info(fmt.Sprintf("Sending header request {hash: %x, height: %d, length: %d}", req.Hash, req.Number, req.Length))
reqData := &eth.GetBlockHeadersPacket66{
RequestId: rand.Uint64(),

View File

@ -357,6 +357,10 @@ func runPeer(
}
send(eth.ToProto[protocol][msg.Code], peerID, b)
case eth.GetNodeDataMsg:
if protocol >= eth.ETH67 {
msg.Discard()
return fmt.Errorf("unexpected GetNodeDataMsg from %s in eth/%d", peerID, protocol)
}
if !hasSubscribers(eth.ToProto[protocol][msg.Code]) {
continue
}
@ -491,7 +495,7 @@ func NewGrpcServer(ctx context.Context, dialCandidates enode.Iterator, readNodeI
peersStreams: NewPeersStreams(),
}
if protocol != eth.ETH66 {
if protocol != eth.ETH66 && protocol != eth.ETH67 {
panic(fmt.Errorf("unexpected p2p protocol: %d", protocol))
}
@ -631,7 +635,7 @@ func (ss *GrpcServer) writePeer(logPrefix string, peerInfo *PeerInfo, msgcode ui
func (ss *GrpcServer) startSync(ctx context.Context, bestHash common.Hash, peerID [64]byte) error {
switch ss.Protocol.Version {
case eth.ETH66:
case eth.ETH66, eth.ETH67:
b, err := rlp.EncodeToBytes(&eth.GetBlockHeadersPacket66{
RequestId: rand.Uint64(),
GetBlockHeadersPacket: &eth.GetBlockHeadersPacket{
@ -805,6 +809,8 @@ func (ss *GrpcServer) HandShake(context.Context, *emptypb.Empty) (*proto_sentry.
switch ss.Protocol.Version {
case eth.ETH66:
reply.Protocol = proto_sentry.Protocol_ETH66
case eth.ETH67:
reply.Protocol = proto_sentry.Protocol_ETH67
}
return reply, nil
}

View File

@ -504,6 +504,11 @@ var (
Usage: "Network listening port",
Value: 30303,
}
P2pProtocolVersionFlag = cli.IntFlag{
Name: "p2p.protocol",
Usage: "Version of eth p2p protocol",
Value: int(nodecfg.DefaultConfig.P2P.ProtocolVersion),
}
SentryAddrFlag = cli.StringFlag{
Name: "sentry.api.addr",
Usage: "comma separated sentry addresses '<host>:<port>,<host>:<port>'",
@ -850,6 +855,8 @@ func NewP2PConfig(
switch protocol {
case eth.ETH66:
enodeDBPath = filepath.Join(dirs.Nodes, "eth66")
case eth.ETH67:
enodeDBPath = filepath.Join(dirs.Nodes, "eth67")
default:
return nil, fmt.Errorf("unknown protocol: %v", protocol)
}
@ -910,6 +917,9 @@ func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
if ctx.GlobalIsSet(ListenPortFlag.Name) {
cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name))
}
if ctx.GlobalIsSet(P2pProtocolVersionFlag.Name) {
cfg.ProtocolVersion = uint(ctx.GlobalInt(P2pProtocolVersionFlag.Name))
}
if ctx.GlobalIsSet(SentryAddrFlag.Name) {
cfg.SentryAddr = SplitAndTrim(ctx.GlobalString(SentryAddrFlag.Name))
}

View File

@ -235,16 +235,16 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere
return res
}
d66, err := setupDiscovery(backend.config.EthDiscoveryURLs)
discovery, err := setupDiscovery(backend.config.EthDiscoveryURLs)
if err != nil {
return nil, err
}
cfg := stack.Config().P2P
cfg.NodeDatabase = filepath.Join(stack.Config().Dirs.Nodes, eth.ProtocolToString[cfg.ProtocolVersion])
server := sentry.NewGrpcServer(backend.sentryCtx, discovery, readNodeInfo, &cfg, cfg.ProtocolVersion)
cfg66 := stack.Config().P2P
cfg66.NodeDatabase = filepath.Join(stack.Config().Dirs.Nodes, "eth66")
server66 := sentry.NewGrpcServer(backend.sentryCtx, d66, readNodeInfo, &cfg66, eth.ETH66)
backend.sentryServers = append(backend.sentryServers, server66)
sentries = []direct.SentryClient{direct.NewSentryClientDirect(eth.ETH66, server66)}
backend.sentryServers = append(backend.sentryServers, server)
sentries = []direct.SentryClient{direct.NewSentryClientDirect(cfg.ProtocolVersion, server)}
go func() {
logEvery := time.NewTicker(120 * time.Second)

View File

@ -34,10 +34,12 @@ import (
// Constants to match up protocol versions and messages
const (
ETH66 = 66
ETH67 = 67
)
var ProtocolToString = map[uint]string{
ETH66: "eth66",
ETH67: "eth67",
}
// ProtocolName is the official short name of the `eth` protocol used during
@ -86,6 +88,20 @@ var ToProto = map[uint]map[uint64]proto_sentry.MessageId{
GetPooledTransactionsMsg: proto_sentry.MessageId_GET_POOLED_TRANSACTIONS_66,
PooledTransactionsMsg: proto_sentry.MessageId_POOLED_TRANSACTIONS_66,
},
ETH67: {
GetBlockHeadersMsg: proto_sentry.MessageId_GET_BLOCK_HEADERS_66,
BlockHeadersMsg: proto_sentry.MessageId_BLOCK_HEADERS_66,
GetBlockBodiesMsg: proto_sentry.MessageId_GET_BLOCK_BODIES_66,
BlockBodiesMsg: proto_sentry.MessageId_BLOCK_BODIES_66,
GetReceiptsMsg: proto_sentry.MessageId_GET_RECEIPTS_66,
ReceiptsMsg: proto_sentry.MessageId_RECEIPTS_66,
NewBlockHashesMsg: proto_sentry.MessageId_NEW_BLOCK_HASHES_66,
NewBlockMsg: proto_sentry.MessageId_NEW_BLOCK_66,
TransactionsMsg: proto_sentry.MessageId_TRANSACTIONS_66,
NewPooledTransactionHashesMsg: proto_sentry.MessageId_NEW_POOLED_TRANSACTION_HASHES_66,
GetPooledTransactionsMsg: proto_sentry.MessageId_GET_POOLED_TRANSACTIONS_66,
PooledTransactionsMsg: proto_sentry.MessageId_POOLED_TRANSACTIONS_66,
},
}
var FromProto = map[uint]map[proto_sentry.MessageId]uint64{
@ -105,6 +121,20 @@ var FromProto = map[uint]map[proto_sentry.MessageId]uint64{
proto_sentry.MessageId_GET_POOLED_TRANSACTIONS_66: GetPooledTransactionsMsg,
proto_sentry.MessageId_POOLED_TRANSACTIONS_66: PooledTransactionsMsg,
},
ETH67: {
proto_sentry.MessageId_GET_BLOCK_HEADERS_66: GetBlockHeadersMsg,
proto_sentry.MessageId_BLOCK_HEADERS_66: BlockHeadersMsg,
proto_sentry.MessageId_GET_BLOCK_BODIES_66: GetBlockBodiesMsg,
proto_sentry.MessageId_BLOCK_BODIES_66: BlockBodiesMsg,
proto_sentry.MessageId_GET_RECEIPTS_66: GetReceiptsMsg,
proto_sentry.MessageId_RECEIPTS_66: ReceiptsMsg,
proto_sentry.MessageId_NEW_BLOCK_HASHES_66: NewBlockHashesMsg,
proto_sentry.MessageId_NEW_BLOCK_66: NewBlockMsg,
proto_sentry.MessageId_TRANSACTIONS_66: TransactionsMsg,
proto_sentry.MessageId_NEW_POOLED_TRANSACTION_HASHES_66: NewPooledTransactionHashesMsg,
proto_sentry.MessageId_GET_POOLED_TRANSACTIONS_66: GetPooledTransactionsMsg,
proto_sentry.MessageId_POOLED_TRANSACTIONS_66: PooledTransactionsMsg,
},
}
// Packet represents a p2p message in the `eth` protocol.

View File

@ -45,7 +45,7 @@ var DefaultConfig = Config{
WSModules: []string{"net", "web3"},
P2P: p2p.Config{
ListenAddr: ":30303",
ListenAddr65: ":30304",
ProtocolVersion: 66, // eth/66 by default
MaxPeers: 100,
MaxPendingPeers: 1000,
NAT: nat.Any(),

View File

@ -24,13 +24,14 @@ import (
"encoding/hex"
"errors"
"fmt"
"golang.org/x/sync/semaphore"
"net"
"sort"
"sync"
"sync/atomic"
"time"
"golang.org/x/sync/semaphore"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/debug"
"github.com/ledgerwatch/erigon/common/mclock"
@ -136,9 +137,12 @@ type Config struct {
// If the port is zero, the operating system will pick a port. The
// ListenAddr field will be updated with the actual address when
// the server is started.
ListenAddr string
ListenAddr65 string
SentryAddr []string
ListenAddr string
// eth/66, eth/67, etc
ProtocolVersion uint
SentryAddr []string
// If set to a non-nil value, the given NAT port mapper
// is used to make the listening port available to the

View File

@ -89,6 +89,7 @@ var DefaultFlags = []cli.Flag{
utils.TorrentDownloadRateFlag,
utils.TorrentVerbosityFlag,
utils.ListenPortFlag,
utils.P2pProtocolVersionFlag,
utils.NATFlag,
utils.NoDiscoverFlag,
utils.DiscoveryV5Flag,