Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions cmd/derod/rpc/nbio_websocket_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package rpc

import (
"crypto/tls"
"net"
"net/http"
"sync/atomic"
"testing"
"time"

gws "github.com/gorilla/websocket"
ltls "github.com/lesismal/llib/std/crypto/tls"
"github.com/lesismal/nbio/nbhttp"
"github.com/lesismal/nbio/nbhttp/websocket"
)

// TestNbioWebsocketRoundTrip validates that the bumped nbio (v1.6.11) websocket
// server still upgrades HTTP connections, delivers messages, and fires the
// connection-close callback. This exercises the exact library the getwork
// mining server relies on (websocket_getwork_server.go), which the simulator
// integration suite does not cover.
func TestNbioWebsocketRoundTrip(t *testing.T) {
// Reserve an ephemeral port.
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("listen: %v", err)
}
addr := l.Addr().String()
l.Close()

// Self-signed cert (same generator the production getwork server uses,
// backed by llib's crypto/tls which nbio v1.6.11 requires).
tlsCert := generate_random_tls_cert()
tlsConfig := &ltls.Config{Certificates: []ltls.Certificate{tlsCert}}

upgrader := websocket.NewUpgrader()
var closed int32
upgrader.OnMessage(func(c *websocket.Conn, messageType websocket.MessageType, data []byte) {
// Echo the payload back to the client.
_ = c.WriteMessage(messageType, data)
})
upgrader.OnClose(func(c *websocket.Conn, err error) {
atomic.AddInt32(&closed, 1)
})

mux := &http.ServeMux{}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if _, err := upgrader.Upgrade(w, r, nil); err != nil {
t.Errorf("upgrade failed: %v", err)
}
})

svr := nbhttp.NewServer(nbhttp.Config{
Name: "TEST",
Network: "tcp",
AddrsTLS: []string{addr},
TLSConfig: tlsConfig,
Handler: mux,
NPoller: 1,
})
if err := svr.Start(); err != nil {
t.Fatalf("server start failed: %v", err)
}
defer svr.Stop()

// Allow the listener to come up.
time.Sleep(200 * time.Millisecond)

dialer := gws.Dialer{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
c, _, err := dialer.Dial("wss://"+addr+"/", nil)
if err != nil {
t.Fatalf("dial failed: %v", err)
}
defer c.Close()

// Send a frame and expect it echoed back.
msg := []byte("hello-nbio-v1.6.11")
if err := c.WriteMessage(gws.TextMessage, msg); err != nil {
t.Fatalf("write failed: %v", err)
}
c.SetReadDeadline(time.Now().Add(2 * time.Second))
mt, got, err := c.ReadMessage()
if err != nil {
t.Fatalf("read failed: %v", err)
}
if mt != gws.TextMessage {
t.Fatalf("message type = %d, want TextMessage", mt)
}
if string(got) != string(msg) {
t.Fatalf("echo = %q, want %q", got, msg)
}

// Closing the client must trigger the server-side OnClose callback.
c.Close()
time.Sleep(200 * time.Millisecond)
if atomic.LoadInt32(&closed) == 0 {
t.Fatalf("expected OnClose to fire after client disconnect")
}
}
11 changes: 6 additions & 5 deletions cmd/derod/rpc/websocket_getwork_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ func onWebsocket(w http.ResponseWriter, r *http.Request) {
//panic(err)
return
}
wsConn := conn.(*websocket.Conn)
wsConn := conn

session := user_session{address: *addr, address_sum: graviton.Sum(addr_raw)}
wsConn.SetSession(&session)
Expand Down Expand Up @@ -350,11 +350,12 @@ func Getwork_server() {
NPoller: runtime.NumCPU(),
})

