Added PoW doc, separate pow_formula.rst and reference in protocol.rst

This commit is contained in:
Dmitri Bogomolov 2021-01-31 20:42:35 +02:00 committed by Lee Miller
parent c0657f61dd
commit 2b69288540
Signed by untrusted user: lee.miller
GPG Key ID: 4F97A5EA88F4AB63
3 changed files with 128 additions and 3 deletions

77
docs/pow.rst Normal file
View 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
View File

@ -0,0 +1,7 @@
.. math::
target = \frac{2^{64}}{{\displaystyle
nonceTrialsPerByte (payloadLength + payloadLengthExtraBytes + \frac{
TTL (payloadLength + payloadLengthExtraBytes)}{2^{16}})
}}

View File

@ -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
------------