Skip to content

Commit

Permalink
feat: geth bootnode binary (#1)
Browse files Browse the repository at this point in the history
* feat: add dockerfile for bootnode build

* test: remove pong bond verify

* feat: add static peers on bootnode
krish-nr committed Jan 22, 2024
1 parent c3f1db4 commit 8a8939b
Showing 13 changed files with 410 additions and 20 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/docker-release.yml
Original file line number Diff line number Diff line change
@@ -43,3 +43,36 @@ jobs:
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

push-op-geth-bootnode:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: image meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/op-geth-bootnode
tags: |
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{version}}
type=sha
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./cmd/bootnode/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
36 changes: 36 additions & 0 deletions cmd/bootnode/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Support setting various labels on the final image
ARG COMMIT=""
ARG VERSION=""
ARG BUILDNUM=""

# Build Geth in a stock Go builder container
FROM golang:1.20-alpine as builder

RUN apk add --no-cache build-base libc-dev
RUN apk add --no-cache gcc musl-dev linux-headers git

# Get dependencies - will also be cached if we won't change go.mod/go.sum
COPY go.mod /go-ethereum/
COPY go.sum /go-ethereum/
RUN cd /go-ethereum && go mod download

ADD . /go-ethereum
ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__"
ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__"
RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/bootnode

# Pull Geth into a second stage deploy alpine container
FROM alpine:latest

RUN apk add --no-cache ca-certificates
COPY --from=builder /go-ethereum/build/bin/bootnode /usr/local/bin/

EXPOSE 8545 8546 30303 30303/udp
ENTRYPOINT ["bootnode"]

# Add some metadata labels to help programatic image consumption
ARG COMMIT=""
ARG VERSION=""
ARG BUILDNUM=""

LABEL commit="$COMMIT" version="$VERSION" buildnum="$BUILDNUM"
38 changes: 38 additions & 0 deletions cmd/bootnode/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This Makefile is meant to be used by people that do not usually work
# with Go source code. If you know what GOPATH is then you probably
# don't need to bother with make.

.PHONY: geth android ios evm all test clean

GOBIN = ./build/bin
GO ?= latest
GORUN = env GO111MODULE=on go run

geth:
$(GORUN) build/ci.go install ./cmd/geth
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."

all:
$(GORUN) build/ci.go install

test: all
$(GORUN) build/ci.go test

lint: ## Run linters.
$(GORUN) build/ci.go lint

