|
3 | 3 | from fixtures import TEST_NETWORK
|
4 | 4 | from flaky import flaky # noqa: F401
|
5 | 5 | from pyln.client import RpcError, Millisatoshi
|
| 6 | +import pyln.proto.wire as wire |
6 | 7 | from utils import (
|
7 | 8 | only_one, wait_for, sync_blockheight, TIMEOUT,
|
8 | 9 | expected_peer_features, expected_node_features,
|
|
20 | 21 | import shutil
|
21 | 22 | import time
|
22 | 23 | import unittest
|
| 24 | +import websocket |
23 | 25 |
|
24 | 26 |
|
25 | 27 | def test_connect(node_factory):
|
@@ -3734,3 +3736,51 @@ def test_old_feerate(node_factory):
|
3734 | 3736 |
|
3735 | 3737 | # This will timeout if l2 didn't accept fee.
|
3736 | 3738 | l1.pay(l2, 1000)
|
| 3739 | + |
| 3740 | + |
| 3741 | +def test_websocket(node_factory): |
| 3742 | + l1 = node_factory.get_node(options={'experimental-websocket': None, 'log-level': 'io'}) |
| 3743 | + assert l1.rpc.listconfigs()['experimental-websocket'] |
| 3744 | + |
| 3745 | + # Adapter to turn websocket into a stream "connection" |
| 3746 | + class BinWebSocket(object): |
| 3747 | + def __init__(self, hostname, port): |
| 3748 | + self.ws = websocket.WebSocket() |
| 3749 | + self.ws.connect("ws://" + hostname + ":" + str(port)) |
| 3750 | + self.recvbuf = bytes() |
| 3751 | + |
| 3752 | + def send(self, data): |
| 3753 | + self.ws.send(data, websocket.ABNF.OPCODE_BINARY) |
| 3754 | + |
| 3755 | + def recv(self, maxlen): |
| 3756 | + while len(self.recvbuf) < maxlen: |
| 3757 | + self.recvbuf += self.ws.recv() |
| 3758 | + |
| 3759 | + ret = self.recvbuf[:maxlen] |
| 3760 | + self.recvbuf = self.recvbuf[maxlen:] |
| 3761 | + return ret |
| 3762 | + |
| 3763 | + ws = BinWebSocket('localhost', l1.port) |
| 3764 | + lconn = wire.LightningConnection(ws, |
| 3765 | + wire.PublicKey(bytes.fromhex(l1.info['id'])), |
| 3766 | + wire.PrivateKey(bytes([1] * 32)), |
| 3767 | + is_initiator=True) |
| 3768 | + # Perform handshake. |
| 3769 | + lconn.shake() |
| 3770 | + |
| 3771 | + # Expect to receive init msg. |
| 3772 | + msg = lconn.read_message() |
| 3773 | + assert int.from_bytes(msg[0:2], 'big') == 16 |
| 3774 | + |
| 3775 | + # Echo same message back. |
| 3776 | + lconn.send_message(msg) |
| 3777 | + |
| 3778 | + # Now try sending a ping, ask for 50 bytes |
| 3779 | + msg = bytes((0, 18, 0, 50, 0, 0)) |
| 3780 | + lconn.send_message(msg) |
| 3781 | + |
| 3782 | + # Could actually reply with some gossip msg! |
| 3783 | + while True: |
| 3784 | + msg = lconn.read_message() |
| 3785 | + if int.from_bytes(msg[0:2], 'big') == 19: |
| 3786 | + break |
0 commit comments