BIP 0036: Difference between revisions
m Removing redundant parameter. |
Update BIP text with latest version from https://github.com/bitcoin/bips/blob/b5723035e23896d0/bip-0036.mediawiki |
||
Line 1: | Line 1: | ||
{{bip}} | {{bip}} | ||
{{BipMoved|bip-0036.mediawiki}} | |||
<pre> | <pre> | ||
BIP: 36 | BIP: 36 | ||
Layer: Peer Services | |||
Title: Custom Services | Title: Custom Services | ||
Author: Stefan Thomas <justmoon@members.fsf.org> | Author: Stefan Thomas <justmoon@members.fsf.org> | ||
Comments-Summary: No comments yet. | |||
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0036 | |||
Status: Draft | Status: Draft | ||
Type: Standards Track | Type: Standards Track | ||
Created: 03- | Created: 2012-08-03 | ||
License: PD | |||
</pre> | |||
==Abstract== | |||
This BIP adds new fields to the <code>version</code> message which clients can use to announce custom services without polluting the limited 64-bit <code>services</code> field. It also makes some non-binding recommendations regarding the implementation of custom services. | |||
==Motivation== | |||
We would like to encourage experimentation with custom services that extend the Bitcoin protocol with useful functionality. Examples include Distributed Hash Tables (DHT), distributed pools, lightweight client support protocols, directed message routing and support for custom transports. However, without a general framework for protocol extensions, these custom services are likely to collide in various ways. This BIP provides such a framework. | |||
==Specification== | |||
Two new fields are added to the <code>version</code> command, after <code>extra_height</code>: | |||
{|class="wikitable" | |||
! Field Size !! Description !! Data type !! Comments | |||
|- | |||
| 1+ || service_count || [[Protocol_specification#Variable_length_integer|var_int]] || Number of extra services | |||
|- | |||
| ? || service_list || service[] || List of service definitions | |||
|} | |||
The service definitions <code>service[]</code> are given in the following format: | |||
{|class="wikitable" | |||
! Field Size !! Description !! Data type !! Comments | |||
|- | |||
| ? || service_name || [[#Variable length string|var_str]] || Unique service identifier | |||
|- | |||
| 4 || service_version || uint32_t || Identifies service version being used by the node | |||
|- | |||
| ? || service_data || [[#Variable length string|var_str]] || Additional service-specific data | |||
|} | |||
A node MUST NOT announce two services with the same <code>service_name</code>. If a remote node sends such a <code>version</code> message the client MAY disconnect. | |||
The <code>service_version</code> is service-specific and can be any integer. Higher versions SHOULD be higher integers. When a service is standardized, it is assigned a <code>NODE_*</code> constant for use with the <code>services</code> field and future iterations of the protocol depend on the Bitcoin protocol version. Both the <code>NODE_*</code> flag and the custom service entry MAY be provided for the duration of a transitional period. | |||
Services SHOULD pass an empty string (0x00) as <code>service_data</code> and use a custom handshake to initialize their protocol, exchange information about capabilities etc. Note that to become a standardized service, a service MUST NOT rely on <code>service_data</code> since there is no corresponding mechanism for the standard services defined in the <code>services</code> field. | |||
However, services MAY use <code>service_data</code> if they do not intend to become standard services and need a simple way to transmit a small amount of initialization data. For example, a node offering a custom transport like UDP or WebSocket, may choose to announce this as a service and include the port number in <code>service_data</code>. The format for <code>service_data</code> is service-specific and may be any binary or ASCII data. For ease of debugging, a human-readable (ASCII) format is generally recommended. | |||
===Service identifier=== | |||
Each service SHOULD choose a new identifier that is not used by any other service. To register a new identifier, add it to the [[Service identifiers]] wiki page along with the name of the maintainer and a way to contact them. Please do not register identifiers unless you are actually using them. | |||
Service identifiers that are reserved or used by an accepted BIP MUST NOT be used except in the way specified by that BIP. | |||
Service identifiers MUST be between five (5) and eleven (11) characters long. Service identifiers MUST use only ASCII characters, excluding: / * _ : | |||
Valid examples: | |||
* <code>MySampleSvc</code> | |||
* <code>smartserv</code> | |||
* <code>P-Pool</code> | |||
Valid, but discouraged examples: | |||
* <code>MySVC 1.0</code> (use <code>service_version</code> to differentiate versions) | |||
* <code>@@---.</code> (identifiers should be pronounceable) | |||
* <code>lightweight</code> (avoid too generic names) | |||
Invalid examples: | |||
* <code>Pppc</code> (too short) | |||
* <code>SuperService</code> (too long) | |||
* <code>Cool_Svc</code> (invalid character) | |||
===Optional: Custom commands=== | |||
Bitcoin command names are limited to 12 characters. That doesn't leave a lot of space for both the service identifier and the service command. Therefore we recommend that all service commands SHOULD be represented by a single "command" on the Bitcoin network. This command SHOULD consist of the exact service identifier to avoid collisions with other services, prefixed by an underscore to avoid collisions with current or future Bitcoin protocol messages. For example: <code>_MySampleSvc</code> | |||
The service-specific command name SHOULD then be specified in an extra header in the payload: | |||
{|class="wikitable" | |||
! Field Size !! Description !! Data type !! Comments | |||
|- | |||
| 12 || subcommand || char[12] || ASCII string identifying the service command, NULL padded (non-NULL padding results in packet rejected) | |||
|- | |||
| ? || subpayload || uchar[] || The actual data | |||
|} | |||
The length of <code>subpayload</code> is derived from the length of the total payload minus twelve (12) bytes for the <code>subcommand</code>. Implementations MUST NOT rely on this format to be used by unknown services. Clients SHOULD ignore any services or subcommands they don't explicitly understand. | |||
The recommended way to refer to messages following this format in documentation is by the service identifier, followed by a colon, followed by the subcommand. For example, the subcommand <code>search</code> for the <code>MySampleSvc</code> service would be referred to as: <code>MySampleSvc:search</code> | |||
Full hexdump of an example <code>MySampleSvc:search</code> message: | |||
<pre> | |||
0000 F9 BE B4 D9 5F 4D 79 53 61 6D 70 6C 65 53 76 63 ...._MySampleSvc | |||
0010 14 00 00 00 73 D5 56 77 73 65 61 72 63 68 00 00 ....s.Vwsearch.. | |||
0020 00 00 00 00 12 34 56 78 9A BC DE F0 .....4Vx.... | |||
Message header: | |||
F9 BE B4 D9 - Main network magic bytes | |||
5F 4D 79 53 61 6D 70 6C 65 53 76 63 - "_MySampleSvc" command | |||
14 00 00 00 - Payload is 20 bytes long | |||
(includes 12 bytes for subcommand) | |||
73 D5 56 77 - Checksum | |||
Service header: | |||
73 65 61 72 63 68 00 00 00 00 00 00 - "search" subcommand | |||
Search message: | |||
12 34 56 78 9A BC DE F0 - Payload | |||
</pre> | </pre> | ||
==Standardization== | |||
Custom services may become standard parts of the protocol. Services which wish to become part of the Bitcoin protocol MUST fulfill the following criteria: | |||
* MUST NOT use <code>service_data</code>; Standard services have no corresponding field | |||
* MUST use a peer discovery mechanism which specifies one bit per node, same as the <code>services</code> field in <code>addr</code> messages | |||
* MUST NOT use any subcommands that conflict with current or planned Bitcoin protocol commands | |||
The standardization process will usually take place as follows: | |||
# The service is implemented and tested. | |||
# Once the API is known to be relatively stable it is formalized and submitted as a BIP. | |||
# Once the BIP is accepted, the service is assigned a <code>NODE_*</code> constant and the transitional period starts: | |||
#* Clients MUST understand both the announcement of the service via the <code>services</code> field and via <code>service_list</code> and include both methods in their own <code>version</code> message. | |||
#* Clients MUST accept both the wrapped form messages like <code>MySampleSvc:search</code> as well as the corresponding non-namespaced messages like <code>search</code>. Clients MUST only send wrapped messages. | |||
#* During the transitional period the API of the service MUST NOT change. | |||
# After the transitional period: | |||
#* Clients MUST only announce the service via the <code>services</code> field. | |||
#* Clients MUST only send unwrapped messages. | |||
# Future changes to the service API now require a BIP and an increase in the Bitcoin protocol version. | |||
This process of adding a service to the Bitcoin protocol should only be undertaken for services where there is a strong rationale for doing so. Services MAY also be standardized as custom services via a BIP while maintaining the custom service format. | |||
==Rationale== | |||
This BIP aims to fulfill the following goals: | |||
* Minimize the risk of namespace collisions, ambiguities or other issues arising from conflicting custom services | |||
* Provide an easy upgrade path for custom services to become standardized services with their own <code>NODE_*</code> flag | |||
* Place minimum restrictions on custom service authors | |||
* Allow custom services to be created with minimum effort | |||
* Allow clients to support multiple/many custom services at once | |||
To achieve these goals this BIP adds two new fields to the <code>version</code> message. It would have been possible to avoid changes to <code>version</code> by adding a new message instead. However, it makes sense to keep both types of service announcements in the same message so that the life cycle of standardized services and custom services remains exactly the same. This also simplifies detecting a service which is in the transition from a custom to a standardized service (and being announced using both methods.) | |||
Finally, this BIP defines both explicitly and implicitly some useful common nomenclature that can be used when discussing custom services, e.g. "subcommand", "subpayload", "service identifier" and the colon format for referring to subcommands. | |||
==Copyright== | |||
This document is placed in the public domain. | |||
Revision as of 17:58, 24 September 2019
This page describes a BIP (Bitcoin Improvement Proposal). |
Please do not modify this page. This is a mirror of the BIP from the source Git repository here. |
BIP: 36 Layer: Peer Services Title: Custom Services Author: Stefan Thomas <justmoon@members.fsf.org> Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0036 Status: Draft Type: Standards Track Created: 2012-08-03 License: PD
Abstract
This BIP adds new fields to the version
message which clients can use to announce custom services without polluting the limited 64-bit services
field. It also makes some non-binding recommendations regarding the implementation of custom services.
Motivation
We would like to encourage experimentation with custom services that extend the Bitcoin protocol with useful functionality. Examples include Distributed Hash Tables (DHT), distributed pools, lightweight client support protocols, directed message routing and support for custom transports. However, without a general framework for protocol extensions, these custom services are likely to collide in various ways. This BIP provides such a framework.
Specification
Two new fields are added to the version
command, after extra_height
:
Field Size | Description | Data type | Comments |
---|---|---|---|
1+ | service_count | var_int | Number of extra services |
? | service_list | service[] | List of service definitions |
The service definitions service[]
are given in the following format:
Field Size | Description | Data type | Comments |
---|---|---|---|
? | service_name | var_str | Unique service identifier |
4 | service_version | uint32_t | Identifies service version being used by the node |
? | service_data | var_str | Additional service-specific data |
A node MUST NOT announce two services with the same service_name
. If a remote node sends such a version
message the client MAY disconnect.
The service_version
is service-specific and can be any integer. Higher versions SHOULD be higher integers. When a service is standardized, it is assigned a NODE_*
constant for use with the services
field and future iterations of the protocol depend on the Bitcoin protocol version. Both the NODE_*
flag and the custom service entry MAY be provided for the duration of a transitional period.
Services SHOULD pass an empty string (0x00) as service_data
and use a custom handshake to initialize their protocol, exchange information about capabilities etc. Note that to become a standardized service, a service MUST NOT rely on service_data
since there is no corresponding mechanism for the standard services defined in the services
field.
However, services MAY use service_data
if they do not intend to become standard services and need a simple way to transmit a small amount of initialization data. For example, a node offering a custom transport like UDP or WebSocket, may choose to announce this as a service and include the port number in service_data
. The format for service_data
is service-specific and may be any binary or ASCII data. For ease of debugging, a human-readable (ASCII) format is generally recommended.
Service identifier
Each service SHOULD choose a new identifier that is not used by any other service. To register a new identifier, add it to the Service identifiers wiki page along with the name of the maintainer and a way to contact them. Please do not register identifiers unless you are actually using them.
Service identifiers that are reserved or used by an accepted BIP MUST NOT be used except in the way specified by that BIP.
Service identifiers MUST be between five (5) and eleven (11) characters long. Service identifiers MUST use only ASCII characters, excluding: / * _ :
Valid examples:
MySampleSvc
smartserv
P-Pool
Valid, but discouraged examples:
MySVC 1.0
(useservice_version
to differentiate versions)@@---.
(identifiers should be pronounceable)lightweight
(avoid too generic names)
Invalid examples:
Pppc
(too short)SuperService
(too long)Cool_Svc
(invalid character)
Optional: Custom commands
Bitcoin command names are limited to 12 characters. That doesn't leave a lot of space for both the service identifier and the service command. Therefore we recommend that all service commands SHOULD be represented by a single "command" on the Bitcoin network. This command SHOULD consist of the exact service identifier to avoid collisions with other services, prefixed by an underscore to avoid collisions with current or future Bitcoin protocol messages. For example: _MySampleSvc
The service-specific command name SHOULD then be specified in an extra header in the payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
12 | subcommand | char[12] | ASCII string identifying the service command, NULL padded (non-NULL padding results in packet rejected) |
? | subpayload | uchar[] | The actual data |
The length of subpayload
is derived from the length of the total payload minus twelve (12) bytes for the subcommand
. Implementations MUST NOT rely on this format to be used by unknown services. Clients SHOULD ignore any services or subcommands they don't explicitly understand.
The recommended way to refer to messages following this format in documentation is by the service identifier, followed by a colon, followed by the subcommand. For example, the subcommand search
for the MySampleSvc
service would be referred to as: MySampleSvc:search
Full hexdump of an example MySampleSvc:search
message:
0000 F9 BE B4 D9 5F 4D 79 53 61 6D 70 6C 65 53 76 63 ...._MySampleSvc 0010 14 00 00 00 73 D5 56 77 73 65 61 72 63 68 00 00 ....s.Vwsearch.. 0020 00 00 00 00 12 34 56 78 9A BC DE F0 .....4Vx.... Message header: F9 BE B4 D9 - Main network magic bytes 5F 4D 79 53 61 6D 70 6C 65 53 76 63 - "_MySampleSvc" command 14 00 00 00 - Payload is 20 bytes long (includes 12 bytes for subcommand) 73 D5 56 77 - Checksum Service header: 73 65 61 72 63 68 00 00 00 00 00 00 - "search" subcommand Search message: 12 34 56 78 9A BC DE F0 - Payload
Standardization
Custom services may become standard parts of the protocol. Services which wish to become part of the Bitcoin protocol MUST fulfill the following criteria:
- MUST NOT use
service_data
; Standard services have no corresponding field - MUST use a peer discovery mechanism which specifies one bit per node, same as the
services
field inaddr
messages - MUST NOT use any subcommands that conflict with current or planned Bitcoin protocol commands
The standardization process will usually take place as follows:
- The service is implemented and tested.
- Once the API is known to be relatively stable it is formalized and submitted as a BIP.
- Once the BIP is accepted, the service is assigned a
NODE_*
constant and the transitional period starts:- Clients MUST understand both the announcement of the service via the
services
field and viaservice_list
and include both methods in their ownversion
message. - Clients MUST accept both the wrapped form messages like
MySampleSvc:search
as well as the corresponding non-namespaced messages likesearch
. Clients MUST only send wrapped messages. - During the transitional period the API of the service MUST NOT change.
- Clients MUST understand both the announcement of the service via the
- After the transitional period:
- Clients MUST only announce the service via the
services
field. - Clients MUST only send unwrapped messages.
- Clients MUST only announce the service via the
- Future changes to the service API now require a BIP and an increase in the Bitcoin protocol version.
This process of adding a service to the Bitcoin protocol should only be undertaken for services where there is a strong rationale for doing so. Services MAY also be standardized as custom services via a BIP while maintaining the custom service format.
Rationale
This BIP aims to fulfill the following goals:
- Minimize the risk of namespace collisions, ambiguities or other issues arising from conflicting custom services
- Provide an easy upgrade path for custom services to become standardized services with their own
NODE_*
flag - Place minimum restrictions on custom service authors
- Allow custom services to be created with minimum effort
- Allow clients to support multiple/many custom services at once
To achieve these goals this BIP adds two new fields to the version
message. It would have been possible to avoid changes to version
by adding a new message instead. However, it makes sense to keep both types of service announcements in the same message so that the life cycle of standardized services and custom services remains exactly the same. This also simplifies detecting a service which is in the transition from a custom to a standardized service (and being announced using both methods.)
Finally, this BIP defines both explicitly and implicitly some useful common nomenclature that can be used when discussing custom services, e.g. "subcommand", "subpayload", "service identifier" and the colon format for referring to subcommands.
Copyright
This document is placed in the public domain.