clean:
env GO111MODULE=on go clean -cache
rm -fr build/_workspace/pkg/ $(GOBIN)/*

# The devtools target installs tools required for 'go generate'.
# You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'.

devtools:
env GOBIN= go install golang.org/x/tools/cmd/stringer@latest
env GOBIN= go install github.com/fjl/gencodec@latest
env GOBIN= go install github.com/golang/protobuf/protoc-gen-go@latest
env GOBIN= go install ./cmd/abigen
@type "solc" 2> /dev/null || echo 'Please install solc'
@type "protoc" 2> /dev/null || echo 'Please install protoc'
16 changes: 14 additions & 2 deletions cmd/bootnode/main.go
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/discover/v4wire"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/p2p/netutil"
@@ -45,10 +46,14 @@ func main() {
runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode")
verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-5)")
vmodule = flag.String("vmodule", "", "log verbosity pattern")
network = flag.String("network", "", "testnet/mainnet")

nodeKey *ecdsa.PrivateKey
err error
)

var staticV4Nodes []v4wire.Node

flag.Parse()

glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
@@ -86,6 +91,12 @@ func main() {
}
}

if *network == "testnet" {
staticV4Nodes = staticV4NodesTestnet
} else {
staticV4Nodes = staticV4NodesMainnet
}

if *writeAddr {
fmt.Printf("%x\n", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:])
os.Exit(0)
@@ -123,8 +134,9 @@ func main() {
db, _ := enode.OpenDB("")
ln := enode.NewLocalNode(db, nodeKey)
cfg := discover.Config{
PrivateKey: nodeKey,
NetRestrict: restrictList,
PrivateKey: nodeKey,
NetRestrict: restrictList,
StaticV4Nodes: staticV4Nodes,
}
if *runv5 {
if _, err := discover.ListenV5(conn, ln, cfg); err != nil {
110 changes: 110 additions & 0 deletions cmd/bootnode/static_nodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"encoding/hex"
"net"

"github.com/ethereum/go-ethereum/p2p/discover/v4wire"
)

var staticV4NodesTestnet = []v4wire.Node{
//p2p-0

{
IP: net.ParseIP("18.177.245.157").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("223488870e492f49873b621c21f3e1302f00993aaa5214a077a1c4eb62dfe96675cc7a3360525c3409480d1ec13cc72f432b4d50f5e70f98e60385dc25d4be6b"),
},

//p2p-1
{
IP: net.ParseIP("18.176.219.164").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("f6a082e7861762da7e5d65ebf92b06e72b9fde81787a1a71ec8ab407345f3a7787e2617c5b9565ea3a1be46f794eeb791aef3059818b23588f2352b1d7973dfd"),
},
}

var staticV4NodesMainnet = []v4wire.Node{
//ap-p2p-0

{
IP: net.ParseIP("52.193.218.151").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("db109c6cac5c8b6225edd3176fc3764c58e0720950fe94c122c80978e706a9c9e976629b718e48b6306ea0f9126e5394d3424c9716c5703549e2e7eba216353b"),
},

//ap-p2p-1
{
IP: net.ParseIP("52.195.105.192").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("afe18782053bb31fb7ea41e1acf659ab9bd1eec181fb97331f0a6b61871a469b4f75138f903c977796be1cc2a3c985d33150a396e878d3cd6e4723b6040ff9c0"),
},
//ap-p2p-2
{
IP: net.ParseIP("18.182.161.116").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("0cbbf05d39193127e373038f41cdfb520644453dc764bac49f8403b774f2aab7e679b72ac1ee692f19f55cf07cdf07ef99195c841cbe30d263955149de9213cb"),
},
//us-p2p-2
{
IP: net.ParseIP("34.205.6.198").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("ad16edbb25953c36026636427d637fd874f65d1895a589c987009cb820a675cb0f0e1a1dffe34b826a8ef4cc9a0da398cc921ce612de7e6167dd3fdf3db9a1d9"),
},
//us-p2p-1
{
IP: net.ParseIP("34.194.74.36").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("852a9d69b385ccf858227ab741d73821704b7fc4abf6510840e8769a44c0d360d269a6ff6b0c42d7335e1caa494a16e45e24ad8aaa9830509f1d8ff49ebb1288"),
},
//us-p2p-0
{
IP: net.ParseIP("54.211.157.22").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("23538322b4fa60a936395012b37d5b4407717eec54c64232bd4e985b24ad941c3e4dd36d634e053286d926ceed66c725f8f2a72003f59901b963dee9d9983080"),
},
//eu-p2p-0
{
IP: net.ParseIP("34.246.100.156").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("752038ca7a0359e967d5096453935a5c3d5a13864c3551bd60c5d7d8e6547b2d68b1ceb484d872116ac6977b78d1d39fab8ebd92d22e68b032ffc196fa6cecd7"),
},
//eu-p2p-1
{
IP: net.ParseIP("99.81.30.183").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("6c24f4531d755d647ee3d8082f7945f051032c7bc1fc6c90ae6c328092efa2cf1ce429db01e7c4efe26f198eecf996979c2958745ac1f4d831f88231abd0096e"),
},
//eu-p2p-2
{
IP: net.ParseIP("34.243.159.16").To4(),
UDP: 30303,
TCP: 30303,
ID: decodePubkeyV4("f39da1c3b027b5683387c724363e0e132c287a6094564a05b43e8f22508e973098b3c7234df09beabcc19827f1d8998bd1e1d960fb5949bac0317bbe7fcb20a4"),
},
}

// decodePubkeyV4
func decodePubkeyV4(hexPubkey string) v4wire.Pubkey {
pubkeyBytes, err := hex.DecodeString(hexPubkey)
if err != nil {
return v4wire.Pubkey{}
}
if len(pubkeyBytes) != 64 {
return v4wire.Pubkey{}
}

var pubkey v4wire.Pubkey
copy(pubkey[:], pubkeyBytes)
return pubkey
}
4 changes: 0 additions & 4 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
@@ -27,7 +27,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
@@ -179,10 +178,8 @@ func (s *stateObject) getOriginStorage(key common.Hash) (common.Hash, bool) {
}
// if L1 cache miss, try to get it from shared pool
if s.sharedOriginStorage != nil {
log.Info("debug: sharedOriginStorage enabled")
val, ok := s.sharedOriginStorage.Load(key)
if !ok {
log.Info("debug: get OriginStorage", "key", key, "value", val)
return common.Hash{}, false
}
s.originStorage[key] = val.(common.Hash)
@@ -193,7 +190,6 @@ func (s *stateObject) getOriginStorage(key common.Hash) (common.Hash, bool) {

func (s *stateObject) setOriginStorage(key common.Hash, value common.Hash) {
if s.db.writeOnSharedStorage && s.sharedOriginStorage != nil {
log.Info("debug: set OriginStorage", "key", key, "value", value)
s.sharedOriginStorage.Store(key, value)
}
s.originStorage[key] = value
1 change: 0 additions & 1 deletion core/state/statedb.go
Original file line number Diff line number Diff line change
@@ -169,7 +169,6 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)

// NewWithSharedPool creates a new state with sharedStorge on layer 1.5
func NewWithSharedPool(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) {
log.Info("debug: NewWithSharedPool called")
statedb, err := New(root, db, snaps)
if err != nil {
return nil, err
4 changes: 4 additions & 0 deletions p2p/discover/common.go
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ import (

"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/discover/v4wire"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethereum/go-ethereum/p2p/netutil"
@@ -55,6 +56,9 @@ type Config struct {

ValidSchemes enr.IdentityScheme // allowed identity schemes
Clock mclock.Clock

//static v4 nodes
StaticV4Nodes []v4wire.Node
}

func (cfg Config) withDefaults() Config {
63 changes: 63 additions & 0 deletions p2p/discover/table.go
Original file line number Diff line number Diff line change
@@ -411,10 +411,13 @@ func (tab *Table) findnodeByID(target enode.ID, nresults int, preferLive bool) *
liveNodes := &nodesByDistance{target: target}
for _, b := range &tab.buckets {
for _, n := range b.entries {
distance := xorDistance(target, n.ID())
nodes.push(n, nresults)
if preferLive && n.livenessChecks > 0 {
liveNodes.push(n, nresults)
}
log.Trace("Distance", "Node ID", n.ID(), "Target ID", target, "XOR Distance", distance)

}
}

@@ -424,6 +427,56 @@ func (tab *Table) findnodeByID(target enode.ID, nresults int, preferLive bool) *
return nodes
}

func xorDistance(a, b enode.ID) (distance enode.ID) {
for i := range a {
distance[i] = a[i] ^ b[i]
}
return distance
}

// get all nodes ids
func (tab *Table) getAllNodeIDs() []enode.ID {
tab.mutex.Lock()
defer tab.mutex.Unlock()

var ids []enode.ID
for _, b := range tab.buckets {
for _, n := range b.entries {
ids = append(ids, n.ID())
}
}
return ids
}

// get node by given id
func (tab *Table) getNodeByID(id enode.ID) enode.Node {
tab.mutex.Lock()
defer tab.mutex.Unlock()

for _, b := range tab.buckets {
for _, n := range b.entries {
if n.ID().String() == id.String() {
return n.Node
}
}
}
return enode.Node{}
}

// get all nodes ids
func (tab *Table) getAllNodes() []enode.Node {
tab.mutex.Lock()
defer tab.mutex.Unlock()

var nodes []enode.Node
for _, b := range tab.buckets {
for _, n := range b.entries {
nodes = append(nodes, n.Node)
}
}
return nodes
}

// len returns the number of nodes in the table.
func (tab *Table) len() (n int) {
tab.mutex.Lock()
@@ -501,12 +554,22 @@ func (tab *Table) addSeenNode(n *node) {
//
// The caller must not hold tab.mutex.
func (tab *Table) addVerifiedNode(n *node) {
log.Trace("addVerifiedNode", "nodeIP", n.IP().String(), "nodeId", n.ID().String())
if !tab.isInitDone() {
return
}
if n.ID() == tab.self().ID() {
return
}
nodes := tab.getAllNodes()

for i, nodeIndex := range nodes {
log.Trace("current tab content", "index", i, "nodeId", nodeIndex.ID(), "nodeIP", nodeIndex.IP().String())
for j, pair := range nodeIndex.Record().GetPairs() {
log.Trace("current node content", "node index", i, "pair index", j, "pairKey", pair.GetPairKey(), "pairValue", pair.GetPairValue())

}
}

tab.mutex.Lock()
defer tab.mutex.Unlock()
93 changes: 81 additions & 12 deletions p2p/discover/v4_udp.go
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"net"
"sync"
"time"
@@ -48,6 +49,24 @@ var (
errLowPort = errors.New("low port")
)

/*
// decodePubkeyV4
func decodePubkeyV4(hexPubkey string) (v4wire.Pubkey, error) {
pubkeyBytes, err := hex.DecodeString(hexPubkey)
if err != nil {
return v4wire.Pubkey{}, err
}
if len(pubkeyBytes) != 64 {
return v4wire.Pubkey{}, fmt.Errorf("public key is not 64 bytes long")
}
var pubkey v4wire.Pubkey
copy(pubkey[:], pubkeyBytes)
return pubkey, nil
}
*/

