Commit 75cd317d authored by Chris Zumbrunn's avatar Chris Zumbrunn
Browse files

Added proposal to extend block headers with creatorSignature as FIP-0005

parent 9b185db5
......@@ -16,3 +16,4 @@ If you have any questions on how to proceed with a new or existing proposal, ple
| [0002](proposals/ | 2019-01-17 | Stable price algorithm close to the market | Sebastian Gampe | Distribution<br>(FreeVision) | Markets | Active |
| [0003](proposals/ | 2019-03-18 | Fairo price reference | Chris Zumbrunn | Distribution | Markets | Active |
| [0004](proposals/ | 2019-03-18 | WFAIR Wrapped Faircoin | Xuann ( | Distribution | Markets | Funding
| [0005](proposals/ | 2020-04-30 | Extend block headers with creatorSignature | Yoshi Jäger | Core | Blockchain | Active
FIP: 0005
Title: Extend block headers with creatorSignature
Author: Yoshi Jäger
Status: Active
Type: Core
Module: Blockchain
Created: 2020-04-30
Updated: 2020-04-30
Scheduled: 2020-05-01
## Abstract
The Extend block headers PR provides the necessary changes that extend the regular block header message by a field called creatorSignature, which is usually only available in full block messages. By extending the faircoin protocol with this message type, the complexity of validating block header messages drastically decreases!
## Motivation
Instead of querying regular block header messages, so-called lightweight nodes (SPV validation nodes) will now be able to request extended block headers **that can be validated on-the-fly**.
## Backwards compatibility
The Extend block headers PR extends the protocol such that the existing protocol commands don't break (fully backward compatible)
## Rationale
Regular block header messages contain the following fields:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
nVersion = this->nVersion;
The fields containing hashes (hashPrevBlock, hashMerkleRoot and hashPayload) do not allow to validate the creation of the block.
A malicious node, for instance, could flood you with header messages of non-existing blocks and there would be no way to determine the integrity of those headers.
## Specification
By adding the 64-byte field `creatorSignature` to the response, the receiver of these messages can validate them on-the-fly by:
1. Calculating the double SHA256 hash of the non-extended header message (108 byte)
2. Retrieving the public key of `nCreatorId`
3. Validating the `creatorSignature` using the calculated hash with the retrieved public key
### Side notes on SPV validation
The SPV validation works almost the same as in Bitcoin, except that there is no PoW hash that can used for validation. In faircoin there are small differences when it comes to trust:
In order to validate the blockchain a faircoin lightweight client needs to
1. know the genesis block, implicitly trusting the creator's public key.
2. request the extended headers repeatedly and validate them with the procedure described above
3. requesting the full blocks of all header messages that have the `CVN_PAYLOAD` (1<<9) bit.
- The full blocks have a list of all signer's IDs and public keys in it's cvn payload
- The lightweight node needs to parse these and keep an internal list of these keys (`cvn_list`).
- Additionally, the lightweight node may validate the chainMultiSig field by following the steps described in this [document]( This adds an extra layer of security.
- A lightweight client may also request the full blocks in case the `CHAIN_PARAMETERS_PAYLOAD` bit is set in order to retrieve the values of dynamic chain parameters.
4. repeating the steps 2-3 until the lightweight client reaches a date ca. one week prior the first wallet seed could have been created
5. From that point on, only use `getblocks` instead `getheaders`, which will enable transaction messages
6. Validate tx messages with _merkleTree_ technology
7. Repeatedly call `getblocks` until we receive less than 500 headers.
8. Upon that point, we are fully synced. Listen to tx and block messages
### Security measures
1. Like with Bitcoin, never rely on one single node. Always use multiple nodes in order to sync your client
2. If the `cvn_list` contains multiple entities, the block signer is simply not allowed to sign two subsequent blocks unless the `cvn_list` contains just one entity. If the cvn_list contains multiple entities and subsequent header messages were signed by the same creator, the client should again request the full blocks and check the other signatures and fields, such as `vMissingSignerIds`.
### Implementation notes
Further notes regarding the with creatorSignature extended headers as implements it:
1. The `CBlockIndex` and `CDiskBlockIndex` have been extended by the field `creatorSignature`. This allows a node to respond quickly to the requests of a lightweight client as they don't have to repeatedly read the blocks from disk. Their constructors were altered so that the `creatorSignature` field can be passed as a parameter.
2. The methods AcceptBlockHeader, AddToBlockIndex have been altered the same way.
3. `CExtendedBlockHeader` class was created
4. A method has been added to the `CBlockIndex` class that allows the creation of the proposed extended headers.
5. Three message types have been added: `GETHEADERS_SIGNED` (`getheaders+`), `HEADERS_SIGNED` (`headers+`) and `MERKLEBLOCK_SIGNED` (`merkleblk+`). The first is the request command, the second represents the response and the third requests filtered _extended_ blocks and it's transactions (if any)
6. A message handler was added that has the responsibility to respond with the `CExtendedBlockHeader` instances.
7. A copy constructor was added to `poc_storage` and `CSchnorrSig`
8. The protocol version was increased to `92001`
9. CExtendedMerkleTree class was added
10. INV_TYPE extended filtered block was added that will be used to respond with extended merkleblocks
I am not saying this is the best way to extend the protocol. Neither am I saying that this PR is perfect. This way of extending the protocol is probably the easiest and most placative way to add the signature field to the responses. One alternative I can think of is adding a `getdata` command, that requests the `creatorSignature` data for a bunch of blocks using locators. However, the current PR simplifies the process of SPV, because existing SPV wallets can still use their sync procedures. Only the underlying protocol identifiers and parsers have to be changed.
Please, if somebody can improve or comment on this PR, feel free to do so! :-)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment