Browse Source

pylightning: Add a compatibility mode for pre-\n\n versions

We inadvertently broke the compatibility between the python library
and the binary when switching to \n\n-delimiters. This reintroduces
the old inefficient parsing, and dynamically upgrades to the faster
version if it detects the \n\n-delimiter.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
plugin-6
Christian Decker 6 years ago
parent
commit
bd6e3bfe6a
  1. 1
      CHANGELOG.md
  2. 29
      contrib/pylightning/lightning/lightning.py

1
CHANGELOG.md

@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- JSON API: `pay` and `decodepay` accept and ignore `lightning:` prefixes. - JSON API: `pay` and `decodepay` accept and ignore `lightning:` prefixes.
- pylightning: Allow either keyword arguments or positional arguments. - pylightning: Allow either keyword arguments or positional arguments.
- JSON-RPC: messages are now separated by 2 consecutive newlines. The pylightning client library has temporary support for both separators, but will eventually drop the single newline separator, which may cause it to stop working on older clients (see #2135 for details).
### Deprecated ### Deprecated

29
contrib/pylightning/lightning/lightning.py

@ -20,11 +20,38 @@ class UnixDomainSocketRpc(object):
self.executor = executor self.executor = executor
self.logger = logger self.logger = logger
# Do we require the compatibility mode?
self._compat = True
@staticmethod @staticmethod
def _writeobj(sock, obj): def _writeobj(sock, obj):
s = json.dumps(obj) s = json.dumps(obj)
sock.sendall(bytearray(s, 'UTF-8')) sock.sendall(bytearray(s, 'UTF-8'))
def _readobj_compat(self, sock, buff=b''):
if not self._compat:
return self._readobj(sock, buff)
while True:
try:
b = sock.recv(1024)
buff += b
if b'\n\n' in buff:
# The next read will use the non-compatible read instead
self._compat = False
if len(b) == 0:
return {'error': 'Connection to RPC server lost.'}
if b' }\n' not in buff:
continue
# Convert late to UTF-8 so glyphs split across recvs do not
# impact us
objs, len_used = self.decoder.raw_decode(buff.decode("UTF-8"))
return objs, buff[len_used:].lstrip()
except ValueError:
# Probably didn't read enough
pass
def _readobj(self, sock, buff=b''): def _readobj(self, sock, buff=b''):
"""Read a JSON object, starting with buff; returns object and any buffer left over""" """Read a JSON object, starting with buff; returns object and any buffer left over"""
while True: while True:
@ -74,7 +101,7 @@ class UnixDomainSocketRpc(object):
"params": payload, "params": payload,
"id": 0 "id": 0
}) })
resp, _ = self._readobj(sock) resp, _ = self._readobj_compat(sock)
sock.close() sock.close()
self.logger.debug("Received response for %s call: %r", method, resp) self.logger.debug("Received response for %s call: %r", method, resp)

Loading…
Cancel
Save