const (
respTimeout = 500 * time.Millisecond
expiration = 20 * time.Second
@@ -80,6 +99,9 @@ type UDPv4 struct {
gotreply chan reply
closeCtx context.Context
cancelCloseCtx context.CancelFunc

//static peers
staticNodes []v4wire.Node
}

// replyMatcher represents a pending reply.
@@ -141,6 +163,7 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
closeCtx: closeCtx,
cancelCloseCtx: cancel,
log: cfg.Log,
staticNodes: cfg.StaticV4Nodes,
}

tab, err := newTable(t, ln.Database(), cfg.Bootnodes, t.log)
@@ -209,6 +232,7 @@ func (t *UDPv4) ourEndpoint() v4wire.Endpoint {

// Ping sends a ping message to the given node.
func (t *UDPv4) Ping(n *enode.Node) error {
log.Info("send ping from ping-ping")
_, err := t.ping(n)
return err
}
@@ -224,8 +248,10 @@ func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {

// sendPing sends a ping message to the given node and invokes the callback
// when the reply arrives.
// 在这里发生的变化,只要给Bootndoe发过就会更替
func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher {
req := t.makePing(toaddr)
log.Trace("SendPing", "toID", toid, "fromIP", req.From.IP.String(), "fromPortTCP", req.From.TCP, "fromPortUDP", req.From.UDP)
packet, hash, err := v4wire.Encode(t.priv, req)
if err != nil {
errc := make(chan error, 1)
@@ -299,6 +325,7 @@ func (t *UDPv4) newLookup(ctx context.Context, targetKey encPubkey) *lookup {

// findnode sends a findnode request to the given node and waits until
// the node has sent up to k neighbors.
// 处理neighbors逻辑的地方
func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubkey) ([]*node, error) {
t.ensureBond(toid, toaddr)

@@ -497,6 +524,7 @@ func (t *UDPv4) loop() {
}
}

// 通用send? send
func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]byte, error) {
packet, hash, err := v4wire.Encode(t.priv, req)
if err != nil {
@@ -508,6 +536,11 @@ func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]b
func (t *UDPv4) write(toaddr *net.UDPAddr, toid enode.ID, what string, packet []byte) error {
_, err := t.conn.WriteToUDP(packet, toaddr)
t.log.Trace(">> "+what, "id", toid, "addr", toaddr, "err", err)
/*
if what == "FINDNODE/v4" {
log.Info("FINDNODE msg")
}
*/
return err
}

@@ -569,6 +602,7 @@ func (t *UDPv4) checkBond(id enode.ID, ip net.IP) bool {
func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) {
tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.IP)) > bondExpiration
if tooOld || t.db.FindFails(toid, toaddr.IP) > maxFindnodeFailures {
log.Trace("sendPing from ensureBond")
rm := t.sendPing(toid, toaddr, nil)
<-rm.errc
// Wait for them to ping back and process our pong.
@@ -665,10 +699,13 @@ func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
Expiration: uint64(time.Now().Add(expiration).Unix()),
ENRSeq: t.localNode.Node().Seq(),
})
log.Trace("handlePing,sendPong", "nodeId", fromID, "targetIP", from.IP.String(), "targetPort", from.Port)

// Ping back if our last pong on file is too far in the past.
// TODO
n := wrapNode(enode.NewV4(h.senderKey, from.IP, int(req.From.TCP), from.Port))
if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration {
log.Trace("sendPing from bondExpiration")
t.sendPing(fromID, from, func() {
t.tab.addVerifiedNode(n)
})
@@ -705,15 +742,20 @@ func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
if v4wire.Expired(req.Expiration) {
return errExpired
}
if !t.checkBond(fromID, from.IP) {
// No endpoint proof pong exists, we don't process the packet. This prevents an
// attack vector where the discovery protocol could be used to amplify traffic in a
// DDOS attack. A malicious actor would send a findnode request with the IP address
// and UDP port of the target as the source address. The recipient of the findnode
// packet would then send a neighbors packet (which is a much bigger packet than
// findnode) to the victim.
return errUnknownNode
}

/*
if !t.checkBond(fromID, from.IP) {
// No endpoint proof poudpng exists, we don't process the packet. This prevents an
// attack vector where the discovery protocol could be used to amplify traffic in a
// DDOS attack. A malicious actor would send a findnode request with the IP address
// and UDP port of the target as the source address. The recipient of the findnode
// packet would then send a neighbors packet (which is a much bigger packet than
// findnode) to the victim.
return errUnknownNode
}
*/

return nil
}

@@ -727,6 +769,13 @@ func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
// Send neighbors in chunks with at most maxNeighbors per packet
// to stay below the packet size limit.
p := v4wire.Neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())}

