0

I am trying to get the stash id of a validator from the host of the node. I have a list of candidate validators. How would I achieve this?

I tried the following using Polkadot.js

var validator = "H3DL157HL7DkvV2kXocanmKaGXNyQphUDVW33Fnfk8KNhsv" // dummy key
var hasKey = await api.rpc.author.hasKey(validator, "acco")

But it always returns false even from a known match

when running it via shell:

curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "athor_hasKey", "params":["H3DL157HL7DkvV2kXocanmKaGXNyQphUDVW33Fnfk8KNhsv", "acco"]}' http://localhost:9933

I get the following error

{"jsonrpc":"2.0","error":{"code":-32602,"message":"invalid hex character: H, at 0 at line 1 column 49"},"id":1}

I also tried the keys returned from api.query.session.nextKeys, but I did not get a match. Not sure what I should use.

2 Answers 2

3

Where are you getting this list of candidate validators from?

The hasKey query is for checking if a node contains a specific session key. That is, you would not pass an account ID or address to it. I see that you are connected to localhost. Is this actually a validator with keys?

If you want to check if your local node is a validator, you can look up the nextKeys for the address you're interested in, and then call api.rpc.author.hasSessionKeys(<keys>) for the concatenation of all the keys. If it returns true, then that node has the session keys for that validator.

Note that this does not guarantee that you are safe from equivocation, i.e. that another node does not have the keys as well. Only that this node does have the keys.


EDIT: Here is a more complete example:

First, I'll check if the stash I'm interested in has signaled intent to be a validator with staking.validators.

staking-validators

It is, so let's look up its session keys with session.nextKeys(1NDRMvN7FH9YtJLVPf9doF5zbuUwn6hdH1b4WmVyZDr5joM).

session-nextKeys

Now, I SSH into the node that I know is using those keys. Of course, you need RPC access to whatever node you want to check the keys on. To make the storage key, I concatenate all of the keys into one value:

0x53a51c848834661c92e74b3c2492b8de2591f914ab75345d70e61c79be9699d73a80d898638dccd4aaa472e7948e7394969cc443335c494159948915c097c03624299947ecf9410e9dc4e439da8cec932a6584affd6026055e0718b8850fa0380658f8f3a64ec6949a26916ae2cd976fe531947a9c9e93e6d587bac746cb08263451595f904e1bcc1ecaffb327a9375f9f09251fd12a66f7cbd6faf86fe90243aa63a6245db826d277bf7bed80169db1bccdc7a3eb0ae7852317a5fb2628982a

And calling author.hasSessionKeys(<long hex value>), I get true :tada:

author-hasSessionKeys

If I just want to check one, I can do so with session.hasKey(<key>, <type>). In this case I'll use babe, so the key is 0x3a80d898638dccd4aaa472e7948e7394969cc443335c494159948915c097c036.

session-hasKey

2

working JS code (thank you @joepetrowski)

var validatorAddress = ''; // add your address here
var keys = await api.query.session.nextKeys(validatorAddress);
var keysJson = JSON.parse(JSON.stringify(keys));
// typescript Struct has a .toArray() function
var grandpa = keysJson.grandpa;
var babe = keysJson.babe;
var imOnline = keysJson.imOnline;
var paraValidator = keysJson.paraValidator;
var paraAssignment = keysJson.paraAssignment;
var authorityDiscovery = keysJson.authorityDiscovery;
var keys = [grandpa, babe, imOnline, paraValidator, paraAssignment, authorityDiscovery];
//
var sessionKeys = "0x";
for (const key of keys) {
  if (key != undefined) {
    sessionKeys += key.replace(/^(0x)/,'');
  }
}
var result = await api.rpc.author.hasSessionKeys(sessionKeys)
console.log(result)

Your Answer

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

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