diff --git a/node/direct/sentry_client.go b/node/direct/sentry_client.go
index 0380fb80bef..a3c077876a0 100644
--- a/node/direct/sentry_client.go
+++ b/node/direct/sentry_client.go
@@ -28,37 +28,25 @@ import (
"github.com/erigontech/erigon/node/gointerfaces/sentryproto"
"github.com/erigontech/erigon/node/gointerfaces/typesproto"
+ "github.com/erigontech/erigon/p2p/protocols/eth"
+ "github.com/erigontech/erigon/p2p/protocols/wit"
"github.com/erigontech/erigon/p2p/sentry/libsentry"
)
const (
- ETH68 = 68
- ETH69 = 69
- ETH70 = 70
- ETH71 = 71
+ ETH68 = eth.ETH68
+ ETH69 = eth.ETH69
+ ETH70 = eth.ETH70
+ ETH71 = eth.ETH71
- WIT0 = 1
+ WIT0 = wit.WIT1
)
var (
- ProtocolToUintMap = map[sentryproto.Protocol]uint{
- sentryproto.Protocol_ETH68: ETH68,
- sentryproto.Protocol_ETH69: ETH69,
- sentryproto.Protocol_ETH70: ETH70,
- sentryproto.Protocol_ETH71: ETH71,
- }
- UintToProtocolMap = map[uint]sentryproto.Protocol{
- ETH68: sentryproto.Protocol_ETH68,
- ETH69: sentryproto.Protocol_ETH69,
- ETH70: sentryproto.Protocol_ETH70,
- ETH71: sentryproto.Protocol_ETH71,
- }
- SupportedSideProtocols = map[sentryproto.Protocol]struct{}{
- sentryproto.Protocol_WIT0: {},
- }
- UintToSideProtocolMap = map[uint]sentryproto.Protocol{
- WIT0: sentryproto.Protocol_WIT0,
- }
+ ProtocolToUintMap = libsentry.ProtocolToUintMap
+ UintToProtocolMap = libsentry.UintToProtocolMap
+ SupportedSideProtocols = libsentry.SupportedSideProtocols
+ UintToSideProtocolMap = libsentry.UintToSideProtocolMap
)
//go:generate mockgen -typed=true -destination=./sentry_client_mock.go -package=direct . SentryClient
diff --git a/p2p/protocols/eth/handlers.go b/p2p/protocols/eth/handlers.go
index 69bb976ff3e..c376229dd9f 100644
--- a/p2p/protocols/eth/handlers.go
+++ b/p2p/protocols/eth/handlers.go
@@ -283,7 +283,7 @@ const NoSizeLimit = math.MaxInt
// ReceiptQueryOpts controls the behavior differences between eth protocol versions
// when answering GetReceipts queries.
type ReceiptQueryOpts struct {
- // EthVersion is the protocol version (e.g. direct.ETH68, direct.ETH69, direct.ETH70).
+ // EthVersion is the protocol version (e.g. ETH68, ETH69, ETH70).
// eth/69+ uses encoding without the Bloom field.
EthVersion uint
// FirstBlockReceiptIndex skips this many receipts from the first block (eth/70).
diff --git a/p2p/protocols/eth/handlers_receipts_query_test.go b/p2p/protocols/eth/handlers_receipts_query_test.go
index e494ec3d57a..a12182f34a4 100644
--- a/p2p/protocols/eth/handlers_receipts_query_test.go
+++ b/p2p/protocols/eth/handlers_receipts_query_test.go
@@ -31,7 +31,6 @@ import (
"github.com/erigontech/erigon/execution/chain"
"github.com/erigontech/erigon/execution/rlp"
"github.com/erigontech/erigon/execution/types"
- "github.com/erigontech/erigon/node/direct"
)
// Per the devp2p spec, a Receipts response carries one receipt list per requested
@@ -97,7 +96,7 @@ func answerQuery(t *testing.T, f *receiptsQueryFixture) ([]rlp.RawValue, bool, e
tx, err := db.BeginTemporalRo(context.Background())
require.NoError(t, err)
defer tx.Rollback()
- opts := ReceiptQueryOpts{EthVersion: direct.ETH68, SizeLimit: NoSizeLimit}
+ opts := ReceiptQueryOpts{EthVersion: ETH68, SizeLimit: NoSizeLimit}
return AnswerGetReceiptsQuery(context.Background(), chain.TestChainBerlinConfig, f.getter, f.br, tx, f.query, nil, opts)
}
diff --git a/p2p/protocols/eth/protocol.go b/p2p/protocols/eth/protocol.go
index 425ea1cba2b..fa334ad2288 100644
--- a/p2p/protocols/eth/protocol.go
+++ b/p2p/protocols/eth/protocol.go
@@ -22,6 +22,7 @@ package eth
import (
"fmt"
"io"
+ "maps"
"math/big"
"github.com/holiman/uint256"
@@ -29,16 +30,22 @@ import (
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/execution/rlp"
"github.com/erigontech/erigon/execution/types"
- "github.com/erigontech/erigon/node/direct"
"github.com/erigontech/erigon/node/gointerfaces/sentryproto"
"github.com/erigontech/erigon/p2p/forkid"
)
+const (
+ ETH68 = 68
+ ETH69 = 69
+ ETH70 = 70
+ ETH71 = 71
+)
+
var ProtocolToString = map[uint]string{
- direct.ETH68: "eth68",
- direct.ETH69: "eth69",
- direct.ETH70: "eth70",
- direct.ETH71: "eth71",
+ ETH68: "eth68",
+ ETH69: "eth69",
+ ETH70: "eth70",
+ ETH71: "eth71",
}
// ProtocolName is the official short name of the `eth` protocol used during
@@ -49,7 +56,7 @@ const ProtocolName = "eth"
const maxMessageSize = 10 * 1024 * 1024
const ProtocolMaxMsgSize = maxMessageSize
-var ProtocolLengths = map[uint]uint64{direct.ETH68: 17, direct.ETH69: 18, direct.ETH70: 18, direct.ETH71: 20}
+var ProtocolLengths = map[uint]uint64{ETH68: 17, ETH69: 18, ETH70: 18, ETH71: 20}
const (
// Protocol messages in eth/64
@@ -75,137 +82,70 @@ const (
BlockAccessListsMsg = 0x13
)
+var toProto68 = map[uint64]sentryproto.MessageId{
+ GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
+ BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
+ GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
+ BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
+ GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_66,
+ ReceiptsMsg: sentryproto.MessageId_RECEIPTS_66,
+ NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
+ NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
+ TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
+ NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
+ GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
+ PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
+}
+
+var toProto69 = withDelta(toProto68, map[uint64]sentryproto.MessageId{
+ StatusMsg: sentryproto.MessageId_STATUS_69,
+ GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_69,
+ BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69,
+})
+
+var toProto70 = withDelta(toProto69, map[uint64]sentryproto.MessageId{
+ GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_70,
+ ReceiptsMsg: sentryproto.MessageId_RECEIPTS_70,
+})
+
+var toProto71 = withDelta(toProto70, map[uint64]sentryproto.MessageId{
+ GetBlockAccessListsMsg: sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71,
+ BlockAccessListsMsg: sentryproto.MessageId_BLOCK_ACCESS_LISTS_71,
+})
+
var ToProto = map[uint]map[uint64]sentryproto.MessageId{
- direct.ETH68: {
- GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
- BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
- GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
- BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
- GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_66,
- ReceiptsMsg: sentryproto.MessageId_RECEIPTS_66,
- NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
- NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
- TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
- NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68, // Modified in eth/68
- GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
- PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
- },
- direct.ETH69: {
- StatusMsg: sentryproto.MessageId_STATUS_69,
- GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
- BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
- GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
- BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
- GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_69, // Modified in eth/69
- ReceiptsMsg: sentryproto.MessageId_RECEIPTS_66,
- NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
- NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
- TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
- NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
- GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
- PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
- BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69, // Modified in eth/69
- },
- direct.ETH70: {
- StatusMsg: sentryproto.MessageId_STATUS_69,
- GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
- BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
- GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
- BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
- GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_70, // Modified in eth/70
- ReceiptsMsg: sentryproto.MessageId_RECEIPTS_70, // Modified in eth/70
- NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
- NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
- TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
- NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
- GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
- PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
- BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69,
- },
- direct.ETH71: {
- StatusMsg: sentryproto.MessageId_STATUS_69,
- GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
- BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
- GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
- BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
- GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_70,
- ReceiptsMsg: sentryproto.MessageId_RECEIPTS_70,
- NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
- NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
- TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
- NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
- GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
- PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
- BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69,
- // Added in eth/71 (EIP-8159 Block Access List Exchange)
- GetBlockAccessListsMsg: sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71,
- BlockAccessListsMsg: sentryproto.MessageId_BLOCK_ACCESS_LISTS_71,
- },
-}
-
-var FromProto = map[uint]map[sentryproto.MessageId]uint64{
- direct.ETH68: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: GetBlockHeadersMsg,
- sentryproto.MessageId_BLOCK_HEADERS_66: BlockHeadersMsg,
- sentryproto.MessageId_GET_BLOCK_BODIES_66: GetBlockBodiesMsg,
- sentryproto.MessageId_BLOCK_BODIES_66: BlockBodiesMsg,
- sentryproto.MessageId_GET_RECEIPTS_66: GetReceiptsMsg,
- sentryproto.MessageId_RECEIPTS_66: ReceiptsMsg,
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: NewBlockHashesMsg,
- sentryproto.MessageId_NEW_BLOCK_66: NewBlockMsg,
- sentryproto.MessageId_TRANSACTIONS_66: TransactionsMsg,
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: NewPooledTransactionHashesMsg,
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: GetPooledTransactionsMsg,
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: PooledTransactionsMsg,
- },
- direct.ETH69: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: GetBlockHeadersMsg,
- sentryproto.MessageId_BLOCK_HEADERS_66: BlockHeadersMsg,
- sentryproto.MessageId_GET_BLOCK_BODIES_66: GetBlockBodiesMsg,
- sentryproto.MessageId_BLOCK_BODIES_66: BlockBodiesMsg,
- sentryproto.MessageId_GET_RECEIPTS_69: GetReceiptsMsg,
- sentryproto.MessageId_RECEIPTS_66: ReceiptsMsg,
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: NewBlockHashesMsg,
- sentryproto.MessageId_NEW_BLOCK_66: NewBlockMsg,
- sentryproto.MessageId_TRANSACTIONS_66: TransactionsMsg,
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: NewPooledTransactionHashesMsg,
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: GetPooledTransactionsMsg,
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: PooledTransactionsMsg,
- sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: BlockRangeUpdateMsg,
- },
- direct.ETH70: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: GetBlockHeadersMsg,
- sentryproto.MessageId_BLOCK_HEADERS_66: BlockHeadersMsg,
- sentryproto.MessageId_GET_BLOCK_BODIES_66: GetBlockBodiesMsg,
- sentryproto.MessageId_BLOCK_BODIES_66: BlockBodiesMsg,
- sentryproto.MessageId_GET_RECEIPTS_70: GetReceiptsMsg,
- sentryproto.MessageId_RECEIPTS_70: ReceiptsMsg,
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: NewBlockHashesMsg,
- sentryproto.MessageId_NEW_BLOCK_66: NewBlockMsg,
- sentryproto.MessageId_TRANSACTIONS_66: TransactionsMsg,
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: NewPooledTransactionHashesMsg,
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: GetPooledTransactionsMsg,
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: PooledTransactionsMsg,
- sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: BlockRangeUpdateMsg,
- },
- direct.ETH71: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: GetBlockHeadersMsg,
- sentryproto.MessageId_BLOCK_HEADERS_66: BlockHeadersMsg,
- sentryproto.MessageId_GET_BLOCK_BODIES_66: GetBlockBodiesMsg,
- sentryproto.MessageId_BLOCK_BODIES_66: BlockBodiesMsg,
- sentryproto.MessageId_GET_RECEIPTS_70: GetReceiptsMsg,
- sentryproto.MessageId_RECEIPTS_70: ReceiptsMsg,
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: NewBlockHashesMsg,
- sentryproto.MessageId_NEW_BLOCK_66: NewBlockMsg,
- sentryproto.MessageId_TRANSACTIONS_66: TransactionsMsg,
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: NewPooledTransactionHashesMsg,
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: GetPooledTransactionsMsg,
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: PooledTransactionsMsg,
- sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: BlockRangeUpdateMsg,
- // Added in eth/71 (EIP-8159 Block Access List Exchange)
- sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71: GetBlockAccessListsMsg,
- sentryproto.MessageId_BLOCK_ACCESS_LISTS_71: BlockAccessListsMsg,
- },
+ ETH68: toProto68,
+ ETH69: toProto69,
+ ETH70: toProto70,
+ ETH71: toProto71,
+}
+
+var FromProto = inverseWithoutStatus(ToProto)
+
+func withDelta(prev, changes map[uint64]sentryproto.MessageId) map[uint64]sentryproto.MessageId {
+ next := maps.Clone(prev)
+ maps.Copy(next, changes)
+ return next
+}
+
+// Status is handshake-only: FromProto omits it so that SendMessageById can
+// never emit a status frame.
+func inverseWithoutStatus(toProto map[uint]map[uint64]sentryproto.MessageId) map[uint]map[sentryproto.MessageId]uint64 {
+ fromProto := make(map[uint]map[sentryproto.MessageId]uint64, len(toProto))
+ for version, codes := range toProto {
+ inv := make(map[sentryproto.MessageId]uint64, len(codes))
+ for code, id := range codes {
+ if code == StatusMsg {
+ continue
+ }
+ if _, ok := inv[id]; ok {
+ panic(fmt.Sprintf("eth/%d: message id %s mapped from multiple message codes", version, id))
+ }
+ inv[id] = code
+ }
+ fromProto[version] = inv
+ }
+ return fromProto
}
// Packet represents a p2p message in the `eth` protocol.
diff --git a/p2p/protocols/eth/protocol_msgid_golden_test.go b/p2p/protocols/eth/protocol_msgid_golden_test.go
new file mode 100644
index 00000000000..0be6c65990b
--- /dev/null
+++ b/p2p/protocols/eth/protocol_msgid_golden_test.go
@@ -0,0 +1,191 @@
+// Copyright 2026 The Erigon Authors
+// This file is part of Erigon.
+//
+// Erigon is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Erigon is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with Erigon. If not, see .
+
+package eth_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/erigontech/erigon/node/gointerfaces/sentryproto"
+ "github.com/erigontech/erigon/p2p/protocols/eth"
+)
+
+var goldenToProto = map[uint]map[uint64]sentryproto.MessageId{
+ 68: {
+ eth.GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
+ eth.BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
+ eth.GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
+ eth.BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
+ eth.GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_66,
+ eth.ReceiptsMsg: sentryproto.MessageId_RECEIPTS_66,
+ eth.NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
+ eth.NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
+ eth.TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
+ eth.NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
+ eth.GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
+ eth.PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
+ },
+ 69: {
+ eth.StatusMsg: sentryproto.MessageId_STATUS_69,
+ eth.GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
+ eth.BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
+ eth.GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
+ eth.BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
+ eth.GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_69,
+ eth.ReceiptsMsg: sentryproto.MessageId_RECEIPTS_66,
+ eth.NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
+ eth.NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
+ eth.TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
+ eth.NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
+ eth.GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
+ eth.PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
+ eth.BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69,
+ },
+ 70: {
+ eth.StatusMsg: sentryproto.MessageId_STATUS_69,
+ eth.GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
+ eth.BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
+ eth.GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
+ eth.BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
+ eth.GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_70,
+ eth.ReceiptsMsg: sentryproto.MessageId_RECEIPTS_70,
+ eth.NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
+ eth.NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
+ eth.TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
+ eth.NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
+ eth.GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
+ eth.PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
+ eth.BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69,
+ },
+ 71: {
+ eth.StatusMsg: sentryproto.MessageId_STATUS_69,
+ eth.GetBlockHeadersMsg: sentryproto.MessageId_GET_BLOCK_HEADERS_66,
+ eth.BlockHeadersMsg: sentryproto.MessageId_BLOCK_HEADERS_66,
+ eth.GetBlockBodiesMsg: sentryproto.MessageId_GET_BLOCK_BODIES_66,
+ eth.BlockBodiesMsg: sentryproto.MessageId_BLOCK_BODIES_66,
+ eth.GetReceiptsMsg: sentryproto.MessageId_GET_RECEIPTS_70,
+ eth.ReceiptsMsg: sentryproto.MessageId_RECEIPTS_70,
+ eth.NewBlockHashesMsg: sentryproto.MessageId_NEW_BLOCK_HASHES_66,
+ eth.NewBlockMsg: sentryproto.MessageId_NEW_BLOCK_66,
+ eth.TransactionsMsg: sentryproto.MessageId_TRANSACTIONS_66,
+ eth.NewPooledTransactionHashesMsg: sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68,
+ eth.GetPooledTransactionsMsg: sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66,
+ eth.PooledTransactionsMsg: sentryproto.MessageId_POOLED_TRANSACTIONS_66,
+ eth.BlockRangeUpdateMsg: sentryproto.MessageId_BLOCK_RANGE_UPDATE_69,
+ eth.GetBlockAccessListsMsg: sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71,
+ eth.BlockAccessListsMsg: sentryproto.MessageId_BLOCK_ACCESS_LISTS_71,
+ },
+}
+
+var goldenFromProto = map[uint]map[sentryproto.MessageId]uint64{
+ 68: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: eth.GetBlockHeadersMsg,
+ sentryproto.MessageId_BLOCK_HEADERS_66: eth.BlockHeadersMsg,
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: eth.GetBlockBodiesMsg,
+ sentryproto.MessageId_BLOCK_BODIES_66: eth.BlockBodiesMsg,
+ sentryproto.MessageId_GET_RECEIPTS_66: eth.GetReceiptsMsg,
+ sentryproto.MessageId_RECEIPTS_66: eth.ReceiptsMsg,
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: eth.NewBlockHashesMsg,
+ sentryproto.MessageId_NEW_BLOCK_66: eth.NewBlockMsg,
+ sentryproto.MessageId_TRANSACTIONS_66: eth.TransactionsMsg,
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: eth.NewPooledTransactionHashesMsg,
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: eth.GetPooledTransactionsMsg,
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: eth.PooledTransactionsMsg,
+ },
+ 69: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: eth.GetBlockHeadersMsg,
+ sentryproto.MessageId_BLOCK_HEADERS_66: eth.BlockHeadersMsg,
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: eth.GetBlockBodiesMsg,
+ sentryproto.MessageId_BLOCK_BODIES_66: eth.BlockBodiesMsg,
+ sentryproto.MessageId_GET_RECEIPTS_69: eth.GetReceiptsMsg,
+ sentryproto.MessageId_RECEIPTS_66: eth.ReceiptsMsg,
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: eth.NewBlockHashesMsg,
+ sentryproto.MessageId_NEW_BLOCK_66: eth.NewBlockMsg,
+ sentryproto.MessageId_TRANSACTIONS_66: eth.TransactionsMsg,
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: eth.NewPooledTransactionHashesMsg,
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: eth.GetPooledTransactionsMsg,
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: eth.PooledTransactionsMsg,
+ sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: eth.BlockRangeUpdateMsg,
+ },
+ 70: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: eth.GetBlockHeadersMsg,
+ sentryproto.MessageId_BLOCK_HEADERS_66: eth.BlockHeadersMsg,
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: eth.GetBlockBodiesMsg,
+ sentryproto.MessageId_BLOCK_BODIES_66: eth.BlockBodiesMsg,
+ sentryproto.MessageId_GET_RECEIPTS_70: eth.GetReceiptsMsg,
+ sentryproto.MessageId_RECEIPTS_70: eth.ReceiptsMsg,
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: eth.NewBlockHashesMsg,
+ sentryproto.MessageId_NEW_BLOCK_66: eth.NewBlockMsg,
+ sentryproto.MessageId_TRANSACTIONS_66: eth.TransactionsMsg,
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: eth.NewPooledTransactionHashesMsg,
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: eth.GetPooledTransactionsMsg,
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: eth.PooledTransactionsMsg,
+ sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: eth.BlockRangeUpdateMsg,
+ },
+ 71: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: eth.GetBlockHeadersMsg,
+ sentryproto.MessageId_BLOCK_HEADERS_66: eth.BlockHeadersMsg,
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: eth.GetBlockBodiesMsg,
+ sentryproto.MessageId_BLOCK_BODIES_66: eth.BlockBodiesMsg,
+ sentryproto.MessageId_GET_RECEIPTS_70: eth.GetReceiptsMsg,
+ sentryproto.MessageId_RECEIPTS_70: eth.ReceiptsMsg,
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: eth.NewBlockHashesMsg,
+ sentryproto.MessageId_NEW_BLOCK_66: eth.NewBlockMsg,
+ sentryproto.MessageId_TRANSACTIONS_66: eth.TransactionsMsg,
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: eth.NewPooledTransactionHashesMsg,
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: eth.GetPooledTransactionsMsg,
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: eth.PooledTransactionsMsg,
+ sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: eth.BlockRangeUpdateMsg,
+ sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71: eth.GetBlockAccessListsMsg,
+ sentryproto.MessageId_BLOCK_ACCESS_LISTS_71: eth.BlockAccessListsMsg,
+ },
+}
+
+func TestToProtoGolden(t *testing.T) {
+ require.Equal(t, goldenToProto, eth.ToProto)
+}
+
+func TestFromProtoGolden(t *testing.T) {
+ require.Equal(t, goldenFromProto, eth.FromProto)
+}
+
+// FromProto deliberately omits the status ids so that SendMessageById can
+// never emit a status frame; status is exchanged only during the handshake.
+func TestFromProtoOmitsStatus(t *testing.T) {
+ omitted := make(map[uint]map[sentryproto.MessageId]struct{})
+ for version, toProto := range goldenToProto {
+ omitted[version] = make(map[sentryproto.MessageId]struct{})
+ for _, id := range toProto {
+ if _, ok := goldenFromProto[version][id]; !ok {
+ omitted[version][id] = struct{}{}
+ }
+ }
+ }
+
+ statusOnly := map[sentryproto.MessageId]struct{}{sentryproto.MessageId_STATUS_69: {}}
+ require.Equal(t, map[uint]map[sentryproto.MessageId]struct{}{
+ 68: {},
+ 69: statusOnly,
+ 70: statusOnly,
+ 71: statusOnly,
+ }, omitted)
+
+ for _, version := range []uint{69, 70, 71} {
+ require.NotContains(t, eth.FromProto[version], sentryproto.MessageId_STATUS_69)
+ }
+}
diff --git a/p2p/protocols/eth/protocol_test.go b/p2p/protocols/eth/protocol_test.go
index 9d462fa3512..3724b5c718f 100644
--- a/p2p/protocols/eth/protocol_test.go
+++ b/p2p/protocols/eth/protocol_test.go
@@ -28,7 +28,6 @@ import (
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/execution/rlp"
"github.com/erigontech/erigon/execution/types"
- "github.com/erigontech/erigon/node/direct"
"github.com/erigontech/erigon/node/gointerfaces/sentryproto"
)
@@ -330,14 +329,14 @@ func TestBlockAccessListsPacket66RoundTrip(t *testing.T) {
// the protocol name/length tables and that the two new message codes route to
// their sentry MessageId counterparts via ToProto/FromProto.
func TestEth71ProtocolRegistration(t *testing.T) {
- if name, ok := ProtocolToString[direct.ETH71]; !ok || name != "eth71" {
+ if name, ok := ProtocolToString[ETH71]; !ok || name != "eth71" {
t.Fatalf("ProtocolToString[ETH71] = (%q, %v), want (eth71, true)", name, ok)
}
- if length, ok := ProtocolLengths[direct.ETH71]; !ok || length != 20 {
+ if length, ok := ProtocolLengths[ETH71]; !ok || length != 20 {
t.Fatalf("ProtocolLengths[ETH71] = (%d, %v), want (20, true)", length, ok)
}
- fwd := ToProto[direct.ETH71]
+ fwd := ToProto[ETH71]
if fwd == nil {
t.Fatal("ToProto has no ETH71 entry")
}
@@ -348,7 +347,7 @@ func TestEth71ProtocolRegistration(t *testing.T) {
t.Errorf("ToProto[ETH71][BlockAccessListsMsg] = %v, want BLOCK_ACCESS_LISTS_71", got)
}
- rev := FromProto[direct.ETH71]
+ rev := FromProto[ETH71]
if rev == nil {
t.Fatal("FromProto has no ETH71 entry")
}
diff --git a/p2p/protocols/wit/protocol.go b/p2p/protocols/wit/protocol.go
index aa2e8745382..a59f6c0e91b 100644
--- a/p2p/protocols/wit/protocol.go
+++ b/p2p/protocols/wit/protocol.go
@@ -2,15 +2,15 @@ package wit
import (
"errors"
+ "fmt"
"github.com/erigontech/erigon/common"
"github.com/erigontech/erigon/execution/types/stateless"
- "github.com/erigontech/erigon/node/direct"
"github.com/erigontech/erigon/node/gointerfaces/sentryproto"
)
var ProtocolToString = map[uint]string{
- direct.WIT0: "wit0",
+ WIT1: "wit0",
}
// Constants to match up protocol versions and messages
@@ -128,7 +128,7 @@ func (w *NewWitnessHashesPacket) Name() string { return "NewWitnessHashes" }
func (w *NewWitnessHashesPacket) Kind() byte { return NewWitnessHashesMsg }
var ToProto = map[uint]map[uint64]sentryproto.MessageId{
- direct.WIT0: {
+ WIT1: {
NewWitnessMsg: sentryproto.MessageId_NEW_WITNESS_W0,
NewWitnessHashesMsg: sentryproto.MessageId_NEW_WITNESS_HASHES_W0,
GetWitnessMsg: sentryproto.MessageId_GET_BLOCK_WITNESS_W0,
@@ -136,11 +136,19 @@ var ToProto = map[uint]map[uint64]sentryproto.MessageId{
},
}
-var FromProto = map[uint]map[sentryproto.MessageId]uint64{
- direct.WIT0: {
- sentryproto.MessageId_NEW_WITNESS_W0: NewWitnessMsg,
- sentryproto.MessageId_NEW_WITNESS_HASHES_W0: NewWitnessHashesMsg,
- sentryproto.MessageId_GET_BLOCK_WITNESS_W0: GetWitnessMsg,
- sentryproto.MessageId_BLOCK_WITNESS_W0: WitnessMsg,
- },
+var FromProto = inverse(ToProto)
+
+func inverse(toProto map[uint]map[uint64]sentryproto.MessageId) map[uint]map[sentryproto.MessageId]uint64 {
+ fromProto := make(map[uint]map[sentryproto.MessageId]uint64, len(toProto))
+ for version, codes := range toProto {
+ inv := make(map[sentryproto.MessageId]uint64, len(codes))
+ for code, id := range codes {
+ if _, ok := inv[id]; ok {
+ panic(fmt.Sprintf("wit/%d: message id %s mapped from multiple message codes", version, id))
+ }
+ inv[id] = code
+ }
+ fromProto[version] = inv
+ }
+ return fromProto
}
diff --git a/p2p/protocols/wit/protocol_msgid_golden_test.go b/p2p/protocols/wit/protocol_msgid_golden_test.go
new file mode 100644
index 00000000000..ccd3e5b035e
--- /dev/null
+++ b/p2p/protocols/wit/protocol_msgid_golden_test.go
@@ -0,0 +1,36 @@
+package wit_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/erigontech/erigon/node/gointerfaces/sentryproto"
+ "github.com/erigontech/erigon/p2p/protocols/wit"
+)
+
+var goldenToProto = map[uint]map[uint64]sentryproto.MessageId{
+ 1: {
+ wit.NewWitnessMsg: sentryproto.MessageId_NEW_WITNESS_W0,
+ wit.NewWitnessHashesMsg: sentryproto.MessageId_NEW_WITNESS_HASHES_W0,
+ wit.GetWitnessMsg: sentryproto.MessageId_GET_BLOCK_WITNESS_W0,
+ wit.WitnessMsg: sentryproto.MessageId_BLOCK_WITNESS_W0,
+ },
+}
+
+var goldenFromProto = map[uint]map[sentryproto.MessageId]uint64{
+ 1: {
+ sentryproto.MessageId_NEW_WITNESS_W0: wit.NewWitnessMsg,
+ sentryproto.MessageId_NEW_WITNESS_HASHES_W0: wit.NewWitnessHashesMsg,
+ sentryproto.MessageId_GET_BLOCK_WITNESS_W0: wit.GetWitnessMsg,
+ sentryproto.MessageId_BLOCK_WITNESS_W0: wit.WitnessMsg,
+ },
+}
+
+func TestToProtoGolden(t *testing.T) {
+ require.Equal(t, goldenToProto, wit.ToProto)
+}
+
+func TestFromProtoGolden(t *testing.T) {
+ require.Equal(t, goldenFromProto, wit.FromProto)
+}
diff --git a/p2p/sentry/libsentry/protocol.go b/p2p/sentry/libsentry/protocol.go
index ef603b6565b..854f6a4af44 100644
--- a/p2p/sentry/libsentry/protocol.go
+++ b/p2p/sentry/libsentry/protocol.go
@@ -17,17 +17,53 @@
package libsentry
import (
+ "fmt"
+ "maps"
+ "slices"
+
"github.com/erigontech/erigon/node/gointerfaces/sentryproto"
+ "github.com/erigontech/erigon/p2p/protocols/eth"
+ "github.com/erigontech/erigon/p2p/protocols/wit"
+)
+
+var (
+ UintToProtocolMap = map[uint]sentryproto.Protocol{
+ eth.ETH68: sentryproto.Protocol_ETH68,
+ eth.ETH69: sentryproto.Protocol_ETH69,
+ eth.ETH70: sentryproto.Protocol_ETH70,
+ eth.ETH71: sentryproto.Protocol_ETH71,
+ }
+ ProtocolToUintMap = inverseProtocolMap(UintToProtocolMap)
+
+ UintToSideProtocolMap = map[uint]sentryproto.Protocol{
+ wit.WIT1: sentryproto.Protocol_WIT0,
+ }
+ SupportedSideProtocols = map[sentryproto.Protocol]struct{}{
+ sentryproto.Protocol_WIT0: {},
+ }
)
+func inverseProtocolMap(uintToProtocol map[uint]sentryproto.Protocol) map[sentryproto.Protocol]uint {
+ inv := make(map[sentryproto.Protocol]uint, len(uintToProtocol))
+ for version, protocol := range uintToProtocol {
+ if _, ok := inv[protocol]; ok {
+ panic(fmt.Sprintf("protocol %s mapped from multiple versions", protocol))
+ }
+ inv[protocol] = version
+ }
+ return inv
+}
+
// ethProtocolsByVersion lists ETH protocols in ascending version order.
// Used by MinProtocol to find the lowest version supporting a message.
-var ethProtocolsByVersion = []sentryproto.Protocol{
- sentryproto.Protocol_ETH68,
- sentryproto.Protocol_ETH69,
- sentryproto.Protocol_ETH70,
- sentryproto.Protocol_ETH71,
-}
+var ethProtocolsByVersion = func() []sentryproto.Protocol {
+ versions := slices.Sorted(maps.Keys(UintToProtocolMap))
+ protocols := make([]sentryproto.Protocol, len(versions))
+ for i, version := range versions {
+ protocols[i] = UintToProtocolMap[version]
+ }
+ return protocols
+}()
func MinProtocol(m sentryproto.MessageId) sentryproto.Protocol {
for _, p := range ethProtocolsByVersion {
@@ -41,73 +77,29 @@ func MinProtocol(m sentryproto.MessageId) sentryproto.Protocol {
return -1
}
-var ProtoIds = map[sentryproto.Protocol]map[sentryproto.MessageId]struct{}{
- sentryproto.Protocol_ETH68: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_GET_RECEIPTS_66: struct{}{},
- sentryproto.MessageId_RECEIPTS_66: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
- sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
- },
- sentryproto.Protocol_WIT0: {
- sentryproto.MessageId_GET_BLOCK_WITNESS_W0: struct{}{},
- sentryproto.MessageId_BLOCK_WITNESS_W0: struct{}{},
- sentryproto.MessageId_NEW_WITNESS_W0: struct{}{},
- sentryproto.MessageId_NEW_WITNESS_HASHES_W0: struct{}{},
- },
- sentryproto.Protocol_ETH69: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_GET_RECEIPTS_69: struct{}{},
- sentryproto.MessageId_RECEIPTS_66: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
- sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: struct{}{},
- },
- sentryproto.Protocol_ETH70: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_GET_RECEIPTS_70: struct{}{},
- sentryproto.MessageId_RECEIPTS_70: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
- sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: struct{}{},
- },
- sentryproto.Protocol_ETH71: {
- sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
- sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
- sentryproto.MessageId_GET_RECEIPTS_70: struct{}{},
- sentryproto.MessageId_RECEIPTS_70: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
- sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
- sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
- sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
- sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: struct{}{},
- // Added in eth/71 (EIP-8159 Block Access List Exchange)
- sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71: struct{}{},
- sentryproto.MessageId_BLOCK_ACCESS_LISTS_71: struct{}{},
- },
+var ProtoIds = func() map[sentryproto.Protocol]map[sentryproto.MessageId]struct{} {
+ ids := make(map[sentryproto.Protocol]map[sentryproto.MessageId]struct{}, len(eth.FromProto)+len(wit.FromProto))
+ for version, fromProto := range eth.FromProto {
+ ids[protocolOf(UintToProtocolMap, version)] = messageIdSet(fromProto)
+ }
+ for version, fromProto := range wit.FromProto {
+ ids[protocolOf(UintToSideProtocolMap, version)] = messageIdSet(fromProto)
+ }
+ return ids
+}()
+
+func protocolOf(uintToProtocol map[uint]sentryproto.Protocol, version uint) sentryproto.Protocol {
+ protocol, ok := uintToProtocol[version]
+ if !ok {
+ panic(fmt.Sprintf("no sentry protocol registered for version %d", version))
+ }
+ return protocol
+}
+
+func messageIdSet(fromProto map[sentryproto.MessageId]uint64) map[sentryproto.MessageId]struct{} {
+ set := make(map[sentryproto.MessageId]struct{}, len(fromProto))
+ for id := range fromProto {
+ set[id] = struct{}{}
+ }
+ return set
}
diff --git a/p2p/sentry/libsentry/protocol_msgid_golden_test.go b/p2p/sentry/libsentry/protocol_msgid_golden_test.go
new file mode 100644
index 00000000000..db6e1329bc4
--- /dev/null
+++ b/p2p/sentry/libsentry/protocol_msgid_golden_test.go
@@ -0,0 +1,100 @@
+// Copyright 2026 The Erigon Authors
+// This file is part of Erigon.
+//
+// Erigon is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Erigon is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with Erigon. If not, see .
+
+package libsentry_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/erigontech/erigon/node/gointerfaces/sentryproto"
+ "github.com/erigontech/erigon/p2p/sentry/libsentry"
+)
+
+var goldenProtoIds = map[sentryproto.Protocol]map[sentryproto.MessageId]struct{}{
+ sentryproto.Protocol_ETH68: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_GET_RECEIPTS_66: struct{}{},
+ sentryproto.MessageId_RECEIPTS_66: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
+ sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
+ },
+ sentryproto.Protocol_WIT0: {
+ sentryproto.MessageId_GET_BLOCK_WITNESS_W0: struct{}{},
+ sentryproto.MessageId_BLOCK_WITNESS_W0: struct{}{},
+ sentryproto.MessageId_NEW_WITNESS_W0: struct{}{},
+ sentryproto.MessageId_NEW_WITNESS_HASHES_W0: struct{}{},
+ },
+ sentryproto.Protocol_ETH69: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_GET_RECEIPTS_69: struct{}{},
+ sentryproto.MessageId_RECEIPTS_66: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
+ sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: struct{}{},
+ },
+ sentryproto.Protocol_ETH70: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_GET_RECEIPTS_70: struct{}{},
+ sentryproto.MessageId_RECEIPTS_70: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
+ sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: struct{}{},
+ },
+ sentryproto.Protocol_ETH71: {
+ sentryproto.MessageId_GET_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_HEADERS_66: struct{}{},
+ sentryproto.MessageId_GET_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_BLOCK_BODIES_66: struct{}{},
+ sentryproto.MessageId_GET_RECEIPTS_70: struct{}{},
+ sentryproto.MessageId_RECEIPTS_70: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_HASHES_66: struct{}{},
+ sentryproto.MessageId_NEW_BLOCK_66: struct{}{},
+ sentryproto.MessageId_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_NEW_POOLED_TRANSACTION_HASHES_68: struct{}{},
+ sentryproto.MessageId_GET_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_POOLED_TRANSACTIONS_66: struct{}{},
+ sentryproto.MessageId_BLOCK_RANGE_UPDATE_69: struct{}{},
+ sentryproto.MessageId_GET_BLOCK_ACCESS_LISTS_71: struct{}{},
+ sentryproto.MessageId_BLOCK_ACCESS_LISTS_71: struct{}{},
+ },
+}
+
+func TestProtoIdsGolden(t *testing.T) {
+ require.Equal(t, goldenProtoIds, libsentry.ProtoIds)
+}