IPC - bitcoin-black-bcb/btcb GitHub Wiki

Overview

As of v18, the Btcb node exposes a low level IPC interface over which multiple future APIs can be marshalled. Currently, the IPC interface supports the legacy RPC JSON format. The HTTP based RPC server is still available.

Transports

TCP and unix domain sockets are supported. Named pipes and shared memory may be supported in future releases.

IPC clients

A demo web server written in Go is available at https://github.com/btcbcurrency/rpc-go. This allows HTTP clients to make JSON requests via IPC, which is compatible with the existing format. The web server can communicate with a node over domain sockets or TCP.

A NodeJS client is available at https://github.com/meltingice/btcb-ipc-js

A Python client is being developed at https://github.com/guilhermelawless/btcb-ipc-py

Configuration

On startup, the node will generate configuration options for IPC, one entry for each transport. By default, IPC is disabled.

"ipc": {
   "tcp": {
       "enable": "false",
       "port": "7077",
       "io_timeout": "15000"
   },
   "local": {
       "enable": "false",
       "path": "\/tmp\/btcb",
       "io_timeout": "15000"
     }
}

Each transport also supports an experimental "io_threads" configuration value. If not present (default), the node's IO event loop will be used. If a value is present, a separate event loop with N threads will be created for the transport. For certain transports, this may scale better on some systems.

Because the only IPC encoding is currently "legacy RPC", the RPC config options like "enable_control" still applies.

IPC request/response format

A client must make requests using the following framing format:

REQUEST  ::= HEADER PAYLOAD
HEADER   ::= u8('N') ENCODING u8(0) u8(0)
ENCODING ::= u8(1)
PAYLOAD  ::= <encoding specific>

Only one encoding currently exists: 1 (legacy RPC)

The encoding is followed by two reserved zero-bytes. These allow for future extensions, such as versioning and extended headers.

Note that the framing format does not include a length field - this is optionally placed in the respective payloads. The reason is that some encodings might want to be "streamy", sending responses in chunks, or end with a sentinel.

LEGACY_RPC_PAYLOAD  ::= be32(length) JSON request
LEGACY_RPC_RESPONSE ::= be32(length) JSON response

In short, JSON requests and responses are 32-bit big-endian length-prefixed.