Skip to content
This repository was archived by the owner on Feb 25, 2023. It is now read-only.

Commit a523a5c

Browse files
committed
middleware: Electrum Tunnel Unit tests
This commit adapts the unit tests to the changes introduced in the previous commit for the electrum tunneling. The electrum client is now only spawned with the first electrum rpc call. The electrum client opens a new tcp connection to the electrum server for each connected client of the middleware.
1 parent ee42260 commit a523a5c

7 files changed

Lines changed: 45 additions & 46 deletions

File tree

middleware/src/electrum/electrum.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
// Package electrum reads messages from a connected electrum server over tcp and passes the read value to a callback function. It also sends messages to the electrum server over tcp
12
package electrum
23

34
import (
45
"bufio"
56
"fmt"
7+
"log"
68
"net"
7-
8-
"github.com/ethereum/go-ethereum/log"
99
)
1010

1111
// Electrum makes a connection to an Electrum server and proxies messages.
@@ -28,19 +28,20 @@ func NewElectrum(address string, onMessageReceived func([]byte)) (*Electrum, err
2828
return electrum, nil
2929
}
3030

31+
// read raw message from Electrum server
3132
func (electrum *Electrum) read() {
3233
reader := bufio.NewReader(electrum.connection)
3334
for {
3435
line, err := reader.ReadBytes(byte('\n'))
3536
if err != nil {
36-
log.Error(fmt.Sprintf("electrum read error: %v", err))
37+
log.Println(fmt.Sprintf("electrum read error: %v", err))
3738
break
3839
}
3940
electrum.onMessageReceived(line)
4041
}
4142
}
4243

