cip | title | author | discussions-to | status | type | category (*only required for Standards Track) | created | license |
---|---|---|---|---|---|---|---|---|
26 |
Precompile for getting BLS public key for a given validator in a historical block |
Sami Mäkelä (@mrsmkl) |
Final |
Standards Track |
Ring 0 |
2020-11-17 |
Apache 2.0 |
Adding a precompile that returns the BLS public key of a given validator in a given block.
Returns the BLS public key of a validator in the same way as the existing precompile for getting the validator address.
Currently it's not possible to get the validator BLS public key used for consensus from the chain. It's only possible to get the current BLS key that would be active in the next epoch. However the keys are needed to implement slashing in the case of bad epoch snark data (see CIP-20).
The address of the precompile is 0xE1
The input is interpreted in the same way as precompile for getting the validator address: it is 64 bytes, first 32 bytes are an integer representing the index of validator to get, and the second 32 bytes are an integer representing the block to access. These input values have the same conditions as the precompile for getting validator address: index must be smaller than the number of validator for the given block, and block number must be smaller than current block number.
Returns the BLS public key in uncompressed format as 192 byte string. In the case of Celo, the BLS public key is a point in the BLS12-377 elliptic curve defined over Fp2 (G2). A value of Fp2 is represented as two numbers smaller than the base field modulus. These numbers are encoded as 64 byte little endian strings (function LE
). So if we have a point (a+bi,c+di), it is serialized as LE(a) || LE(b) || LE(c) || LE(d)
.
The precompile will use 1000 gas, same as the current precompile to get the validator address.
(From discord #plumo channel)
The problem we've stumbled upon is that the BLS key might change during an epoch and so we can't get the BLS key that is expected to be used in consensus and should be used for slashing detection.
We've discussed a few possible solutions:
- modifying the validators contract to include that information
- using the proofs of possession that validators submit when updating BLS keys
- introducing a new precompile that gets the consensus-activated BLS keys of the validator set at a block
A brief pros/cons for the approaches:
- pros: easy-ish to implement and very natural. cons: might be hard to deploy, as the validators contract is already pushing the boundaries of the gas limit + we need to upgrade the contract, which introduces risks. We additionally need the ability to decompress points.
- pros: no changes needed to any smart contract. cons: complex to implement + decompression of points is needed.
- pros: easy to implement and we can hide the complexity of point decompression inside the precompile. It's a generic precompile that can be used elsewhere. cons: a new precompile.
@asaj and @kobigurk felt that the best option is 3 and @asaj on to get a sense of acceptance in the All Core Devs calls today, and there was no objection.
Adds new precompile, so a hard fork is needed.
Unit tests in branch mrsmkl/precompile-bls-key
Branch celo-org/celo-blockchain#1250
The precompile is very similar to an existing one, so there shouldn't be too many security implications. Mostly have to be sure that all the edge cases are handled properly and to make sure there's no non-deterministic behavior.
This work is licensed under the Apache License, Version 2.0.