6

I've seen in some guides suggesting to set Session Keys for validating. My concepts of session keys are that they are an amalgation of 4 keys, that will be used instead of the stash or controller keys on a validator node. However my confusion begins when I query the rotateKeys() rpc from author ( I don't know what author is or where this function is defined, please include an explanation for this in your answer as well ), I get a long key like this :

0x87d0bce7ee8e3279674e9a91c4255379592ab5b24ab2bcf9438719d0b08013f0de6b77179766746c767e9fe547d6a57936bbd0846a20b21acd6f75f5fe779f5a6861fae2c2ec3aa460d4559c755d12b4c9186133b8eee66162369348aa7f180afcc75d5a6f0e17f69e8e4c9232ae24b980a230bbe06b1d4ff87ed35985cec04c

which is different on every call. Can someone explain what is going on? Where are these keys coming from? Are they random concats of a ed25519 and 3 sr25519, if my sessionKeys struct has 4 keys just like polkadot?

Am I signing a random key with my controller account and then letting my node use that key for validation (grandpa, Imonline heartbeats, babe authorship, etc?)

1 Answer 1

5

I've seen in some guides suggesting to set Session Keys for validating. My concepts of session keys are that they are an amalgation of 4 keys, that will be used instead of the stash or controller keys on a validator node.

In the Polkadot wiki session key is defined here as "Hot keys that are used for performing network operations by validators".

In the Substrate repository here it shows that these "hot" keys for each authority/validator from a chain specification may be included as session keys in its genesis configuration, and they only include the grandpa, babe, imonline, and authority discovery keys, but not its "cold" stash key or the "hot" controller key. Grandpa are of ed25519 keypair type, whilst the others are sr25519.

If that chain was using aura instead of babe (for example when running a parachain), then the aura key would be included instead.

The stash and controller keys need to be endowed with a balance above the existential deposit, as the controller needs it to pay transaction fees such as bonding the stash to the controller and setting a reward destination, setting the session keys and validator settings with the controller, and loading the session keys into the keystore of the validator node.

However my confusion begins when I query the rotateKeys() rpc from author ( I don't know what author is or where this function is defined, please include an explanation for this in your answer as well ),

"author" represents the the Substrate Authoring RPC API.

In addition to JSON RPC requests using cURL using method author_rotateKeys, rotateKeys may also be used with the Polkadot.js javascript API implementation here, which may be used to encode an JSON RPC request with method author_rotateKeys and to decode an JSON RPC response. The rotateKeys part of the Polkadot.js javascript API documentation is here.

The Polkadot.js javascript API allows you to configure either a HTTP or WebSockets (WS) provider for sending JSON RPC requests using HTTP to a HTTP RPC server TCP port exposed by the endpoint of a node, or to a WebSockets port that is exposed by a node if you also want support for subscriptions (for example to listen to events such as when the session keys change).

The node itself listens for these requests. If the JSON RPC request uses the method author_rotateKeys then it would be interpreted using the Substrate Authoring RPC API.

  • rotate_keys Substrate rust API interface here
  • rotate_keys Substrate rust API implementation here
  • rotate_keys Substrate rust API documentation here

I get a long key like this: 0x87d0bce7ee8e3279674e9a91c4255379592ab5b24ab2bcf9438719d0b08013f0de6b77179766746c767e9fe547d6a57936bbd0846a20b21acd6f75f5fe779f5a6861fae2c2ec3aa460d4559c755d12b4c9186133b8eee66162369348aa7f180afcc75d5a6f0e17f69e8e4c9232ae24b980a230bbe06b1d4ff87ed35985cec04c, which is different on every call. Can someone explain what is going on? Where are these keys coming from? Are they random concats of a ed25519 and 3 sr25519, if my sessionKeys struct has 4 keys just like polkadot?

In the rotate_keys Substrate rust implementation here it shows that when make that RPC call it calls the generate_session_keys function here and provides the best block hash as an argument.

The generate_session_keys function is included in the Substrate documentation here, where it says that this optional argument (the best block hash) is used as the seed that it generates a set of session keys from, and those keys are stored within the keystore, and that function returns the concatenated SCALE encoded public keys of that set of session keys.

The response from every rotateKeys() RPC call would be different if the current best block hash was different each time it processed that RPC call.

In the Substrate implementation here it shows that it generates each of the key pairs using the seed with generate_pair(seed.clone()) and concatenates them together (i.e. an ed25519 key pair for grandpa, and three sr25519 key pairs for babe or aura, imonline, and authority discovery), and then encodes the concatenated key pairs using the Parity SCALE Codec.

The concatenated key pairs may be decoded into raw public keys again using decode_into_raw_public_keys.

Am I signing a random key with my controller account and then letting my node use that key for validation (grandpa, Imonline heartbeats, babe authorship, etc?)

In the Polkadot wiki session certificate is defined here as "A message containing a signature on the concatenation of all the Session keys. Signed by the Controller."

The Substrate Authoring RPC API stores the generated or provided session keys that are used for validating in the keystore CryptoStore, which manages the keys of a node.

It uses the public key of these stored session keys for signing messages using the controller account.

A randomly generated key may be provided at genesis or with the insert_key RPC call, however the session keys generated with the rotate_keys RPC call are based on the best block hash.

4
  • Very good, comprehensive answer, I thank you for addressing each point. I have a follow up question you may edit your answer to include it: How does one generate session keys without running a node and making the rotate_keys RPC call? I ask this because let's say I want some session keys in my genesis chain spec, would it be possible to achieve this using subkey? Mar 8, 2022 at 6:30
  • 1
    generate secret key openssl rand -hex 256 > secret_key_file && export SECRET=$( < secret_key_file ), then generate sudo account on a specific network subkey inspect --network datahighway --scheme sr25519 "//$SECRET", then generate accounts for five (5) authorities/validators for i in 1 2 3 4 5; do for j in stash controller babe imonline audi aura; do subkey inspect --network datahighway --scheme sr25519 "//$SECRET//$i//$j"; done; done && for i in 1 2 3 4 5; do for j in grandpa; do subkey inspect --network datahighway --scheme=ed25519 "//$SECRET//$i//$j"; done; done Mar 8, 2022 at 17:01
  • Great. Thank you so much! Do you mind if I added this comment into your answer? Or you may prefer to do it yourself. Mar 8, 2022 at 17:10
  • I don't mind. I actually just posted similar steps to answer this other question substrate.stackexchange.com/a/666/83 Mar 9, 2022 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.