svr.OnReadBufferAlloc(func(c *nbio.Conn) []byte {
return memPool.Get().([]byte)
svr.OnReadBufferAlloc(func(c *nbio.Conn) *[]byte {
b := memPool.Get().([]byte)
return &b
})
svr.OnReadBufferFree(func(c *nbio.Conn, b []byte) {
memPool.Put(b)
svr.OnReadBufferFree(func(c *nbio.Conn, b *[]byte) {
memPool.Put(*b)
})

//globals.Cron.AddFunc("@every 2s", SendJob) // if daemon restart automaticaly send job
Expand Down
90 changes: 90 additions & 0 deletions tests/normal/nbio_getwork_test/run_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env bash
#
# Integration test for the nbio getwork (mining) websocket server.
#
# This exercises the REAL daemon getwork path (cmd/derod/rpc/websocket_getwork_server.go,
# which is built on nbio) end-to-end with a real miner client (cmd/dero-miner, which uses
# gorilla/websocket). The simulator used by run_integration_test.sh does NOT start the
# getwork server, so this standalone test is the only one that covers the bumped nbio
# code path in production conditions.
#
# When run under run_integration_test.sh, this test starts its OWN derod
# (the harness simulator does not start the getwork server) and uses dedicated,
# non-default ports so it never collides with the harness simulator (20000/8080)
# or the persistent dev daemon (10100/10102).
#
# Usage: bash tests/normal/nbio_getwork_test/run_test.sh

set -u

ABSDIR=$(cd "$(dirname "$0")" && pwd)
REPO_ROOT=$(cd "$ABSDIR/../../.." && pwd)
cd "$REPO_ROOT"

export GOPROXY=https://proxy.golang.org,direct
export GOSUMDB=sum.golang.org
export PATH="$HOME/go/bin:$PATH"

ADDRESS="deto1qy0ehnqjpr0wxqnknyc66du2fsxyktppkr8m8e6jvplp954klfjz2qqdzcd8p"
GETWORK_PORT=18092
DATADIR=/tmp/nbio_getwork_test
DEROD_LOG=/tmp/nbio_getwork_derod.log
MINER_LOG=/tmp/nbio_getwork_miner.log

cleanup() {
pkill -f "/tmp/nbio_derod" 2>/dev/null
pkill -f "/tmp/nbio_miner" 2>/dev/null
rm -rf "$DATADIR" "$DEROD_LOG" "$MINER_LOG"
}
trap cleanup EXIT

echo "==> Building derod + dero-miner"
go build -o /tmp/nbio_derod ./cmd/derod || { echo "FAIL: derod build"; exit 1; }
go build -o /tmp/nbio_miner ./cmd/dero-miner || { echo "FAIL: dero-miner build"; exit 1; }

echo "==> Starting derod --testnet (getwork on 127.0.0.1:$GETWORK_PORT, rpc 18093, p2p disabled)"
rm -rf "$DATADIR"
mkdir -p "$DATADIR"
/tmp/nbio_derod --testnet --data-dir="$DATADIR" --rpc-bind="127.0.0.1:18093" --p2p-bind=":0" --getwork-bind="127.0.0.1:$GETWORK_PORT" --clog-level=2 >"$DEROD_LOG" 2>&1 &
disown

echo "==> Waiting for getwork server to start"
started=0
for i in $(seq 1 60); do
if grep -q "GETWORK/Websocket server started" "$DEROD_LOG" 2>/dev/null; then
started=1
break
fi
sleep 1
done
if [ "$started" -ne 1 ]; then
echo "FAIL: getwork server did not start"
tail -30 "$DEROD_LOG"
exit 1
fi
echo " getwork server started"

echo "==> Starting dero-miner (gorilla/websocket client -> nbio server)"
/tmp/nbio_miner --testnet --daemon-rpc-address="127.0.0.1:$GETWORK_PORT" --wallet-address="$ADDRESS" >"$MINER_LOG" 2>&1 &
disown

echo "==> Waiting for miner to connect and receive a job"
sleep 12

if ! grep -q "wss://127.0.0.1:$GETWORK_PORT" "$MINER_LOG"; then
echo "FAIL: miner did not attempt to connect"
cat "$MINER_LOG"
exit 1
fi

if grep -q "Error connecting to server" "$MINER_LOG"; then
echo "FAIL: miner failed to connect to the bumped nbio getwork server"
echo "---- miner log ----"
cat "$MINER_LOG"
echo "---- derod log (tail) ----"
tail -20 "$DEROD_LOG"
exit 1
fi

echo "PASS: miner connected to the bumped nbio getwork server and received work"
exit 0
11 changes: 9 additions & 2 deletions vendor/github.com/lesismal/llib/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading