JLP Protocol Specification

Version 1.0 - Collision Protocol Pool Communication Standard

Overview

The JLP (JeanLucPons) Protocol is a binary protocol for communication between Kangaroo workers and pool servers. It handles authentication, work distribution, and distinguished point (DP) submission.

Transport:TCP with optional TLS
Default Port:17403
Byte Order:Little-endian
Max Message:1 MB

Connection URLs

jlp://host:portPlain TCP connection
jlps://host:portTLS encrypted connection (recommended)

Message Format

All messages follow this 8-byte header format:

+--------+--------+--------+--------+--------+--------+--------+--------+
|   'K'  |   'A'  |   'N'  |   'G'  |  TYPE  | FLAGS  |    LENGTH (u16)   |
+--------+--------+--------+--------+--------+--------+--------+--------+
|  0x4B  |  0x41  |  0x4E  |  0x47  |  0xNN  |  0x00  |  LO     |  HI    |
+--------+--------+--------+--------+--------+--------+--------+--------+
|<-------- 4 bytes -------->|<- 1B ->|<- 1B ->|<------ 2 bytes -------->|
|        MAGIC              |  TYPE  | FLAGS  |      PAYLOAD LENGTH     |
MAGIC4 bytes - ASCII "KANG" (0x4B 0x41 0x4E 0x47)
TYPE1 byte - Message type (see table below)
FLAGS1 byte - Reserved, must be 0x00
LENGTH2 bytes - Payload length (little-endian uint16)

Implementation Reference

C/C++ Header Structure

#pragma pack(push, 1)
struct JLPHeader {
    uint8_t  magic[4];   // "KANG"
    uint8_t  type;       // Message type
    uint8_t  flags;      // Reserved (0x00)
    uint16_t length;     // Payload length (little-endian)
};
#pragma pack(pop)

// Total header size: 8 bytes

Python Encoding

import struct

def encode_message(msg_type: int, payload: bytes = b'') -> bytes:
    header = struct.pack('<4sBBH', b'KANG', msg_type, 0, len(payload))
    return header + payload

def decode_header(data: bytes) -> tuple[int, int, int]:
    magic, msg_type, flags, length = struct.unpack('<4sBBH', data[:8])
    if magic != b'KANG':
        raise ValueError(f"Invalid magic: {magic}")
    return msg_type, flags, length

Message Types

TypeValueDirectionDescription
AUTH0x01Client → ServerAuthentication request
AUTH_OK0x02Server → ClientAuthentication successful
AUTH_FAIL0x03Server → ClientAuthentication failed
WORK_REQ0x10Client → ServerRequest work assignment
WORK_ASN0x11Server → ClientWork assignment response
DP_SUBMIT0x20Client → ServerSubmit single DP
DP_ACK0x21Server → ClientDP acknowledged
DP_BATCH0x22Client → ServerSubmit batch of DPs
STATS_REQ0x30Client → ServerRequest statistics
STATS_RSP0x31Server → ClientStatistics response
SOLUTION0x40Server → AllSolution found broadcast
PING0x50BothKeepalive ping
PONG0x51BothKeepalive pong
ERROR0xFFServer → ClientError message

Payload Structures

AUTH (0x01) - 96 bytes

struct AuthPayload {
    char worker_name[64];  // Worker name (null-padded)
    char password[32];     // Pool password (null-padded)
};

WORK_ASN (0x11) - 102 bytes

struct WorkAssignment {
    uint32_t puzzle_id;       // Puzzle number
    uint8_t  range_start[32]; // Search range start (big-endian)
    uint8_t  range_end[32];   // Search range end (big-endian)
    uint8_t  public_key[33];  // Target public key (compressed)
    uint8_t  dp_bits;         // Distinguished point bits
};

DP_SUBMIT (0x20) - 66 bytes

struct DistinguishedPoint {
    uint8_t x[32];     // X coordinate (big-endian)
    uint8_t d[32];     // Distance traveled (big-endian)
    uint8_t type;      // 0 = tame, 1 = wild
    uint8_t dp_bits;   // Number of leading zero bits
};

DP_BATCH (0x22) - Variable

struct DPBatch {
    uint32_t count;                  // Number of DPs (max 10,000)
    DistinguishedPoint dps[count];   // Array of DPs (66 bytes each)
};

// Total size: 4 + (count * 66) bytes

DP_ACK (0x21) - 4 bytes

struct DPAck {
    uint32_t count;  // Number of DPs acknowledged
};

Connection Flow

Client                                    Server
   |                                         |
   |  -------- TCP/TLS Connect --------->    |
   |                                         |
   |  -------- AUTH (worker, pass) ----->    |
   |  <------- AUTH_OK -----------------     |
   |                                         |
   |  -------- WORK_REQ --------------->     |
   |  <------- WORK_ASN (puzzle, range)      |
   |                                         |
   |       ... compute DPs ...               |
   |                                         |
   |  -------- DP_BATCH (DPs) --------->     |
   |  <------- DP_ACK ------------------     |
   |                                         |
   |  -------- PING ------------------->     |
   |  <------- PONG --------------------     |
   |                                         |
   |  <------- SOLUTION (if found) -----     |
   |                                         |

Security Considerations

Use TLS

Always use jlps:// for encrypted connections. The server supports TLSv1.2 and TLSv1.3.

Rate Limiting

Workers are limited to 1,000 DPs per second. Exceeding this will result in temporary rate limiting.

Batch Limits

DP_BATCH messages are limited to 10,000 DPs maximum. Larger batches will be rejected.

Message Timeout

Messages must be fully received within 30 seconds or the connection will be closed.

Reference Implementation

The reference server implementation is available on GitHub:

github.com/hevnsnt/collision-protocol

The pool server is written in Python with asyncio. Client implementations can be in any language that supports TCP sockets.