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.