bitcoin-image

Bitcoin SV Node software – Upgrade to v1.0.13 Release

You can view markdown formatted release notes here.

The 1.0.13 node release is a recommended upgrade from version 1.0.11.

Main features of this upgrade are:

  • Support for Miner ID specification v1.0., as well as for legacy versions v0.1, v0.2
  • Authenticated Connections handshake.
  • Enhanced P2P hdrsen message.

To take full advantage of Miner ID features, this release should be run in conjunction with Miner ID Generator 1.0.

The changes to NOMP are not available from the official NOMP website.

Miner ID

Miner ID is a cryptographic way for miners to declare that they created a particular block on the blockchain by adding information to the coinbase transaction in the block header.

The miner ID information can include data such as server endpoints and contact details, information which users need to be able to trust. It is important that a 3rd party who mines a block cannot pretend to be another miner.

The specification can be found at ‘https://github.com/bitcoin-sv-specs/brfc-minerid

Security Features

It is possible that the miner ID private key can become compromised (e.g. a disgruntled employee passes it onto a 3rd party). In this case, the miner ID specification provides a mechanism for rolling miner ID keys (private and public), or the complete revocation of miner ID keys (private and public). I.e. operations include:

  • Roll miner ID to a new value.
  • Forcibly roll miner ID to a new value using the revocation key (used for example if the miner ID key was already compromised and rolled away to a value not controlled by the legitimate owner of the miner ID)
  • Forcibly revoke all miner ID keys.

The user is directed to https://github.com/bitcoin-sv/minerid-reference for other operations and further details.

Miner ID Key Storage

  • No private key information is stored in the node.
  • The Miner ID private key is read/written and stored locally by the Miner ID Generator. Miners who have security concerns should use file permissions to restrict access to local Miner ID Generator files.
  • The Miner ID revocation key should be stored off-line so that it is not available to developers, and only supplied and used when it is needed.

New RPCs

The following RPCs have been introduced to the node as part of Miner ID work.

RPCs intended to be used by the Generator are:

  1. revokeminerid – revokes minerId public key specified in the request and sends out the P2P revokemid message to known peers.
  2. getmineridinfo – checks if the requested minerId public key is present in the Miner ID DB and returns its state along with related revocation public keys.

RPCs used by the Mining Software to communicate with Nodes from the mining pool:

  1. createminerinfotx – creates a miner-info transaction containing a miner-info output script specified in the request.
  2. replaceminerinfotx – replaces in-mempool miner-info transaction by a new one containing a new miner-info output script specified in the request.
  3. getminerinfotxid – returns in-mempool miner-info txid.
  4. createdatareftx – creates a data-ref transaction containing a dataRefs output script(s) specified in the request.
  5. getdatareftxid – returns in-mempool data-ref txid.

RPCs used by a mining node’s operator:

  1. rebuildminerids – forces a rebuild of the Miner ID DB and synchronises it to the blockchain.
  2. dumpminerids – returns details for all currently known miner IDs.
  3. makeminerinfotxsigningkey – creates a private BIP32 key used to sign miner-info and data-ref transactions.
  4. getminerinfotxfundingaddress – returns Base58 encoded BSV address generated from the private key and used to fund miner-info and data-ref transactions.
  5. setminerinfotxfundingoutpoint – sets miner-info funding outpoint to be used by miner-info and data-ref transactions.
  6. datarefindexdump – returns details for all currently stored miner-info and data-ref transactions from the dataRef index.
  7. datareftxndelete – deletes the specified miner-info or data-ref transaction from the dataRef index.

RPCs used by DARA functionality:

  1. addToConfiscationTxidWhitelist – adds a list of txids, of transactions to be whitelisted, as confiscation transactions.
  2. clearConfiscationWhitelist – removes all txid and txo entries from confiscation whitelist.
  3. queryConfiscationTxidWhitelist – returns an array containing information about whitelisted confiscation transactions.

revokemid P2P message format

A revokemid P2P message is used to notify other nodes that a miner ID has been revoked. The message means that a miner does not have to wait until it wins another block before it can notify other nodes.

Field SizeNameData TypeDescription
4versionuint32_tIdentifies MinerID protocol version
33revocationKeyuint8_t[33]The current revocation key ECDSA (secp256k1) public key represented in compressed form as a 33 byte hex string. It is required to verify the first signature defined in the revocationMessageSig field.
33minerIduint8_t[33]The miner’s current minerId ECDSA (secp256k1) public key represented in compressed form as a 33 byte hex string. It is required to verify the second signature defined in the revocationMessageSig field.
33revocationMessageuint8_t[33]Revocation message to be signed to certify the legitimate miner who wants to revoke past reputation