// Add static peers
for i, staticNode := range t.staticNodes {
log.Debug("static nodes", "index", i, "node ID", staticNode.ID.ID().String(), "IP", staticNode.IP.String())
p.Nodes = append(p.Nodes, staticNode)
}

var sent bool
for _, n := range closest {
if netutil.CheckRelayIP(from.IP, n.IP()) == nil {
@@ -743,10 +792,22 @@ func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
}
}

// shuffleNodes takes a slice of nodes and shuffles them in place.
func shuffleNodes(nodes []v4wire.Node) {
rand.Seed(time.Now().UnixNano()) // Ensure a different sequence each time
rand.Shuffle(len(nodes), func(i, j int) {
nodes[i], nodes[j] = nodes[j], nodes[i]
})
}

// NEIGHBORS/v4

func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
log.Debug("verifyNeighbors", "fromIp", from.IP.String(), "fromPort", from.Port)
req := h.Packet.(*v4wire.Neighbors)
for i, neighbor := range req.Nodes {
log.Debug("received neighbors", "index", i, "IP", neighbor.IP.String(), "UDP_PORT", neighbor.UDP, "TCP_PORT", neighbor.TCP, "NodeId", neighbor.ID.ID())
}

if v4wire.Expired(req.Expiration) {
return errExpired
@@ -765,13 +826,21 @@ func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID e
if v4wire.Expired(req.Expiration) {
return errExpired
}
if !t.checkBond(fromID, from.IP) {
return errUnknownNode
}
/*
if !t.checkBond(fromID, from.IP) {
return errUnknownNode
}
*/
return nil
}

