diff --git a/p2p/pipes/pipe.go b/p2p/pipes/pipe.go new file mode 100644 index 0000000000..cf1f3e2a80 --- /dev/null +++ b/p2p/pipes/pipe.go @@ -0,0 +1,47 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library 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. +// +// The go-ethereum library 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 the go-ethereum library. If not, see . + +package pipes + +import "net" + +// TCPPipe creates an in process full duplex pipe based on a localhost TCP socket. +func TCPPipe() (net.Conn, net.Conn, error) { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return nil, nil, err + } + defer l.Close() + + var aconn net.Conn + aerr := make(chan error, 1) + go func() { + var err error + aconn, err = l.Accept() + aerr <- err + }() + + dconn, err := net.Dial("tcp", l.Addr().String()) + if err != nil { + <-aerr + return nil, nil, err + } + if err := <-aerr; err != nil { + dconn.Close() + return nil, nil, err + } + return aconn, dconn, nil +} diff --git a/p2p/rlpx/rlpx_test.go b/p2p/rlpx/rlpx_test.go index 59c3321a68..27d51546e7 100644 --- a/p2p/rlpx/rlpx_test.go +++ b/p2p/rlpx/rlpx_test.go @@ -31,6 +31,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/ecies" + "github.com/ethereum/go-ethereum/p2p/pipes" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/assert" ) @@ -382,8 +383,12 @@ func BenchmarkHandshakeRead(b *testing.B) { } func BenchmarkThroughput(b *testing.B) { + pipe1, pipe2, err := pipes.TCPPipe() + if err != nil { + b.Fatal(err) + } + var ( - pipe1, pipe2 = net.Pipe() conn1, conn2 = NewConn(pipe1, nil), NewConn(pipe2, &keyA.PublicKey) handshakeDone = make(chan error, 1) msgdata = make([]byte, 1024) diff --git a/p2p/transport_test.go b/p2p/transport_test.go index 0361b6b99d..01695cd3af 100644 --- a/p2p/transport_test.go +++ b/p2p/transport_test.go @@ -18,13 +18,13 @@ package p2p import ( "errors" - "net" "reflect" "sync" "testing" "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p/pipes" ) func TestProtocolHandshake(t *testing.T) { @@ -37,11 +37,14 @@ func TestProtocolHandshake(t *testing.T) { pub1 = crypto.FromECDSAPub(&prv1.PublicKey)[1:] hs1 = &protoHandshake{Version: 3, ID: pub1, Caps: []Cap{{"c", 1}, {"d", 3}}} - fd0, fd1 = net.Pipe() - wg sync.WaitGroup ) + fd0, fd1, err := pipes.TCPPipe() + if err != nil { + t.Fatal(err) + } + wg.Add(2) go func() { defer wg.Done()