-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: BLS Key Separation and ERC2335 Implementation #396
feat: BLS Key Separation and ERC2335 Implementation #396
Conversation
… in erc2335 description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! Some initial comments:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank for the answers. One thing as I mentioned in the pr is the change the target branch. Other than that the code lgtm! Will approve once it's ready for review. Also, let's wait for review from @KonradStaniec.
How is CI going (I don't know why I can's see the ci results)?
Commit summary 1f14b31
Additionally, in the CI pipeline, there is an issue with a specific E2E test: test-e2e-cache-upgrade-v1. The problem appears to stem from the recent change requiring the BLS key to be created exclusively during the create-bls-key process. As a result, the node does not start if the key is missing. While addressing the UX issue referred to in this context, it seems more efficient to resolve the related problem together. Furthermore, aside from the test-e2e-cache-ibc-transfer test, which requires DockerHub login, all other E2E tests, and unit tests have been successfully executed locally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
few nits here and there, but in general LGTM! great progress 👍
crypto/erc2335/erc2335.go
Outdated
) | ||
|
||
type Erc2335KeyStore struct { | ||
Crypto map[string]interface{} `json:"crypto"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some doc for this field would be nice like what does this map hold (as type map[string]interface{}
does not tell much to the reader)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
crypto/erc2335/erc2335.go
Outdated
|
||
keyJSONBytes, err := os.ReadFile(filePath) | ||
if err != nil { | ||
return Erc2335KeyStore{}, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets wrap errors here with some additional useful info given that this is public function which is pretty low level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
crypto/erc2335/erc2335.go
Outdated
encryptor := keystorev4.New() | ||
cryptoFields, err := encryptor.Encrypt(privKey, password) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "failed to encrypt private key") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
usually in our codebases we are wrapping our errors with fmt.Errorf("error msg: %w", err)
(which imo looks nicer though this is highly personal opinion), any reason for using errors
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
crypto/erc2335/erc2335.go
Outdated
} | ||
|
||
if err := json.Unmarshal(keyJSONBytes, &keystore); err != nil { | ||
return Erc2335KeyStore{}, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets wrap the error here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
crypto/erc2335/erc2335.go
Outdated
password := make([]byte, 32) | ||
_, err := rand.Read(password) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a bit risky in such low level public operation which does not know context of the application.
Maybe:
- if it is only for testing, lets make it private
- it is supposed to be public, lets return error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// encrypt the bls12381 key to erc2335 type | ||
erc2335BlsPvKey, err := erc2335.Encrypt(k.PrivKey, k.PubKey.Bytes(), password) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems weird to be panicking in low level library code. Lets wrap and return errors ? (and panic at callsites if necessary)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for saving BLS keys to files is written to be consistent with FilePV in cometbft.
In addition, since Save is not executed during state transition, but only when setting keys before the chain is executed, the risk of panic should not be great.
Nevertheless, if necessary, I will rewrite it to return an error. Please give me your opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with either way
|
||
// wonjoon: encrypt key pair to erc2335 keystore | ||
// available to handle all keys in []byte format | ||
func Encrypt(privKey, pubKey []byte, password string) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: proper go doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Summary 9dd45f3
|
Here is the plan for the second PR: This second PR is expected to be set R4R until next week. Remove WrappedFilePV:Since the LastSignState field has been removed, the WrappedFilePV structure is no longer necessary. Methods that previously relied on WrappedFilePV will be updated to directly reference FilePV and BlsPV from CometBFT. Ensure Atomic Creation of BLS Key and priv_validator_key.json:Further discussion is needed on “ensuring the atomic creation of the BLS key file along with priv_validator_key.json and removing the create-bls-key command”.
Update Delegator Address Handling:Modify the logic so that the delegator address is provided directly during the ExtendVote() function instead of being stored in BlsPV. This will follow the pseudo-code shared earlier. Check Validator Status During InitPrivSigner:Add a check in InitPrivSigner to determine if the node is a validator by verifying whether the Consensus public key(from FilePV) is included in the validator list. If the node is a validator, generate the BLS key; otherwise, skip key generation. |
Description
This PR was created from epic #336, separates BLS key from priv_validator_key.json, and applies ERC2335.
There are still issues in CI that are being resolved, but I'm uploading a PR to first discuss the changed structure and ideas.
ERC2335 structure
Change WrappedFilePV to include BLS structure and use cometbft's FilePV directly
BLS separation
babylond init
, only priv_validator_key.json is created.babylond create-bls-key
creates a BLS key with the password entered as the prompt and encrypts it into an ERC2335 structure.bls_key.json
, and the password is saved asbls_password.txt
.An example of a
bls_key.json
is below:An example of a
priv_validator_key.json
with BLS separated is below:Change DelegatorAddress to be stored in the description field of ERC2335 structure instead of storing it in
priv_validator_key.json
.bls_key.json
file in erc2335 format.Test script
$ ./babylond init my-node --chain-id test-chain-1
$ ./babylond keys add validator1 --keyring-backend test
$ ./babylond add-genesis-account $(./babylond keys show validator1 -a --keyring-backend test) 2000000000000ubbn,2000000000000stake
$ ./babylond gentx validator1 1500000000000stake --chain-id test-chain-1 --keyring-backend test --fees 400ubbn
$ ./babylond collect-gentxs
$ ./babylond create-bls-key $(./babylond keys show validator1 -a --keyring-backend test)
$ ./babylond gen-helpers create-bls
After the create-bls command, json file starting with the prefix "gen-bls" will be created in {home}/.babylond/config.
Copy data in the created file to the 'checkpointing.genesis_keys' field in genesis.json.
Here is an example after inserting data to 'checkpointing.genesis_keys' field in genesis.json
Subsequent tasks
BlsPV
structure and obtain it fromGetValidatorByConsAddr()
function of the Epoch(Staking) module.Add the option to use the1f14b31--bls-password
flag when creating the BLS keyWrappedFilePV
since LastSignState is not used