-
Notifications
You must be signed in to change notification settings - Fork 10
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(multiple): read from genesis file #23
Conversation
The bootstrapping contract and its script are required to generate the genesis state, which includes the following: - Registration of client chain - Registration of client chain assets / tokens, with the total deposit value - Total amount delegated to each operator for each asset ID - Total amount deposited by each staker for each asset ID, and the portion of it that is currently withdrawable
The delegation module by itself does not store a lot of information. The small portion that it does store is handled by this commit at the time of genesis. It validates that the formats of the StakerID, the AssetID and the OperatorAddress are correct and that the amount is not nil.
The map was used to store operator consensus key to vote power mapping as of the last iteration. However, the same information is available with the iteration `GetAllExocoreValidators` and the same complexity.
explain why the protobuf.Any type is used
When the `bytes32` consensus key from Solidity is dumped for the genesis file to import, it is not directly readable as bytes. We have to read it via the `hexutil` import. This import expectes double the length (32 * 2 = 64) plus a prefix (`0x`) length of 2, and operators on the string as the input.
There was a duplicates check being enforced, that should not have been, and vice-versa.
This helps ensure one interface for encoding and decoding, and the suffix `0x` is always present. It also takes care of the case (upper or lower) by itself.
instead, generate it on the fly (to avoid gitleaks thinking it is an API key)
Assumptions: - `assets` module genesis is only responsible for deposits - `delegation` module genesis then locks up the assets based on its genesis state, from its own perspective as well as in the `assets` module. - `operator` module genesis verifies that the delegated amount provided to it is the same as that provided to the delegation module.
Clarify that the check made by the operator module indirectly includes a check for the assets data
Checks in the delegation module include: - assetID corresponds to a registered staking asset - free (unbonded) deposits for stakerID and assetID combination exceed (or are equal to) the delegation amount. Checks in the operator module (on loop 3, amounts) include: - the operator is registered (during loop 1), since this is not something that the delegation module can enforce. - the amount delegated by {staker,asset,operator} equals the amount delegated for the same combination according to the delegation module. - the combinations {staker,asset,operator} that exist in the module equal those provided by the delegation module. this check helps skip the `IsStakingAsset` check within this module.
for stakerID, assetMap := range map1 { | ||
if assetMap2, ok := map2[stakerID]; ok { | ||
for assetID, operatorMap := range assetMap { | ||
if operatorMap2, ok := assetMap2[assetID]; ok { | ||
for operatorAddress, amount := range operatorMap { | ||
if amount2, ok := operatorMap2[operatorAddress]; ok { | ||
if !amount.Equal(amount2) { | ||
return false // Amounts differ | ||
} | ||
} else { | ||
return false // OperatorAddress not found in map2 | ||
} | ||
} | ||
} else { | ||
return false // AssetID not found in map2 | ||
} | ||
} | ||
} else { | ||
return false // StakerID not found in map2 | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
for assetID, operatorMap := range assetMap { | ||
if operatorMap2, ok := assetMap2[assetID]; ok { | ||
for operatorAddress, amount := range operatorMap { | ||
if amount2, ok := operatorMap2[operatorAddress]; ok { | ||
if !amount.Equal(amount2) { | ||
return false // Amounts differ | ||
} | ||
} else { | ||
return false // OperatorAddress not found in map2 | ||
} | ||
} | ||
} else { | ||
return false // AssetID not found in map2 | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
for operatorAddress, amount := range operatorMap { | ||
if amount2, ok := operatorMap2[operatorAddress]; ok { | ||
if !amount.Equal(amount2) { | ||
return false // Amounts differ | ||
} | ||
} else { | ||
return false // OperatorAddress not found in map2 | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
x/operator/keeper/genesis.go
Outdated
for stakerID, assetMap := range map2 { | ||
if _, ok := map1[stakerID]; !ok { | ||
return false // Extra StakerID in map2 | ||
} | ||
for assetID, _ := range assetMap { | ||
if _, ok := map1[stakerID][assetID]; !ok { | ||
return false // Extra AssetID in map2 | ||
} | ||
} | ||
} |
Check warning
Code scanning / CodeQL
Iteration over map Warning
The dogfood module accepts a list of validators as input. These validators must be registered within the operator module for the chain's ChainID.
// #nosec G703 // already validated | ||
consKey, _ := operatortypes.HexStringToPubKey(val.PublicKey) | ||
// #nosec G601 // this only fails if the key is of a type not already defined. | ||
consAddr, _ := operatortypes.TMCryptoPublicKeyToConsAddr(consKey) |
Check warning
Code scanning / gosec
Returned error is not propagated up the stack. Warning
Closing this PR to break it down into multiple PRs. |
This pull request sets up genesis data structures for the modules
assets
,delegation
,operator
anddogfood
. The data is read, marshaled and then validated before the node starts. Once the node starts, the data is sent to the module keepers at genesis where stateful validations can take place.Secondly, it makes some minor changes (comments and clean-up) in the
dogfood
module.Lastly, it also sets up a CLI way for validators to export their consensus public key as a bytes32 object to use within Solidity.
exocored keys consensus-pubkey-to-bytes --output json | jq -r .bytes F0F6919E522C5B97DB2C8255BFF743F9DFDDD7AD9FC37CB0C1670B480D0F9914
For reference, the (JSON) string object can be exported as follows:
The same key can be recovered from the mnemonic (which can also be read from stdin manually)