Adding Protocol specification to docs (WIP) #1727
77
docs/pow.rst
Normal file
77
docs/pow.rst
Normal file
|
@ -0,0 +1,77 @@
|
|||
Proof of work
|
||||
=============
|
||||
|
||||
This page describes Bitmessage's Proof of work ("POW") mechanism as it exists in
|
||||
Protocol Version 3. In this document, hash() means SHA512(). SHA512 was chosen
|
||||
as it is widely supported and so that Bitcoin POW hardware cannot trivially be
|
||||
used for Bitmessage POWs. The author acknowledges that they are essentially the
|
||||
same algorithm with a different key size.
|
||||
|
||||
Both ``averageProofOfWorkNonceTrialsPerByte`` and ``payloadLengthExtraBytes``
|
||||
are set by the owner of a Bitmessage address. The default and minimum for each
|
||||
is 1000. (This is the same as difficulty 1. If the difficulty is 2, then this
|
||||
value is 2000). The purpose of ``payloadLengthExtraBytes`` is to add some extra
|
||||
weight to small messages.
|
||||
|
||||
Do a POW
|
||||
--------
|
||||
|
||||
Let us use a ``msg`` message as an example::
|
||||
|
||||
payload = embeddedTime + encodedObjectVersion + encodedStreamNumber + encrypted
|
||||
|
||||
``payloadLength``
|
||||
the length of payload, in bytes, + 8
|
||||
(to account for the nonce which we will append later)
|
||||
``TTL``
|
||||
the number of seconds in between now and the object expiresTime.
|
||||
|
||||
.. include:: pow_formula.rst
|
||||
|
||||
::
|
||||
|
||||
initialHash = hash(payload)
|
||||
|
||||
start with ``trialValue = 99999999999999999999``
|
||||
|
||||
also start with ``nonce = 0`` where nonce is 8 bytes in length and can be
|
||||
hashed as if it is a string.
|
||||
|
||||
::
|
||||
|
||||
while trialValue > target:
|
||||
nonce = nonce + 1
|
||||
resultHash = hash(hash( nonce || initialHash ))
|
||||
trialValue = the first 8 bytes of resultHash, converted to an integer
|
||||
|
||||
When this loop finishes, you will have your 8 byte nonce value which you can
|
||||
prepend onto the front of the payload. The message is then ready to send.
|
||||
|
||||
Check a POW
|
||||
-----------
|
||||
|
||||
Let us assume that ``payload`` contains the payload for a msg message (the nonce
|
||||
down through the encrypted message data).
|
||||
|
||||
``nonce``
|
||||
the first 8 bytes of payload
|
||||
``dataToCheck``
|
||||
the ninth byte of payload on down (thus it is everything except the nonce)
|
||||
|
||||
::
|
||||
|
||||
initialHash = hash(dataToCheck)
|
||||
|
||||
resultHash = hash(hash( nonce || initialHash ))
|
||||
|
||||
``POWValue``
|
||||
the first eight bytes of resultHash converted to an integer
|
||||
``TTL``
|
||||
the number of seconds in between now and the object ``expiresTime``.
|
||||
|
||||
.. include:: pow_formula.rst
|
||||
|
||||
If ``POWValue`` is less than or equal to ``target``, then the POW check passes.
|
||||
|
||||
|
||||
|
7
docs/pow_formula.rst
Normal file
7
docs/pow_formula.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
.. math::
|
||||
|
||||
target = \frac{2^{64}}{{\displaystyle
|
||||
nonceTrialsPerByte (payloadLength + payloadLengthExtraBytes + \frac{
|
||||
TTL (payloadLength + payloadLengthExtraBytes)}{2^{16}})
|
||||
}}
|
|
@ -289,12 +289,53 @@ object
|
|||
|
||||
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 must
|
||||
be done. The maximum allowable length of an object (not to be confused with the
|
||||
objectPayload) is |2^18| bytes.
|
||||
type, like 'msg', or 'broadcast'. To be a valid object, the
|
||||
:doc:`pow` must be done. The maximum allowable length of an object
|
||||
(not to be confused with the ``objectPayload``) is |2^18| bytes.
|
||||
|
||||
.. |2^18| replace:: 2\ :sup:`18`\
|
||||
|
||||
.. list-table:: Message structure
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
|
||||
* - Field Size
|
||||
- Description
|
||||
- Data type
|
||||
- Comments
|
||||
* - 8
|
||||
- nonce
|
||||
- uint64_t
|
||||
- Random nonce used for the :doc:`pow`
|
||||
* - 8
|
||||
- expiresTime
|
||||
- uint64_t
|
||||
- The "end of life" time of this object (be aware, in version 2 of the
|
||||
protocol this was the generation time). 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.
|
||||
* - 4
|
||||
- objectType
|
||||
- uint32_t
|
||||
- Four values are currently defined: 0-"getpubkey", 1-"pubkey", 2-"msg",
|
||||
3-"broadcast". All other values are reserved. Nodes should relay objects
|
||||
even if they use an undefined object type.
|
||||
* - 1+
|
||||
- version
|
||||
- var_int
|
||||
- The object's version. Note that msg objects won't contain a version
|
||||
until Sun, 16 Nov 2014 22:00:00 GMT.
|
||||
* - 1+
|
||||
- stream number
|
||||
- var_int
|
||||
- The stream number in which this object may propagate
|
||||
* - ?
|
||||
- objectPayload
|
||||
- uchar[]
|
||||
- This field varies depending on the object type; see below.
|
||||
|
||||
|
||||
Object types
|
||||
------------
|
||||
|
|
Reference in New Issue
Block a user