https://wiki.bitmessage.org/w/index.php?title=Bitmessage_Protocol_Version_3&feed=atom&action=historyBitmessage Protocol Version 3 - Revision history2024-03-28T10:10:46ZRevision history for this page on the wikiMediaWiki 1.34.0https://wiki.bitmessage.org/index.php?title=Bitmessage_Protocol_Version_3&diff=47477&oldid=prevBmng-dev: Distinguish identity from pubkey structure, minor corrections2016-11-16T01:57:58Z<p>Distinguish identity from pubkey structure, minor corrections</p>
<a href="https://wiki.bitmessage.org/index.php?title=Bitmessage_Protocol_Version_3&diff=47477&oldid=46346">Show changes</a>Bmng-devhttps://wiki.bitmessage.org/index.php?title=Bitmessage_Protocol_Version_3&diff=46346&oldid=prevBmng-dev: Removed proposed message encoding. Added ping and pong messages. Other fixes and clarifications2016-06-27T04:41:47Z<p>Removed proposed message encoding. Added ping and pong messages. Other fixes and clarifications</p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #222; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #222; text-align: center;">Revision as of 04:41, 27 June 2016</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l173" >Line 173:</td>
<td colspan="2" class="diff-lineno">Line 173:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 2 || SIMPLE || UTF-8. Uses 'Subject' and 'Body' sections. No MIME is used. </div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 2 || SIMPLE || UTF-8. Uses 'Subject' and 'Body' sections. No MIME is used. </div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div><code>messageToTransmit = 'Subject:' + subject + '\n' + 'Body:' + message</code></div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div><code>messageToTransmit = 'Subject:' + subject + '\n' + 'Body:' + message</code></div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del style="font-weight: bold; text-decoration: none;">|-</del></div></td><td colspan="2"> </td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del style="font-weight: bold; text-decoration: none;">| 3 || EXTENDED || <span style="color:red">A data structure in bencode, then compressed with zlib. Null data type is encoded as an empty string, and booleans as an integer 0 (false) or 1 (true). Text fields are encoded using UTF-8. v5 and newer address versions MUST support this. Proposal, exact structure pending standardisation.</span></del></div></td><td colspan="2"> </td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l239" >Line 239:</td>
<td colspan="2" class="diff-lineno">Line 237:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== error ===</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== error ===</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del class="diffchange diffchange-inline"><span style="color:red">The only </del>error <del class="diffchange diffchange-inline">PyBitmessage sends </del>is a <del class="diffchange diffchange-inline">FATAL error when it receives a version message where the timestamp is out by more than hour from its own</span></del></div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>error is <ins class="diffchange diffchange-inline">used to convey the reason for </ins>a <ins class="diffchange diffchange-inline">following disconnection.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>{|class="wikitable"</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>{|class="wikitable"</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>! Field Size !! Description !! Data type !! Comments</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>! Field Size !! Description !! Data type !! Comments</div></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l247" >Line 247:</td>
<td colspan="2" class="diff-lineno">Line 247:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || ban time || [[#Variable_length_integer|var_int]] || The length of time the emitting node will refuse connections from the receiving node</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || ban time || [[#Variable_length_integer|var_int]] || The length of time the emitting node will refuse connections from the receiving node</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || inv_vector_length || [[#Variable_length_integer|var_int]] || The length of the inventory vector (max: 100) <span style="color:red">Inventory vectors are fixed length at 32 bytes. Why does the size need to specified? Perhaps this <del class="diffchange diffchange-inline">should </del>be a <del class="diffchange diffchange-inline">boolean value to indicate the presence </del>of <del class="diffchange diffchange-inline">an </del>inventory <del class="diffchange diffchange-inline">vector instead</del>?</span></div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || inv_vector_length || [[#Variable_length_integer|var_int]] || The length of the inventory vector (max: 100) <span style="color:red">Inventory vectors are fixed length at 32 bytes. Why does the size need to specified? Perhaps this <ins class="diffchange diffchange-inline">was intended to </ins>be a <ins class="diffchange diffchange-inline">count </ins>of inventory <ins class="diffchange diffchange-inline">vectors</ins>?</span></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| inv_vector_length || inv_vecter || [[#Inventory Vectors|inv_vect]] || The inventory vector of the offending object this error relates to</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| inv_vector_length || inv_vecter || [[#Inventory Vectors|inv_vect]] || The inventory vector of the offending object this error relates to</div></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l253" >Line 253:</td>
<td colspan="2" class="diff-lineno">Line 253:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || errorText || [[#Variable_length_string|var_str]] || The error text (max length: 1000)</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || errorText || [[#Variable_length_string|var_str]] || The error text (max length: 1000)</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"><span style="color:red">The only error PyBitmessage sends is a FATAL error when it receives a version message where the timestamp is out by more than hour from its own</span></ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== version ===</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== version ===</div></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l261" >Line 261:</td>
<td colspan="2" class="diff-lineno">Line 262:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>! Field Size !! Description !! Data type !! Comments</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>! Field Size !! Description !! Data type !! Comments</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>| 4 || version || int32_t || Identifies protocol version being used by the node. The current protocol version is 3. <del class="diffchange diffchange-inline">Nodes should disconnect if </del>the <del class="diffchange diffchange-inline">remote node's </del>version is <del class="diffchange diffchange-inline">lower but continue with the connection </del>if it is <del class="diffchange diffchange-inline">higher</del>. <del class="diffchange diffchange-inline"><span style="color:red">What is the intent here?<span></del></div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>| 4 || version || int32_t || Identifies protocol version being used by the node. The current protocol version is 3. <ins class="diffchange diffchange-inline">Old nodes will always assume that future protocol version nodes are compatible; it is up to the new client to judge whether </ins>the <ins class="diffchange diffchange-inline">previous </ins>version is <ins class="diffchange diffchange-inline">incompatible and disconnect </ins>if <ins class="diffchange diffchange-inline">it thinks that </ins>it is <ins class="diffchange diffchange-inline">a good idea</ins>.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 8 || services || uint64_t || bitfield of features to be enabled for this connection</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 8 || services || uint64_t || bitfield of features to be enabled for this connection</div></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l284" >Line 284:</td>
<td colspan="2" class="diff-lineno">Line 285:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>This message is sent in reply to [[#version|version]] and has no payload. The TCP timeout starts out at 20 seconds; after verack messages are exchanged, the timeout is raised to 10 minutes.</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>This message is sent in reply to [[#version|version]] and has no payload. The TCP timeout starts out at 20 seconds; after verack messages are exchanged, the timeout is raised to 10 minutes.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>If both sides announce that they support SSL, they MUST perform a SSL handshake immediately after they both send and receive verack. During this SSL handshake, the TCP client acts as a SSL client, and the TCP server acts as a SSL server. <span style="color:red">PyBitmessage v0.5.4 or later requires the AECDH-AES256-SHA cipher <del class="diffchange diffchange-inline">over TLSv1, and prefers </del>the secp256k1 curve <del class="diffchange diffchange-inline">(but other curves may be accepted, depending on the version of python and OpenSSL used)</del>.</span></div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>If both sides announce that they support SSL, they MUST perform a SSL handshake immediately after they both send and receive verack. During this SSL handshake, the TCP client acts as a SSL client, and the TCP server acts as a SSL server. <span style="color:red">PyBitmessage v0.5.4 or later requires the AECDH-AES256-SHA cipher <ins class="diffchange diffchange-inline">using </ins>the secp256k1 curve <ins class="diffchange diffchange-inline">over TLSv1</ins>.</span></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== addr ===</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== addr ===</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>Provide information on known nodes of the network. Only nodes that have been known to be on the network in the last 3 hours should be advertised. <span style="color:red">This command is <del class="diffchange diffchange-inline">easily </del>abused and any entries should be <del class="diffchange diffchange-inline">treated </del>as <del class="diffchange diffchange-inline">unreliable</del></span></div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>Provide information on known nodes of the network. Only nodes that have been known to be on the network in the last 3 hours should be advertised. <span style="color:red">This command is <ins class="diffchange diffchange-inline">regularly </ins>abused and any entries should <ins class="diffchange diffchange-inline">not </ins>be <ins class="diffchange diffchange-inline">relied upon </ins>as <ins class="diffchange diffchange-inline">being nodes</ins></span></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>{|class="wikitable"</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>{|class="wikitable"</div></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l307" >Line 307:</td>
<td colspan="2" class="diff-lineno">Line 308:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || count || [[#Variable_length_integer|var_int]] || Number of inventory entries (max: 50,000)</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>| 1+ || count || [[#Variable_length_integer|var_int]] || Number of inventory entries (max: 50,000)</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|-</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>| 32 x count || list of inv_vect || [[<del class="diffchange diffchange-inline">Protocol specification</del>#Inventory Vectors|inv_vect]][] || Inventory vectors</div></td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>| 32 x count || list of inv_vect || [[#Inventory Vectors|inv_vect]][] || Inventory vectors</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l322" >Line 322:</td>
<td colspan="2" class="diff-lineno">Line 323:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>|}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div><span style="color:red">Current usage reveals getdata to only ever contain 1 entry</span></div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div><span style="color:red">Current usage reveals getdata to only ever contain 1 entry</span></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">=== ping ===</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">ping is used to check whether a peer is still responsive and has no payload. A ping should be sent if a peer has not sent anything for more than 5 minutes. A peer receiving a ping may either close the connection or keep it open. To keep a connection open a peer should respond with either a pong (if it has nothing to send) or any contextually valid message. If a peer is silent for a full 10 minutes the connection should be closed.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">=== pong ===</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">pong may be sent in response to a ping. pong may also be sent pre-emptively when a node recognises it hasn't sent anything to a peer for up to 5 minutes and wishes to keep the connection open. pong has no payload.</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== object ===</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>=== object ===</div></td></tr>
</table>Bmng-devhttps://wiki.bitmessage.org/index.php?title=Bitmessage_Protocol_Version_3&diff=46093&oldid=prevBmng-dev: Cleaned and updated Protocol v3 for posterity2016-06-12T03:53:56Z<p>Cleaned and updated Protocol v3 for posterity</p>
<p><b>New page</b></p><div>==Common standards==<br />
<br />
=== Hashes ===<br />
<br />
Most of the time [http://en.wikipedia.org/wiki/SHA-2 SHA-512] hashes are used, however [http://en.wikipedia.org/wiki/RIPEMD RIPEMD-160] is also used when creating an address.<br />
<br />
A double-round of SHA-512 is used for the Proof Of Work. Example of double-SHA-512 encoding of string "hello":<br />
<br />
hello<br />
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043(first round of sha-512)<br />
0592a10584ffabf96539f3d780d776828c67da1ab5b169e9e8aed838aaecc9ed36d49ff1423c55f019e050c66c6324f53588be88894fef4dcffdb74b98e2b200(second round of sha-512)<br />
<br />
For Bitmessage addresses (RIPEMD-160) this would give:<br />
<br />
hello<br />
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043(first round is sha-512)<br />
79a324faeebcbf9849f310545ed531556882487e (with ripemd-160)<br />
<br />
<br />
== Common structures ==<br />
<br />
All integers are encoded in big endian<br />
<br />
=== Message structure ===<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 4 || magic || uint32_t || Magic value indicating message origin network, and used to seek to next message when stream state is unknown<br />
|-<br />
| 12 || command || char[12] || ASCII string identifying the packet content, NULL padded (non-NULL padding results in packet rejected)<br />
|-<br />
| 4 || length || uint32_t || Length of payload in number of bytes. The maximum allowed value is 1,600,003 bytes<br />
|-<br />
| 4 || checksum || uint32_t || First 4 bytes of sha512(payload)<br />
|-<br />
| ? || message_payload || uchar[] || The actual data, a [[#Message_types|message]]. Not to be confused with objectPayload.<br />
|}<br />
<br />
Known magic values:<br />
<br />
{|class="wikitable"<br />
! Magic value !! Sent over wire as<br />
|-<br />
| 0xE9BEB4D9 || E9 BE B4 D9<br />
|}<br />
<br />
=== Variable length integer ===<br />
<br />
An integer can be encoded depending on the represented value to save space. Variable length integers always precede an array/vector of a type of data that may vary in length. Varints MUST use the minimum possible number of bytes to encode a value. For example; the value 6 can be encoded with one byte therefore a varint that uses three bytes to encode the value 6 is malformed and the decoding task must be aborted.<br />
<br />
{|class="wikitable"<br />
! Value !! Storage length !! Format<br />
|-<br />
| < 0xfd || 1 || uint8_t<br />
|-<br />
| <= 0xffff || 3 || 0xfd followed by the integer as uint16_t<br />
|-<br />
| <= 0xffffffff || 5 || 0xfe followed by the integer as uint32_t<br />
|-<br />
| - || 9 || 0xff followed by the integer as uint64_t<br />
|}<br />
<br />
=== Variable length string ===<br />
<br />
A variable length string can be stored using a variable length integer to encode the length followed by the string itself.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || length || [[#Variable_length_integer|var_int]] || Length of the string<br />
|-<br />
| length || string || char[] || The string itself (can be empty)<br />
|}<br />
<br />
=== Variable length list of integers===<br />
<br />
n integers can be stored using n+1 [[#Variable_length_integer|variable length integers]] where the first var_int equals n.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || count|| [[#Variable_length_integer|var_int]] || Number of var_ints below<br />
|-<br />
| 1+ || || [[#Variable_length_integer|var_int]] || The first value stored<br />
|-<br />
| 1+ || || [[#Variable_length_integer|var_int]] || The second value stored...<br />
|-<br />
| 1+ || || [[#Variable_length_integer|var_int]] || etc...<br />
|}<br />
<br />
=== Network address ===<br />
<br />
When a network address is needed somewhere, this structure is used. Network addresses are not prefixed with a timestamp or stream in the version message.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 8 || time || uint64 || the Time.<br />
|-<br />
| 4 || stream || uint32 || Stream number for this node<br />
|-<br />
| 8 || services || uint64_t || same service(s) listed in [[#version|version]]<br />
|-<br />
| 16 || IPv6/4 || char[16] || IPv6 address. IPv4 addresses are written into the message as a 16 byte [http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses IPv4-mapped IPv6 address]<br />
(12 bytes ''00 00 00 00 00 00 00 00 00 00 FF FF'', followed by the 4 bytes of the IPv4 address). Hidden Service addresses can be represented as an IPv6 address with a 48-bit routing prefix of fd87:d87e:eb43::48 under the Unique Local Address block (fc00::/7) with the remaining 10 bytes being the Base256 encoding of the Hidden Service address<br />
|-<br />
| 2 || port || uint16_t || port number<br />
|}<br />
<br />
=== Inventory Vectors ===<br />
<br />
Inventory vectors are used for notifying other nodes about objects they have or data which is being requested. Two rounds of SHA-512 are used, resulting in a 64 byte hash. Only the first 32 bytes are used; the remaining 32 bytes are ignored.<br />
<br />
Inventory vectors consist of the following data format:<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 32 || hash || char[32] || Hash of the object<br />
|}<br />
<br />
=== Envelope ===<br />
<br />
Bitmessage uses [https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme ECIES] to encrypt its messages. For more information see [[Encryption]]<br />
<br />
==== Plain Envelope ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 16 || IV || uchar[16] || Initialization Vector used for AES-256-CBC<br />
|-<br />
| 2 || elliptic curve || uint16_t || Elliptic Curve secp256k1. <span style="color:red">This is the NID (numerical identifier) 714 (0x02CA) assigned by OpenSSL to represent secp256k1</span><br />
|-<br />
| 2 || X length || uint16_t || Length of X component of public key R<br />
|-<br />
| X length || X || uchar[X length] || X component of public key R<br />
|-<br />
| 2 || Y length || uint16_t || Length of Y component of public key R<br />
|-<br />
| Y length || Y || uchar[Y length] || Y component of public key R<br />
|-<br />
| ? || encrypted || uchar[] || Cipher text<br />
|-<br />
| 32 || mac || uchar[32] || HMACSHA256 Message Authentication Code<br />
|}<br />
<br />
==== Tagged Envelope ====<br />
<br />
A tagged envelope is identical to an [[#Plain_Envelope|plain envelope]] but prepended with a tag. Tagged envelopes are only used by [[#v4_pubkey|v4 pubkeys]] and [[#v5 broadcast|v5 broadcasts]].<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 32 || tag || uchar[32] || The recipients tag<br />
|-<br />
| 1+ || envelope || [[#Plain_Envelope|plain_envelope]] ||<br />
|}<br />
<br />
<br />
== Enumerations and Flags ==<br />
<br />
=== Message Encodings ===<br />
<br />
{|class="wikitable"<br />
! Value !! Name !! Description<br />
|-<br />
| 0 || IGNORE || Any data with this number may be ignored. The sending node might simply be sharing its public key with you.<br />
|-<br />
| 1 || TRIVIAL|| UTF-8. No 'Subject' or 'Body' sections. Useful for simple strings of data, like URIs or magnet links.<br />
|-<br />
| 2 || SIMPLE || UTF-8. Uses 'Subject' and 'Body' sections. No MIME is used. <br />
<code>messageToTransmit = 'Subject:' + subject + '\n' + 'Body:' + message</code><br />
|-<br />
| 3 || EXTENDED || <span style="color:red">A data structure in bencode, then compressed with zlib. Null data type is encoded as an empty string, and booleans as an integer 0 (false) or 1 (true). Text fields are encoded using UTF-8. v5 and newer address versions MUST support this. Proposal, exact structure pending standardisation.</span><br />
|}<br />
<br />
Further values for the message encodings can be decided upon by the community. Any MIME or MIME-like encoding format, should they be used, should make use of Bitmessage's 8-bit bytes.<br />
<br />
=== Identity bitfield features ===<br />
<br />
{|class="wikitable"<br />
! Bit!! Name !! Description<br />
|-<br />
| 0 || undefined || The most significant bit at the beginning of the structure. Undefined<br />
|-<br />
| 1 || undefined || The next most significant bit. Undefined<br />
|-<br />
| ... || ... || ...<br />
|-<br />
| 30 || include_destination || Receiving node expects that the RIPE hash encoded in their address preceedes the encrypted message data of msg messages bound for them. <br />
|-<br />
| 31 || does_ack|| If true, the receiving node does send acknowledgements (rather than dropping them).<br />
|}<br />
<br />
=== Node services ===<br />
<br />
The following services are currently assigned:<br />
<br />
{|class="wikitable"<br />
! Value !! Name !! Description<br />
|-<br />
| 1 || NODE_NETWORK || This is a normal network node.<br />
|-<br />
| 2 || NODE_SSL || This node supports SSL/TLS in the current connect<br />
|}<br />
<br />
=== Object Types ===<br />
<br />
{|class="wikitable"<br />
! Value !! Name !! Description<br />
|-<br />
| 0 || [[#getpubkey|getpubkey]] ||<br />
|-<br />
| 1 || [[#pubkey|pubkey]] ||<br />
|-<br />
| 2 || [[#msg|msg]] || A msg or msg ack<br />
|-<br />
| 3 || [[#broadcast|broadcast]] ||<br />
|}<br />
<br />
=== Error Levels ===<br />
<br />
{|class="wikitable"<br />
! Value !! Name !! Description<br />
|-<br />
| 0 || WARNING ||<br />
|-<br />
| 1 || ERROR || <br />
|-<br />
| 2 || FATAL || A fatal or fatal-like error has occured. The connection usually terminated following this error.<br />
|}<br />
<br />
<br />
== Message types ==<br />
<br />
Undefined messages received on the wire must be ignored.<br />
<br />
=== error ===<br />
<span style="color:red">The only error PyBitmessage sends is a FATAL error when it receives a version message where the timestamp is out by more than hour from its own</span><br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || error level || [[#Variable_length_integer|var_int]] || The [[#Error_levels|error level]] of this error<br />
|-<br />
| 1+ || ban time || [[#Variable_length_integer|var_int]] || The length of time the emitting node will refuse connections from the receiving node<br />
|-<br />
| 1+ || inv_vector_length || [[#Variable_length_integer|var_int]] || The length of the inventory vector (max: 100) <span style="color:red">Inventory vectors are fixed length at 32 bytes. Why does the size need to specified? Perhaps this should be a boolean value to indicate the presence of an inventory vector instead?</span><br />
|-<br />
| inv_vector_length || inv_vecter || [[#Inventory Vectors|inv_vect]] || The inventory vector of the offending object this error relates to<br />
|-<br />
| 1+ || errorText || [[#Variable_length_string|var_str]] || The error text (max length: 1000)<br />
|}<br />
<br />
=== version ===<br />
<br />
When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No further communication is possible until both peers have exchanged their version. <span style="color:red">A PyBitmessage server responds with verack then version. A bmd server responds with version then verack</span><br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 4 || version || int32_t || Identifies protocol version being used by the node. The current protocol version is 3. Nodes should disconnect if the remote node's version is lower but continue with the connection if it is higher. <span style="color:red">What is the intent here?<span><br />
|-<br />
| 8 || services || uint64_t || bitfield of features to be enabled for this connection<br />
|-<br />
| 8 || timestamp || int64_t || standard UNIX timestamp in seconds<br />
|-<br />
| 26 || addr_recv || [[#Network_address|net_addr]] || The network address of the node receiving this message (not including the time or stream number)<br />
|-<br />
| 26 || addr_from || [[#Network_address|net_addr]] || The network address of the node emitting this message (not including the time or stream number and the ip itself is ignored by the receiver)<br />
|-<br />
| 8 || nonce || uint64_t || Random nonce used to detect connections to self.<br />
|-<br />
| 1+ || user_agent || [[#Variable_length_string|var_str]] || User Agent generally in the form of /Application:Version/ (max length: 5000)<br />
|-<br />
| 1+ || stream_numbers || [[#Variable_length_list_of_integers|var_int_list]] || The stream numbers that the emitting node is interested in. Sending nodes must not include more than 160,000 stream numbers.<br />
|}<br />
<br />
A "verack" packet shall be sent if the version packet was accepted. Once you have sent and received a verack messages with the remote node, send an addr message advertising up to 1,000 peers of which you are aware, and one or more inv messages advertising all of the valid objects of which you are aware.<br />
<br />
=== verack ===<br />
<br />
This message is sent in reply to [[#version|version]] and has no payload. The TCP timeout starts out at 20 seconds; after verack messages are exchanged, the timeout is raised to 10 minutes.<br />
<br />
If both sides announce that they support SSL, they MUST perform a SSL handshake immediately after they both send and receive verack. During this SSL handshake, the TCP client acts as a SSL client, and the TCP server acts as a SSL server. <span style="color:red">PyBitmessage v0.5.4 or later requires the AECDH-AES256-SHA cipher over TLSv1, and prefers the secp256k1 curve (but other curves may be accepted, depending on the version of python and OpenSSL used).</span><br />
<br />
=== addr ===<br />
<br />
Provide information on known nodes of the network. Only nodes that have been known to be on the network in the last 3 hours should be advertised. <span style="color:red">This command is easily abused and any entries should be treated as unreliable</span><br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || count || [[#Variable_length_integer|var_int]] || Number of address entries (max: 1,000)<br />
|-<br />
| 38 x count || list of net_addr || [[#Network_address|net_addr]][] || Address of other nodes on the network.<br />
|}<br />
<br />
=== inv ===<br />
<br />
Allows a node to advertise its knowledge of one or more objects.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || count || [[#Variable_length_integer|var_int]] || Number of inventory entries (max: 50,000)<br />
|-<br />
| 32 x count || list of inv_vect || [[Protocol specification#Inventory Vectors|inv_vect]][] || Inventory vectors<br />
|}<br />
<br />
=== getdata ===<br />
<br />
getdata is used in response to an [[#inv|inv]] message to retrieve the content of a specific object after filtering known elements.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || count || [[#Variable_length_integer|var_int]] || Number of inventory entries (max: 50,000)<br />
|-<br />
| 32 x count || list of inv_vect || [[#Inventory_Vectors|inv_vect]][] || Inventory vectors<br />
|}<br />
<span style="color:red">Current usage reveals getdata to only ever contain 1 entry</span><br />
<br />
=== object ===<br />
<br />
An object is a message which is shared throughout a stream. It is the only message which propagates; all others are only between two nodes. Objects have a type, like 'msg', or 'broadcast'. To be a valid object, the [[Proof of work|Proof Of Work]] must be done. The maximum allowable length of an object (not to be confused with the objectPayload) is 2<sup>18</sup> bytes (256 KiB).<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 8 || nonce || uint64_t || A nonce that satisfies the [[Proof of work|Proof Of Work]]<br />
|-<br />
| 8 || expiresTime || uint64_t || The "end of life" time of this object. Objects shall be shared with peers until its end-of-life time has been reached. The node should store the inventory vector of that object for some extra period of time to avoid reloading it from another node with a small time delay. The time may be no further than 28 days + 3 hours in the future.<br />
|-<br />
| 4 || objectType || uint32_t || The [[#Object_type_enum|object type]]. Nodes should relay objects even if they use an undefined object type.<br />
|-<br />
| 1+ || version || [[#Variable_length_integer|var_int]] || The object's version.<br />
|-<br />
| 1+ || stream number || [[#Variable_length_integer|var_int]] || The stream number in which this object may propagate<br />
|-<br />
| ? || objectPayload || uchar[] || This field varies depending on the object type; see below.<br />
|-<br />
|}<br />
<br />
<br />
== Object types ==<br />
<br />
Here are the payloads for various object types.<br />
<br />
=== getpubkey === <br />
<br />
When a node has the hash of a public key (from an address) but not the public key itself, it must send out a request for the public key.<br />
<br />
==== v2 and v3 getpubkey ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 20 || ripe || uchar[20] || The ripemd hash of the public key<br />
|}<br />
<br />
==== v4 getpubkey ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 32 || tag || uchar[32] || The tag derived from the address version, stream number, and ripe<br />
|}<br />
<br />
<br />
=== pubkey === <br />
<br />
==== v2 pubkey ====<br />
This is still in use and supported by current clients but ''new'' v2 addresses are not generated by clients.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 4 || [[#Pubkey_bitfield_features|behavior bitfield]] || uint32_t || A bitfield of optional behaviors and features that can be expected from the node receiving the message. <br />
|-<br />
| 64 || public signing key || uchar[64] || The ECC public key used for signing in uncompressed format without the point compression prefix<br />
|-<br />
| 64 || public encryption key || uchar[64] || The ECC public key used for encryption in uncompressed format without the point compression prefix<br />
|}<br />
<br />
==== v3 pubkey ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 132 || public keys || [[#v2_pubkey|v2 pubkey]] || This is the same three fields as a [[#v2_pubkey|v2 pubkey]]<br />
|-<br />
| 1+ || nonce_trials_per_byte || [[#Variable_length_integer|var_int]] || Used to calculate the difficulty target of messages accepted by this node. The higher this value, the more difficult the Proof of Work must be before this individual will accept the message. This number is the average number of nonce trials a node will have to perform to meet the Proof of Work requirement. 1000 is the network minimum so any lower values will be automatically raised to 1000. <br />
|-<br />
| 1+ || extra_bytes || [[#Variable_length_integer|var_int]] || Used to calculate the difficulty target of messages accepted by this node. The higher this value, the more difficult the Proof of Work must be before this individual will accept the message. This number is added to the data length to make sending small messages more difficult. 1000 is the network minimum so any lower values will be automatically raised to 1000.<br />
|-<br />
| 1+ || signature || [[#Variable_length_string|var_str]] || The ECDSA signature covering this structure prepended with the object header (excluding the nonce). <span style="color:red">The signature is actually two signed integers ''r'' and ''s'' encoded in ASN.1 according to DER</span><br />
|}<br />
<br />
==== v4 pubkey ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| ? || envelope || [[#Tagged_Envelope|tagged_envelope]] || Encrypted pubkey data<br />
|-<br />
|}<br />
<br />
A decrypted v4 pubkey is identical to a [[#v3_pubkey|v3 pubkey]] (except the version is 4).<br />
<br />
When version 4 pubkeys are created, most of the data in the pubkey is encrypted. This is done in such a way that only someone who has the Bitmessage address which corresponds to a pubkey can decrypt and use that pubkey. This prevents people from gathering pubkeys sent around the network and using the data from them to create messages to be used in spam or in flooding attacks. <br />
<br />
In order to encrypt the pubkey data, a double SHA-512 hash is calculated from the address version number, stream number, and ripe hash of the Bitmessage address that the pubkey corresponds to. The first 32 bytes of this hash are used to create a public and private key pair with which to encrypt and decrypt the pubkey data, using the same algorithm as message encryption (see [[Encryption]]). The remaining 32 bytes of this hash are added to the unencrypted part of the pubkey and used as a tag, as above. This allows nodes to determine which pubkey to decrypt when they wish to send a message. <br />
<br />
In PyBitmessage, the double hash of the address data is calculated using the python code below:<br />
<br />
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()<br />
<br />
<br />
=== msg ===<br />
<br />
Used for person-to-person messages.<br />
<br />
==== v1 msg ====<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| ? || envelope || [[#Plain_Envelope|plain_envelope]] || Encrypted msg data<br />
|}<br />
<br />
==== Decrypted msg ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || sender || [[#pubkey|pubkey]] || Sender's pubkey. A v4 pubkey should be not be encrypted<br />
|-<br />
| 20 || destination ripe || uchar[20] || The ripe hash of the public key of the receiver of the message<br />
|-<br />
| 1+ || encoding || [[#Variable_length_integer|var_int]] || [[#Message_Encodings|Message encoding]]<br />
|-<br />
| 1+ || message || [[#Variable_length_string|var_str]] || The message encoded as per encoding<br />
|-<br />
| 1+ || ack_data || [[#Variable_length_string|var_str]] || The acknowledgement data to be transmitted. This is a fully qualified [[#object|object]] with [[Proof of Work]] completed<br />
|-<br />
| 1+ || signature || [[#Variable_length_string|var_str]] || The ECDSA signature covering this structure prepended with the object header (excluding the nonce). <span style="color:red">The signature is actually two signed integers ''r'' and ''s'' encoded in ASN.1 according to DER</span><br />
|}<br />
<br />
==== msg ack ====<br />
<br />
A special form of msg used as an acknowledgement receipt. The objectType and version fields in the object header are set exactly the same as for a [[#v1 msg|v1 msg]]<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 32 || ack data || uchar[32] || A random sequence of bytes that the sender waits for as an indication that the recipient has received their msg<br />
|}<br />
<br />
<br />
=== broadcast ===<br />
<br />
Users who are subscribed to the sending address will see the message appear in their inbox. <br />
<br />
Pubkey objects and v5 broadcast objects are encrypted the same way: The data encoded in the sender's Bitmessage address is hashed twice. The first 32 bytes of the resulting hash constitutes the "private" encryption key and the last 32 bytes constitute a '''tag''' so that anyone listening can easily decide if this particular message is interesting. The sender calculates the public key from the private key and then encrypts the object with this public key. Thus anyone who knows the Bitmessage address of the sender of a broadcast or pubkey object can decrypt it. <br />
<br />
Having a broadcast version of 5 indicates that a tag is used which, in turn, is used when the sender's address version is >=4.<br />
<br />
==== v4 broadcast ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| ? || envelope || [[#Plain_Envelope|plain_envelope]] ||<br />
|}<br />
<br />
==== v5 broadcast ====<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| ? || envelope || [[#Tagged_Envelope|tagged_envelope]] ||<br />
|}<br />
<br />
==== Decrypted broadcast ====<br />
<br />
A decrypted broadcast is nearly identical to a decrypted msg. The decrypted broadcast does not have destination ripe field nor an acknowlegement field.<br />
<br />
{|class="wikitable"<br />
! Field Size !! Description !! Data type !! Comments<br />
|-<br />
| 1+ || sender || [[#pubkey|pubkey]] || Sender's pubkey. A v4 pubkey should be not be encrypted<br />
|-<br />
| 1+ || encoding || [[#Variable_length_integer|var_int]] || [[#Message_Encodings|Message encoding]]<br />
|-<br />
| 1+ || message || [[#Variable_length_string|var_str]] || The message encoded as per encoding<br />
|-<br />
| 1+ || signature || [[#Variable_length_string|var_str]] || The ECDSA signature covering this structure prepended with the object header (excluding the nonce). <span style="color:red">The signature is actually two signed integers ''r'' and ''s'' encoded in ASN.1 according to DER</span><br />
|}</div>Bmng-dev