The field contains the compromised minerId public key (in the case of complete revocation it is the minerId public key defined by the initial Miner ID document).
variablerevocationMessageSiguint8_t[]The field defines two different signatures on the Hash256(revocationMessage) message digest.

sig1 := Sign(Hash256(revocationMessage), priv_revocationKey), where priv_revocationKey is the private key associated with the revocationKey public key sig2 := Sign(Hash256(revocationMessage), priv_minerId), where priv_minerId is the private key associated with the miner’s current minerId public key

sig1 and sig2 are 70-73 byte hex strings

sig1_length := sig1.length() sig2_length := sig2.length()

msgsig_part1 :=concat(sig1_length, sig1) msgsig_part2 :=concat(sig2_length, sig2)

revocationMessageSig := concat(msgsig_part1, msgsig_part2), where the data layout is: sig1_length|sig1|sig2_length|sig2

The above concatenations are done on the hex encoded bytes.

gethdrsen and hdrsen P2P messages

Remote peers can use P2P message_gethdrsen_to request block headers together with contents of coinbase transaction and its proof of inclusion plus any referenced miner-info transaction and its proof of inclusion. Headers with those transactions and proofs of inclusion are returned to the requesting peer in P2P message_hdrsen_. Peers can also request to receive block announcements in form of_hdrsen_P2P message. Primary users of this P2P message are SPV clients which may require simplified access to MinerID provided in coinbase transaction.

Field SizeNameData TypeDescription
1+countvar_intNumber of enriched block headers

May be 0 if no header matches parameters specified in gethdrsen message.

No more than 2000 enriched block headers are returned in a single message.

Since the contents of coinbase transactions can be large, maximum size of hdrsen message is limited to maximum packet size that was agreed on in protoconf message with maxRecvPayloadLength parameter (value is specified in peer configuration). The number of returned enriched block headers is reduced as needed to stay below this limit, but not below 1. This is so that one header requested by gethdrsen message can be returned even if limit imposed by maxRecvPayloadLength parameter is exceeded.

This limit is always honored if message is sent to announce new blocks (i.e. new blocks will not be announced with this message if the size of the message would exceed the limit).
Variesenriched block headersblock_header_en[]Enriched block headers (specified below)

Enriched block header is serialized in the format described below.

Field SizeNameData TypeDescription
81+block header fields (please see block header definition)variousSame fields as in block header returned by headers message. See: https://wiki.bitcoinsv.io/index.php/Peer-To-Peer_Protocol#headers

Note: Value of field txn_count (transaction count) in block header is typically set to 0 if header is not sent as part of block message (e.g. in headers message). Here the value of this field is set to actual transaction count if that information is available (i.e. if the block was already validated).
1no_more_headersboolBoolean value indicating if there are more block headers available after the current header.

This value only equals true (1) for header of the block that is currently a tip of the active chain as seen by the node that is sending the message.
1has_coinbase_databoolBoolean value indicating if current block header has additional coinbase data following this field. If this value equals false (0), this is the last field in the message.

This value may be equal to false if the message is sent as response to message_gethdrsen_and the node does not have the required data (e.g. if requested block is not yet fully validated, or if it was already pruned).

This value is always true if message is sent to announce new blocks.
variablecoinbase_txtxSerialized coinbase transaction.
variablecoinbase_merkle_prooftsc_merkle_proofMerkle proof in binary format according to standard TS 2020.010-31. See:https://tsc.bitcoinassociation.net/standards/merkle-proof-standardised-format/

Value offlagsfield is zero.

FieldstxOrIdandtargetcontain an ID of a coinbase transaction and a block hash, respectively.

Value ofindexfield is zero since the proof is for coinbase transaction which is always the first transaction in a block.

Value oftypefield is zero in everynodeelement innodesfield.
1has_miner_info_databoolBoolean value indicating if this block contains a miner-info transaction referenced by the coinbase transaction.
variableminer_info_txtxSerialized miner ID miner-info transaction.
variableminer_info_merkle_prooftsc_merkle_proofMerkle proof in binary format according to standard TS 2020.010-31. See:https://tsc.bitcoinassociation.net/standards/merkle-proof-standardised-format/

Value offlagsfield is zero.

FieldstxOrIdandtargetcontain an ID of a miner-info transaction and a block hash, respectively.

Value ofindexfield is the index of the miner-info transaction within the block.

Value oftypefield is zero in everynodeelement innodesfield.

Usage guidance

