iroha icon indicating copy to clipboard operation
iroha copied to clipboard

Remove genesis signing from Iroha

Open mversic opened this issue 1 year ago • 11 comments

Genesis should be signed offline and given to Iroha through config. This way no peer needs to know about genesis private key. The functionality to sign genesis (or any) transaction could be placed into kagami. Also this would remove the --submit-genesis from the start args because genesis could just be picked up through config

mversic avatar Jan 23 '24 07:01 mversic

This would also mean that genesis should be serialized exactly like a SignedTransaction. Which also means that executor field of the current genesis.json should be changed into Upgrade instruction

mversic avatar Jan 23 '24 07:01 mversic

after this is implemented @AlexStroke should test that we can bootstrap the network where multiple nodes submit genesis

mversic avatar Jan 23 '24 08:01 mversic

Currently we store genesis as JSON without any signature attached to it.

So i have few questions/concerns:

  1. How we are going to store signed genesis? JSON, Scale, ... Because atm peer is converting json to scale and only then sign it and send to other peers.
  2. Editing genesis might become more involved: we need to edit possibly scale and then resign it

Erigara avatar Jan 23 '24 08:01 Erigara

Currently we store genesis as JSON without any signature attached to it.

So i have few questions/concerns:

1. How we are going to store signed genesis? JSON, Scale, ...
   Because atm peer is converting json to scale and only then sign it and send to other peers.

2. Editing genesis might become more involved: we need to edit possibly scale and then resign it

I think we should store genesis as json, have kagami sign it and then place the signed one it somewhere where iroha will pick it up. The signed genesis can be encoded as SCALE

mversic avatar Jan 23 '24 08:01 mversic

Correct me if I am wrong. From the point of view of configuration, the change will be:

  • remove genesis.private_key parameter, leave only genesis.public_key and genesis.file
  • remove --submit-genesis CLI argument
  • no need to validate whether the peer is alone or not - it will submit the genesis anyways

0x009922 avatar Feb 20 '24 02:02 0x009922

Yes. Also multiple peers will be able to submit genesis

mversic avatar Feb 20 '24 04:02 mversic

also make sure to update commit_hook like in #4313

mversic avatar Feb 21 '24 07:02 mversic

what if peers have different genesis files but correctly signed with the expected private key? what if genesis.public_key is different, i.e. the same genesis file but signed with different key? what if both violations are present? that's obvious nothing is going to become committed in such a network but how this can be highlighted? or just as a point in FAQ/troubleshooting section of the docs section?

Mingela avatar Mar 27 '24 12:03 Mingela

what if peers have different genesis files but correctly signed with the expected private key?

we can't prevent that. We can pursue some resolution tactic but I don't think we should

what if genesis.public_key is different, i.e. the same genesis file but signed with different key?

every peer knows genesis public key so once they receive the genesis they will verify if it was indeed signed by the correct key. In other words, this cannot happen

mversic avatar Mar 27 '24 12:03 mversic

every peer knows genesis public key

I mean from their perspective it would be valid, imagine isolated sets of peers with distinct public key configured and corresponding genesis file attached

But generally the answer is clear, thanks

Mingela avatar Mar 27 '24 12:03 Mingela

I was scratching my head on this topic and also on the topic of chain-wide configuration (#4028). I have came to the following vision, and you are welcome to find flaws in it.

First of all, I incline towards having the genesis block provided to each peer before it even starts gossiping with other peers. Therefore, I am so far against the idea of starting a network with no blocks at all and then awaiting for it from a client. It has many complications:

  • Iroha Core needs to be written in a way than can handle both states - with the genesis block, and without it yet
  • Chain-wide config should be known before gossiping and validation of any transactions, since consensus is regulated by this config
  • Having an "initial" default executor which allows everything has no use case apart from handling this genesis-less situation, right?
  • If it is submitted as a first transaction, should it be submitted to all peers, or should a receiving peer broadcast it further?

Instead, I think it is simpler to continue with supplying the genesis block on Iroha startup.

So, here is my vision on how to solve multiple problems (remove genesis signing and make chain-wide config purely on-chain).

  1. Term: "Genesis Transaction" is just a SignedTransaction. However, it has the following properties:
    1. It's first instruction is Upgrade
    2. It's second instruction is Configure. While in all other cases Configure might contain only a subset of parameters, here it must have all parameters specified.
    3. It is submitted by all peers Implications:
    • Iroha Core doesn't need to assume any default values for config parameters
    • Iroha Core doesn't need Executor::Initial and other extra invariants only to handle the initial state of the network of not having the genesis yet.
    • If all peers have the same genesis, they can safely participate in consensus
  2. Configuration: make genesis section consist of public_key and signed_file parameters. The latter one points to a binary file containing SCALE-encoded SignedTransaction.
  3. iroha_genesis is not needed anymore. However, Kagami will still work with genesis.json format...
  4. Kagami: kagami genesis sign genesis.json --key-pair ... --out-file signed-genesis.scale command will help to transform a conveniently written genesis.json into a binary SignedTransaction. genesis.json should consist of these fields:
    • chain_id
    • configuration: fields to put into Configure ISI. Does not need to contain all instructions: although Genesis Transaction must contain a Configure ISI with all parameters, Kagami can put some default here.
    • executor_file: a file with a blob to put into Upgrade ISI
    • instructions: array of instructions
  5. Swarm:
    1. It's philosophy is that it doesn't accept any key pairs from a user, but generates everything inside (can get an optional --seed for reproducibility). Therefore, it cannot accept an already signed genesis, since it will also need to accept a public key of it. But that's not an issue!
    2. Another aspect of Swarm philosophy: it relies on our specific Docker images. Their property is that they have not only iroha binary compiled inside, but also iroha_client_cli and kagami.
    3. Therefore, Swarm can accept a convenient genesis.json, generate some key for it, and sign it within the Docker container via kagami.
    4. As one of the ways to do so, it can have an additional "genesis signing" service, which will sign the genesis.json and other peers can access it via volumes.
    5. Implication: We don't need to store the binary artifact of signed genesis in the repo. We still only store genesis.json and executor.wasm in the /configs/swarm. Clean work!

0x009922 avatar May 01 '24 04:05 0x009922

Verified that Iroha starts up as expected using scripts/test_env and through Docker files on this specific commit.

AlexStroke avatar Jun 13 '24 10:06 AlexStroke