43-
// Send sends a raw message to the Electrum server.
44+
// Send a raw message to the Electrum server.
4445
func (electrum *Electrum) Send(msg []byte) error {
4546
_, err := electrum.connection.Write(msg)
4647
return err

middleware/src/handlers/handlers.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"sync"
88

99
middleware "github.com/digitalbitbox/bitbox-base/middleware/src"
10-
"github.com/digitalbitbox/bitbox-base/middleware/src/electrum"
1110
noisemanager "github.com/digitalbitbox/bitbox-base/middleware/src/noise"
1211
"github.com/digitalbitbox/bitbox-base/middleware/src/rpcserver"
1312

@@ -112,28 +111,22 @@ func (handlers *Handlers) wsHandler(w http.ResponseWriter, r *http.Request) {
112111
onElectrumMessageReceived := func(msg []byte) {
113112
writeChan <- append([]byte{opElectrum}, msg...)
114113
}
115-
electrumClient, err := electrum.NewElectrum(handlers.electrumAddress, onElectrumMessageReceived)
116-
if err != nil {
117-
log.Println(err.Error() + "Electrum connection failed to initialize")
118-
return
119-
}
120114

121115
server := rpcserver.NewRPCServer(
122116
handlers.middleware,
123-
electrumClient,
117+
handlers.electrumAddress,
118+
onElectrumMessageReceived,
124119
)
125120
go func() {
126121
for {
127122
msg := <-server.RPCConnection.WriteChan()
128-
writeChan <- append([]byte{opRPC}, msg...)
123+
significantMsg := append([]byte{opRPC}, msg...)
124+
writeChan <- significantMsg
129125
}
130126
}()
131127
handlers.mu.Lock()
132-
handlers.clientsMap[handlers.nClients] = server.RPCConnection.WriteChan()
133-
onMessageReceived := func(msg []byte) {
134-
server.RPCConnection.ReadChan() <- msg
135-
}
136-
handlers.runWebsocket(ws, onMessageReceived, writeChan, handlers.nClients)
128+
handlers.clientsMap[handlers.nClients] = writeChan
129+
handlers.runWebsocket(ws, server.RPCConnection.ReadChan(), writeChan, handlers.nClients)
137130
handlers.nClients++
138131
handlers.mu.Unlock()
139132
go server.Serve()

middleware/src/handlers/handlers_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ func TestRootHandler(t *testing.T) {
4949
}
5050

5151
func TestWebsocketHandler(t *testing.T) {
52-
return
5352
argumentMap := make(map[string]string)
5453
argumentMap["bitcoinRPCUser"] = "user"
5554
argumentMap["bitcoinRPCPassword"] = "password"

middleware/src/handlers/websocket.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const (
1818
// The goroutines close client upon exit or dues to a send/receive error.
1919
func (handlers *Handlers) runWebsocket(
2020
client *websocket.Conn,
21-
onMessageReceived func([]byte),
21+
readChan chan<- []byte,
2222
writeChan <-chan []byte,
2323
clientID int) {
2424

@@ -63,7 +63,7 @@ func (handlers *Handlers) runWebsocket(
6363
return
6464
}
6565
log.Println(string(messageDecrypted))
66-
onMessageReceived(messageDecrypted)
66+
readChan <- messageDecrypted
6767
}
6868
}
6969

middleware/src/middleware.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@ const (
1818

1919
// Middleware connects to services on the base with provided parrameters and emits events for the handler.
2020
type Middleware struct {
21-
info SampleInfoResponse
22-
environment system.Environment
23-
events chan []byte
21+
info SampleInfoResponse
22+
environment system.Environment
23+
events chan []byte
24+
electrumEvents chan []byte
2425
}
2526

2627
// NewMiddleware returns a new instance of the middleware
2728
func NewMiddleware(argumentMap map[string]string) *Middleware {
2829
middleware := &Middleware{
2930
environment: system.NewEnvironment(argumentMap),
3031
//TODO(TheCharlatan) find a better way to increase the channel size
31-
events: make(chan []byte), //the channel size needs to be increased every time we had an extra endpoint
32+
events: make(chan []byte), //the channel size needs to be increased every time we had an extra endpoint
33+
electrumEvents: make(chan []byte),
3234
info: SampleInfoResponse{
3335
Blocks: 0,
3436
Difficulty: 0.0,

middleware/src/rpcserver/rpcserver.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net/rpc"
66

77
middleware "github.com/digitalbitbox/bitbox-base/middleware/src"
8+
"github.com/digitalbitbox/bitbox-base/middleware/src/electrum"
89
)
910

1011
type rpcConn struct {
@@ -55,17 +56,21 @@ type Electrum interface {
5556

5657
// RPCServer provides rpc calls to the middleware
5758
type RPCServer struct {
58-
middleware Middleware
59-
electrum Electrum
60-
RPCConnection *rpcConn
59+
middleware Middleware
60+
electrum Electrum
61+
electrumAddress string
62+
onElectrumMessageReceived func(msg []byte)
63+
RPCConnection *rpcConn
6164
}
6265

6366
// NewRPCServer returns a new RPCServer
64-
func NewRPCServer(middleware Middleware, electrum Electrum) *RPCServer {
67+
func NewRPCServer(middleware Middleware, electrumAddress string, onElectrumMessageReceived func(msg []byte)) *RPCServer { //, electrum Electrum) *RPCServer {
6568
server := &RPCServer{
66-
middleware: middleware,
67-
electrum: electrum,
68-
RPCConnection: newRPCConn(),
69+
middleware: middleware,
70+
//electrum: electrum,
71+
electrumAddress: electrumAddress,
72+
onElectrumMessageReceived: onElectrumMessageReceived,
73+
RPCConnection: newRPCConn(),
6974
}
7075
err := rpc.Register(server)
7176
if err != nil {
@@ -96,10 +101,18 @@ func (server *RPCServer) GetSampleInfo(args int, reply *middleware.SampleInfoRes
96101
return nil
97102
}
98103

99-
// ElectrumSend sends a message to Electrum on the connection owned by the client.
104+
// ElectrumSend sends a message to the Electrum server on the connection owned by the client.
100105
func (server *RPCServer) ElectrumSend(
101106
args struct{ Msg []byte },
102107
reply *struct{}) error {
108+
if server.electrum == nil {
109+
electrumClient, err := electrum.NewElectrum(server.electrumAddress, server.onElectrumMessageReceived)
110+
server.electrum = electrumClient
111+
if err != nil {
112+
log.Println(err.Error() + "Electrum connection failed to initialize")
113+
return err
114+
}
115+
}
103116
return server.electrum.Send(args.Msg)
104117
}
105118

middleware/src/rpcserver/rpcserver_test.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,6 @@ func (conn *rpcConn) Close() error {
2929
return nil
3030
}
3131

32-
type electrumMock struct {
33-
send func([]byte) error
34-
}
35-
36-
func (e *electrumMock) Send(msg []byte) error {
37-
if e.send != nil {
38-
return e.send(msg)
39-
}
40-
return nil
41-
}
42-
4332
func TestRPCServer(t *testing.T) {
4433
argumentMap := make(map[string]string)
4534
argumentMap["bitcoinRPCUser"] = "user"
@@ -50,7 +39,7 @@ func TestRPCServer(t *testing.T) {
5039
argumentMap["network"] = "testnet"
5140
argumentMap["bbbConfigScript"] = "/home/bitcoin/script.sh"
5241
middlewareInstance := middleware.NewMiddleware(argumentMap)
53-
rpcServer := rpcserver.NewRPCServer(middlewareInstance, &electrumMock{})
42+
rpcServer := rpcserver.NewRPCServer(middlewareInstance, "localhost:80801", func([]byte) {})
5443
serverWriteChan := rpcServer.RPCConnection.WriteChan()
5544
serverReadChan := rpcServer.RPCConnection.ReadChan()
5645

@@ -73,9 +62,11 @@ func TestRPCServer(t *testing.T) {
7362
msgRequest := <-clientWriteChan
7463
serverReadChan <- msgRequest
7564
msgResponse := <-serverWriteChan
65+
//t.Logf("significant byte: %s", string(msgResponse[0]))
7666
t.Logf("response message %s", string(msgResponse))
7767
// Cut off the significant Byte in the response
78-
clientReadChan <- msgResponse[1:]
68+
//t.Logf("significant byte: %s", string(msgResponse[1]))
69+
clientReadChan <- msgResponse
7970
wg.Wait()
8071
t.Logf("reply: %v", reply)
8172
require.Equal(t, "testnet", reply.Network)
@@ -96,7 +87,7 @@ func TestRPCServer(t *testing.T) {
9687
msgResponse = <-serverWriteChan
9788
t.Logf("Resync Bitcoin Response %q", string(msgResponse))
9889
// Cut off the significant Byte in the response
99-
clientReadChan <- msgResponse[1:]
90+
clientReadChan <- msgResponse
10091
wg.Wait()
10192
require.Equal(t, false, resyncReply.Success)
10293
}

0 commit comments

Comments
 (0)