Existing SPV clients that wish to receive enriched headers can follow these guidelines when implementing the changes:

  • Send gethdrsen where previously you would have sent getheaders.
  • Send a sendhdrsen where previously you would have sent sendheaders and be prepared to receive any of the following to announce a block:
    • hdrsen
    • inv
  • If receiving an inv, fetch the enriched headers via gethdrsen from peer that sent the inv until you have the additional coinbase/proof information.

Authenticated Connections

An authentication challenge/response test is now performed between mining nodes when a connection is first established. If the nodes pass the challenge/response tests, the standard connection is elevated to an authenticated conenction. Two new P2P messages have been defined for this purpose.

Configuration Options

Parameters required to enable communication between the Node and the MID Generator are:

  • -mineridgeneratorurl – sets URL for communicating with the miner ID generator. Required to setup authenticated connections. For example: http://127.0.0.1:9002.
  • -mineridgeneratoralias – sets an alias used to identify our current miner ID in the generator. Required to setup authenticated connections.

authch P2P message format

The authch message starts the authentication handshake

Field SizeNameData TypeDescription
4versionint32_tThe message version, should be 0x01
4message_lengthuint32_tThe length of the payload
Variesmessageuint8_t[]The payload (random text)

authresp P2P message format

A recipient of the authch message should respond with an authresp message. See specification for further details.

Field SizeNameData TypeDescription
4public_key_lengthuint32_tThe length of the Miner ID public key
Variespublic_keyuint8_t[]The latest ECDSA Miner ID public key
8client_nonceuint64_tNonce (random text)
4signature_lengthuint32_tThe length of the signature
Variessignatureuint8_t[]Signature of message using latest Miner ID private key

getdata message

SPV clients will become aware that they need dataref transactions to fully reconstruct a coinbase document when they first see a new block header and the associated coinbase transaction containing the coinbase document. The node that sent the SPV client the block header must have also validated that block and so will have seen any dataref transactions contained in that block (plus any dataref transactions also contained in earlier blocks), and so will have those dataref transactions stored in its dataref index. The SPV client can therefore direct its requests for dataref transactions to the same node that sent it the block header.

Inventory vector new type

In order for SPV clients to request dataref transactions we specify here an extension to the getdata P2P message. We will introduce a new inventory type for getdata called MSG_DATAREF_TX with a value of 0x05 to indicate to the receiving node that the sender is requesting a dataref transaction. The items in the inventory vector within the getdata message are then in the standard format. I.e:

Field SizeNameData TypeDescription
4typeuint32_tThe type of the object being requested. In this case the value 0x05.
32hashchar[32]The hash of the dataref transaction requested.

If the requested dataref transaction(s) could not be found then a standard P2P notfound reply should be returned. Otherwise, a series of datareftx P2P messages (format shown below) should be sent back to the requester, one for each of the dataref transactions specified in the getdata request.

datareftx P2P message

Dataref transactions are returned in a new P2P datareftx message, the format of which is as follows:

Field SizeNameData TypeDescription
variabletxnchar[]The serialised dataref transaction in the standard transaction format as for the P2P tx message described here.
variablemerkle proofmerkle_proofA proof that the above dataref transaction is included in a block (see below for format).

The merkle_proof

The merkle proof contents format should follow the TSC standard described here:

Field SizeNameData TypeDescription
1flagscharSet to 0x00 to indicate this proof contains just the transaction ID, the target type is a block hash, and the proof type is a merkle branch.
1+transaction indexvariantTransaction index for the transaction this proof is for.
32txidchar[32]Txid for the dataref transaction this proof is for.
32targetchar[32]Hash of the block containing the dataref transaction.
1+node countvarintThe number of following hashes from the merkle branch.
variablenode listnode[]An array of node objects comprising the merkle branch for this proof. The format of the node object is as described in the standard (link above).

Deprecated version P2P Message Fields

The addr_from field in the version P2P message have been deprecated. This value is now directly extracted at the socket level.

Removed configuration settings

The config setting –allowunsolicitedaddr has been removed.

Selfish Mining

The Journal Block Assembler (JBA) has been modified so that once the block template exceeds a certain size, it begins to throttle the addition of further transactions and adds transactions that will be recent enough so that the block template will not be consider to be selfish.

New parameters have been added:

  • detectselfishmining – enables or disables selfish mining detection (default: true)
  • minblockmempooltimedifferenceselfish – the lowest time difference in sec between the last block and last mempool transaction for the block to be classified as selfishly mined (default: 60)
  • selfishtxpercentthreshold – percentage threshold of number of txs in mempool that are not included in received block for the block to be classified as selfishly mined (default: 10).
  • jbathrottlethreshold – After a new block has been found it can take a short while for the journaling block assembler to catch up and return a new candidate containing every transaction in the mempool. If this flag is 1, calling getminingcandidate will wait until the JBA has caught up and always return a candidate with every available transaction. If it is 0, calls to getminingcandidate will always return straight away but may occasionally only contain a subset of the available transactions from the mempool.