func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
log.Info("handle ENR reqeust", "from", from, "fromID", fromID)
record := t.localNode.Node().Record()
for i, p := range record.GetPairs() {
log.Info("ENR pairs", "index", i, "key", p.GetPairKey(), "value", p.GetPairValue())
}
t.send(from, fromID, &v4wire.ENRResponse{
ReplyTok: mac,
Record: *t.localNode.Node().Record(),
18 changes: 18 additions & 0 deletions p2p/discover/v4_udp_test.go
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ import (
"crypto/ecdsa"
crand "crypto/rand"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"io"
@@ -664,3 +665,20 @@ func (c *dgramPipe) receive() (dgram, error) {
c.queue = c.queue[:len(c.queue)-1]
return p, nil
}

func TestPubkeyToID(t *testing.T) {
hexPubkey := "223488870e492f49873b621c21f3e1302f00993aaa5214a077a1c4eb62dfe96675cc7a3360525c3409480d1ec13cc72f432b4d50f5e70f98e60385dc25d4be6b"

pubkeyBytes, err := hex.DecodeString(hexPubkey)
if err != nil {
t.Fatalf("Error decoding public key: %v", err)
}

var pubkey v4wire.Pubkey
copy(pubkey[:], pubkeyBytes)

nodeID := pubkey.ID()

fmt.Printf("Node ID: %s\n", nodeID.String())

}
2 changes: 1 addition & 1 deletion p2p/discover/v4wire/v4wire.go
Original file line number Diff line number Diff line change
@@ -103,7 +103,7 @@ type (
)

// MaxNeighbors is the maximum number of neighbor nodes in a Neighbors packet.
const MaxNeighbors = 12
const MaxNeighbors = 20

// This code computes the MaxNeighbors constant value.

12 changes: 12 additions & 0 deletions p2p/enr/enr.go
Original file line number Diff line number Diff line change
@@ -90,12 +90,24 @@ type Record struct {
pairs []pair // sorted list of all key/value pairs
}

func (r *Record) GetPairs() []pair {
return r.pairs
}

// pair is a key/value pair in a record.
type pair struct {
k string
v rlp.RawValue
}

func (r *pair) GetPairKey() string {
return r.k
}

func (r *pair) GetPairValue() rlp.RawValue {
return r.v
}

// Size returns the encoded size of the record.
func (r *Record) Size() uint64 {
if r.raw != nil {

0 comments on commit 8a8939b

Please sign in to comment.