mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-11-27 10:28:21 +00:00
370 lines
13 KiB
Plaintext
370 lines
13 KiB
Plaintext
|
---------------------------------------------
|
||
|
BIP: 22
|
||
|
Title: getblocktemplate - Fundamentals
|
||
|
Author: Luke Dashjr <luke+bip22@dashjr.org>
|
||
|
Status: Accepted
|
||
|
Type: Standards Track
|
||
|
Created: 2012-02-28
|
||
|
---------------------------------------------
|
||
|
|
||
|
[[abstract]]
|
||
|
Abstract
|
||
|
~~~~~~~~
|
||
|
|
||
|
This BIP describes a new JSON-RPC method for "smart" Bitcoin miners and
|
||
|
proxies. Instead of sending a simple block header for hashing, the
|
||
|
entire block structure is sent, and left to the miner to (optionally)
|
||
|
customize and assemble.
|
||
|
|
||
|
[[specification]]
|
||
|
Specification
|
||
|
~~~~~~~~~~~~~
|
||
|
|
||
|
[[block-template-request]]
|
||
|
Block Template Request
|
||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
|
||
|
A JSON-RPC method is defined, called "getblocktemplate". It accepts
|
||
|
exactly one argument, which MUST be an Object of request parameters. If
|
||
|
the request parameters include a "mode" key, that is used to explicitly
|
||
|
select between the default "template" request or a
|
||
|
link:bip-0023.mediawiki#Block_Proposal["proposal"].
|
||
|
|
||
|
Block template creation can be influenced by various parameters:
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|colspan=4|template request
|
||
|
|Key |Required |Type |Description
|
||
|
|
||
|
|capabilities a| |Array of Strings |SHOULD contain a list of the
|
||
|
following, to indicate client-side support:
|
||
|
#Optional:_Long_Polling["longpoll"], "coinbasetxn", "coinbasevalue",
|
||
|
link:bip-0023.mediawiki#Block_Proposal["proposal"],
|
||
|
link:bip-0023.mediawiki#Logical_Services["serverlist"], "workid", and
|
||
|
any of the link:bip-0023.mediawiki#Mutations[mutations]
|
||
|
|
||
|
|mode a| |String |MUST be "template" or omitted
|
||
|
|=======================================================================
|
||
|
|
||
|
getblocktemplate MUST return a JSON Object containing the following
|
||
|
keys:
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|colspan=4| template
|
||
|
|Key |Required |Type |Description
|
||
|
|
||
|
|bits a| |String |the compressed difficulty in hexadecimal
|
||
|
|
||
|
|curtime a| |Number |the current time as seen by the server (recommended
|
||
|
for block time) - note this is not necessarily the system clock, and
|
||
|
must fall within the mintime/maxtime rules
|
||
|
|
||
|
|height a| |Number |the height of the block we are looking for
|
||
|
|
||
|
|previousblockhash a| |String |the hash of the previous block, in
|
||
|
big-endian hexadecimal
|
||
|
|
||
|
|sigoplimit a| |Number |number of sigops allowed in blocks
|
||
|
|
||
|
|sizelimit a| |Number |number of bytes allowed in blocks
|
||
|
|
||
|
|transactions a| |Array of Objects |Objects containing
|
||
|
link:#Transactions_Object_Format[information for Bitcoin transactions]
|
||
|
(excluding coinbase)
|
||
|
|
||
|
|version a| |Number |always 1 or 2 (at least for bitcoin) - clients MUST
|
||
|
understand the implications of the version they use (eg, comply with
|
||
|
link:bip-0034.mediawiki[BIP 0034] for version 2)
|
||
|
|
||
|
|coinbaseaux a| |Object |data that SHOULD be included in the coinbase's
|
||
|
scriptSig content. Only the values (hexadecimal byte-for-byte) in this
|
||
|
Object should be included, not the keys. This does not include the block
|
||
|
height, which is required to be included in the scriptSig by
|
||
|
link:bip-0034.mediawiki[BIP 0034]. It is advisable to encode values
|
||
|
inside "PUSH" opcodes, so as to not inadvertantly expend SIGOPs (which
|
||
|
are counted toward limits, despite not being executed).
|
||
|
|
||
|
|coinbasetxn a| |Object |link:#Transactions_Object_Format[information
|
||
|
for coinbase transaction]
|
||
|
|
||
|
|coinbasevalue a| |Number |total funds available for the coinbase (in
|
||
|
Satoshis)
|
||
|
|
||
|
|workid a| |String |if provided, this value must be returned with
|
||
|
results (see link:#Block_Submission[Block Submission])
|
||
|
|=======================================================================
|
||
|
|
||
|
[[transactions-object-format]]
|
||
|
Transactions Object Format
|
||
|
++++++++++++++++++++++++++
|
||
|
|
||
|
The Objects listed in the response's "transactions" key contains these
|
||
|
keys:
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|colspan=3|template "transactions" element
|
||
|
|Key |Type |Description
|
||
|
|
||
|
|data |String |transaction data encoded in hexadecimal (byte-for-byte)
|
||
|
|
||
|
|depends |Array of Numbers |other transactions before this one (by
|
||
|
1-based index in "transactions" list) that must be present in the final
|
||
|
block if this one is; if key is not present, dependencies are unknown
|
||
|
and clients MUST NOT assume there aren't any
|
||
|
|
||
|
|fee |Number |difference in value between transaction inputs and outputs
|
||
|
(in Satoshis); for coinbase transactions, this is a negative Number of
|
||
|
the total collected block fees (ie, not including the block subsidy); if
|
||
|
key is not present, fee is unknown and clients MUST NOT assume there
|
||
|
isn't one
|
||
|
|
||
|
|hash |String |hash/id encoded in little-endian hexadecimal
|
||
|
|
||
|
|required |Boolean |if provided and true, this transaction must be in
|
||
|
the final block
|
||
|
|
||
|
|sigops |Number |total number of SigOps, as counted for purposes of
|
||
|
block limits; if key is not present, sigop count is unknown and clients
|
||
|
MUST NOT assume there aren't any
|
||
|
|=======================================================================
|
||
|
|
||
|
Only the "data" key is required, but servers should provide the others
|
||
|
if they are known.
|
||
|
|
||
|
[[block-submission]]
|
||
|
Block Submission
|
||
|
^^^^^^^^^^^^^^^^
|
||
|
|
||
|
A JSON-RPC method is defined, called "submitblock", to submit potential
|
||
|
blocks (or shares). It accepts two arguments: the first is always a
|
||
|
String of the hex-encoded block data to submit; the second is an Object
|
||
|
of parameters, and is optional if parameters are not needed.
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|colspan=3|submitblock parameters (2nd argument)
|
||
|
|Key |Type |Description
|
||
|
|
||
|
|workid |String |if the server provided a workid, it MUST be included
|
||
|
with submissions
|
||
|
|=======================================================================
|
||
|
|
||
|
This method MUST return either null (when a share is accepted), a String
|
||
|
describing briefly the reason the share was rejected, or an Object of
|
||
|
these with a key for each merged-mining chain the share was submitted
|
||
|
to.
|
||
|
|
||
|
[[optional-long-polling]]
|
||
|
Optional: Long Polling
|
||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|template request
|
||
|
|Key |Type |Description
|
||
|
|
||
|
|capabilities |Array of Strings |miners which support long polling
|
||
|
SHOULD provide a list including the String "longpoll"
|
||
|
|
||
|
|longpollid |String |"longpollid" of job to monitor for expiration;
|
||
|
required and valid only for long poll requests
|
||
|
|=======================================================================
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|template
|
||
|
|Key |Type |Description
|
||
|
|
||
|
|longpollid |String |identifier for long poll request; MUST be omitted
|
||
|
if the server does not support long polling
|
||
|
|
||
|
|longpolluri |String |if provided, an alternate URI to use for long poll
|
||
|
requests
|
||
|
|
||
|
|submitold |Boolean |only relevant for long poll responses: indicates if
|
||
|
work received prior to this response remains potentially valid (default)
|
||
|
and should have its shares submitted; if false, the miner may wish to
|
||
|
discard its share queue
|
||
|
|=======================================================================
|
||
|
|
||
|
If the server supports long polling, it MUST include a "longpollid" key
|
||
|
in block templates, and it MUST be unique for each event: any given
|
||
|
"longpollid" should check for only one condition and not be reused. For
|
||
|
example, a server which has a long poll wakeup only for new blocks might
|
||
|
use the previous block hash. However, clients should not assume the
|
||
|
"longpollid" has any specific meaning. It MAY supply the "longpolluri"
|
||
|
key with a relative or absolute URI, which MAY specify a completely
|
||
|
different resource than the original connection, including port number.
|
||
|
If "longpolluri" is provided by the server, clients MUST only attempt to
|
||
|
use that URI for longpoll requests.
|
||
|
|
||
|
Clients MAY start a longpoll request with a standard JSON-RPC request
|
||
|
(in the case of HTTP transport, POST with data) and same authorization,
|
||
|
setting the "longpollid" parameter in the request to the value provided
|
||
|
by the server.
|
||
|
|
||
|
This request SHOULD NOT be processed nor answered by the server until it
|
||
|
wishes to replace the current block data as identified by the
|
||
|
"longpollid". Clients SHOULD make this request with a very long request
|
||
|
timeout and MUST accept servers sending a partial response in advance
|
||
|
(such as HTTP headers with "chunked" Transfer-Encoding), and only
|
||
|
delaying the completion of the final JSON response until processing.
|
||
|
|
||
|
Upon receiving a completed response:
|
||
|
|
||
|
* Only if "submitold" is provided and false, the client MAY discard the
|
||
|
results of past operations and MUST begin working on the new work
|
||
|
immediately.
|
||
|
* The client SHOULD begin working on the new work received as soon as
|
||
|
possible, if not immediately.
|
||
|
* The client SHOULD make a new request to the same long polling URI.
|
||
|
|
||
|
If a client receives an incomplete or invalid response, it SHOULD retry
|
||
|
the request with an exponential backoff. Clients MAY implement this
|
||
|
backoff with limitations (such as maximum backoff time) or any algorithm
|
||
|
as deemed suitable. It is, however, forbidden to simply retry
|
||
|
immediately with no delay after more than one failure. In the case of a
|
||
|
"Forbidden" response (for example, HTTP 403), a client SHOULD NOT
|
||
|
attempt to retry without user intervention.
|
||
|
|
||
|
[[optional-template-tweaking]]
|
||
|
Optional: Template Tweaking
|
||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|template request
|
||
|
|Key |Type |Description
|
||
|
|
||
|
|sigoplimit |Number or Boolean |maximum number of sigops to include in
|
||
|
template
|
||
|
|
||
|
|sizelimit |Number or Boolean |maximum number of bytes to use for the
|
||
|
entire block
|
||
|
|
||
|
|maxversion |Number |highest block version number supported
|
||
|
|=======================================================================
|
||
|
|
||
|
For "sigoplimit" and "sizelimit", negative values and zero are offset
|
||
|
from the server-determined block maximum. If a Boolean is provided and
|
||
|
true, the default limit is used; if false, the server is instructed not
|
||
|
to use any limits on returned template. Servers SHOULD respect these
|
||
|
desired maximums, but are NOT required to: clients SHOULD check that the
|
||
|
returned template satisfies their requirements appropriately.
|
||
|
|
||
|
[[appendix-example-rejection-reasons]]
|
||
|
Appendix: Example Rejection Reasons
|
||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
|
||
|
Possible reasons a share may be rejected include, but are not limited
|
||
|
to:
|
||
|
|
||
|
[cols="",options="header",]
|
||
|
|=======================================================================
|
||
|
|colspan=2| share rejection reasons
|
||
|
|Reason |Description
|
||
|
|
||
|
|bad-cb-flag |the server detected a feature-signifying flag that it does
|
||
|
not allow
|
||
|
|
||
|
|bad-cb-length |the coinbase was too long (bitcoin limit is 100 bytes)
|
||
|
|
||
|
|bad-cb-prefix |the server only allows appending to the coinbase, but it
|
||
|
was modified beyond that
|
||
|
|
||
|
|bad-diffbits |"bits" were changed
|
||
|
|
||
|
|bad-prevblk |the previous-block is not the one the server intends to
|
||
|
build on
|
||
|
|
||
|
|bad-txnmrklroot |the block header's merkle root did not match the
|
||
|
transaction merkle tree
|
||
|
|
||
|
|bad-txns |the server didn't like something about the transactions in
|
||
|
the block
|
||
|
|
||
|
|bad-version |the version was wrong
|
||
|
|
||
|
|duplicate |the server already processed this block data
|
||
|
|
||
|
|high-hash |the block header did not hash to a value lower than the
|
||
|
specified target
|
||
|
|
||
|
|rejected |a generic rejection without details
|
||
|
|
||
|
|stale-prevblk |the previous-block is no longer the one the server
|
||
|
intends to build on
|
||
|
|
||
|
|stale-work |the work this block was based on is no longer accepted
|
||
|
|
||
|
|time-invalid |the time was not acceptable
|
||
|
|
||
|
|time-too-new |the time was too far in the future
|
||
|
|
||
|
|time-too-old |the time was too far in the past
|
||
|
|
||
|
|unknown-user |the user submitting the block was not recognized
|
||
|
|
||
|
|unknown-work |the template or workid could not be identified
|
||
|
|=======================================================================
|
||
|
|
||
|
[[motivation]]
|
||
|
Motivation
|
||
|
~~~~~~~~~~
|
||
|
|
||
|
bitcoind's JSON-RPC server can no longer support the load of generating
|
||
|
the work required to productively mine Bitcoin, and external software
|
||
|
specializing in work generation has become necessary. At the same time,
|
||
|
new independent node implementations are maturing to the point where
|
||
|
they will also be able to support miners.
|
||
|
|
||
|
A common standard for communicating block construction details is
|
||
|
necessary to ensure compatibility between the full nodes and work
|
||
|
generation software.
|
||
|
|
||
|
[[rationale]]
|
||
|
Rationale
|
||
|
~~~~~~~~~
|
||
|
|
||
|
Why not just deal with transactions as hashes (txids)?
|
||
|
|
||
|
* Servers might not have access to the transaction database, or miners
|
||
|
may wish to include transactions not broadcast to the network as a
|
||
|
whole.
|
||
|
* Miners may opt not to do full transaction verification, and may not
|
||
|
have access to the transaction database on their end.
|
||
|
|
||
|
What is the purpose of "workid"?
|
||
|
|
||
|
* If servers allow all mutations, it may be hard to identify which job
|
||
|
it is based on. While it may be possible to verify the submission by its
|
||
|
content, it is much easier to compare it to the job issued. It is very
|
||
|
easy for the miner to keep track of this. Therefore, using a "workid" is
|
||
|
a very cheap solution to enable more mutations.
|
||
|
|
||
|
Why should "sigops" be provided for transactions?
|
||
|
|
||
|
* Due to the link:bip-0016.mediawiki[BIP 0016] changes regarding rules
|
||
|
on block sigops, it is impossible to count sigops from the transactions
|
||
|
themselves (the sigops in the scriptCheck must also be included in the
|
||
|
count).
|
||
|
|
||
|
[[reference-implementation]]
|
||
|
Reference Implementation
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
* https://gitorious.org/bitcoin/eloipool[Eloipool (server)]
|
||
|
* http://gitorious.org/bitcoin/libblkmaker[libblkmaker (client)]
|
||
|
* https://github.com/bitcoin/bitcoin/pull/936/files[bitcoind (minimal
|
||
|
server)]
|
||
|
|
||
|
[[see-also]]
|
||
|
See Also
|
||
|
~~~~~~~~
|
||
|
|
||
|
* link:bip-0023.mediawiki[BIP 23: getblocktemplate - Pooled Mining]
|
||
|
|