Support for Digital Asset Recovery Alert (DARA)

This release supports code for the reassignment of digital assets. 

A confiscation transaction is identified by the first transaction output being an OP_RETURN output which adopts the confiscation transaction protocol (See https://github.com/bitcoin-sv-specs/protocol/tree/master/updates) and contains a reference to identify the related ConfiscationOrder document. The complete Court order document is not embedded in the OP_RETURN data of the confiscation transaction because not all blockchains support a large payload. For example, the default data carrier size on BTC is 80 bytes.

Highlights of the feature

  1. Introduces support for confiscation transactions, which when explicitly whitelisted can spend consensus frozen TXOs without providing unlocking scripts.
  2. Outputs of a confiscation transaction can only be spent when they mature (CONFISCATION_MATURITY = 1000 blocks), similar to coinbase outputs.
    A flag to indicate that an output was created by a confiscation transaction is stored in the UTXO database and block undo files by the 32nd bit in the existing value that stores height + is_coinbase and is serialized as the VARINT data type. If this flag is set to 0,  the serialized value is exactly the same as before, which makes it backward compatible. However, if this flag is set to 1, the serialized value cannot be read by the previous versions of the node because it no longer fits in a 32 bit integer as was expected in previous versions. This is detected as a serialization exception, which results in stopping the node.
  3. Downgrading to the previous versions of the node is only possible if all of the following is true:
    1. There are no confiscation transactions in blocks on the active chain.
      If there are, these blocks will be incorrectly detected as invalid or the node will not work correctly due to the UTXO database incompatibilities.
    2. There are no whitelisted confiscation transactions in the database.
      If there are, their records in the database will result in an incorrect handling of consensus frozen TXOs.
      Before downgrading all whitelisted transactions should be removed from the database by calling clearConfiscationWhitelist RPC function.

Please refer to https://bitcoinsv.io for more details.

New RPCs

RPCs used by DARA functionality:

  1. addToConfiscationTxidWhitelist – adds a list of txids, of transactions to be whitelisted, as confiscation transactions.
  2. clearConfiscationWhitelist – removes all txid and txo entries from confiscation whitelist.
  3. queryConfiscationTxidWhitelist – returns an array containing information about whitelisted confiscation transactions.

Modified RPCs

RPCs modified by DARA functionality:

  1. clearBlacklists – a new optional parameter keepExistingPolicyEntries is added.
  2. gettxout – a new data field confiscation (a boolean flag) is added to the result to indicate if the given output is created by a confiscation transaction.

New configuration options

Configuration options added by DARA functionality:

  • -enableassumewhitelistedblockdepth – assumes confiscation transaction to be whitelisted if it is in block that is at least as deep under tip as specified by option assumewhitelistedblockdepth (default: false).
  • -assumewhitelistedblockdepth – sets minimal depth of block under tip at which confiscation transaction is assumed to be whitelisted (default: 6).

leveldb

The version of leveldb has been updated to version 1.23

Time locked transactions

A transaction accepted into the time-locked mempool can be replaced “for free”. An attacker can send a large amount of such transactions, one replacing another, forcing us to validate and propagate each of these transactions. This could consume all of our CPU power and/or bandwidth leading to DoS.

2 new config settings have been added:

mempoolnonfinalmaxreplacementrate – the maximum rate at which a transaction in the non-final mempool can be replaced by another updated transaction, expressed in transactions per hour. Default = 7200.
mempoolnonfinalmaxreplacementrateperiod – the period of time (in minutes) over which the maximum rate for non-final transactions is measured (see -mempoolnonfinalmaxreplacementrate above). Default = 60.

Safe-mode

The safe mode configuration settings safemodeminforklength has been changed from 3 to 6. This should reduce spurious safe mode activations.

Scaling Test Network reset

The Scaling Test Network (STN) has been reset at block height 7. This block has hash 000000001f15fe3dac966c6bb873c63348ca3d877cd606759d26bd9ad41e5545.

Other changes

Other changes include various enhancements and fixes to functional tests, and improvements to logging including

  • logging the reason a consolidation transaction is rejected.
  • logging messages whenever the mapAskFor max size limit is exceeded.
profile-icon
Reporter
Bitcoin Association
The BSV Maintainer