-
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
Validators module #253
Validators module #253
Conversation
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.
Overall looks good! Let's go ahead and get these changes in and then I will do a second pass.
Two kind of interesting things are happening here that haven't come up before:
- You are using a
Set
to keep track of the keys that belong to a certain store map. - There is a state object (
ValidatorUpdate
) that is not accessible to the outside world.
In both cases you opted to use JSON to implement the HasCodec
instance. In general I am not a fan of this because it makes it more difficult to operate on these values across languages and applications. There are a few reasons why, you can see this discussion if you're interested: cosmos/cosmos-rust#14 (comment)
I'm not even sure I care about addressing this now, but:
(2) above would easily solved by just implementing a protobuf definition, but I have a feeling (1) is going to come up over and over again because it does with solidity.
regarding a proper tests setup with multiple docker images, I am not really worried about that in this PR but feel free to file an issue. It seems simple enough that things should just work 🤞 |
To your comment points: I think the "Set of Map keys" pattern could be added as a feature in Map. Since IAVL has the IterateRange methods and the gRPC layer has the List method, it should be possible to get all the key/value pairs for a Map substore. I can write up an issue if you think this is worth pursuing.
I can probably do this more cleanly with newtype and by reusing the proto stuff from ABCI to implement Also ValidatorUpdate is not externally accessible partly because it's only being used as a way to queue updates from different deliverTx into the endblock, it's never actually stored in committed state. Which is somewhat weird, but I can't really see a better way to do this other than creating some entirely new system for local block processing storage. I agree with the larger point about cross platform compatibility and standardization, so I'll switch all of this over to proto. |
Regarding new typing to avoid circular dependency, or what would usually be orphan instances , it’s a very common method. If you need to do it then go for it. i think you should write up this issue for map with keys because it would be really useful. I remember it being a big annoyance in ethereum contracts. Regarding the grpc stuff, maybe you’ve seen but I have a branch to upgrade the grpc protobuf file from iavl. I just haven’t finished it yet... |
Okay. Did some stuff:
Two things to note:
|
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.
OK looks good to me! Just a few small review comments, only one small change. Also need to Otherwise the majority of the work will be in figuring out #254 at some point. Great work!
Regarding weeder, I think you need to put the tope level Tendermint.SDK.Modules.Validators
and generated protobuf modules in the package.yaml
, similar to what you see here
:: Members [ReadStore, Error AppError] r | ||
=> Sem r (Map.Map PubKey_ Word64) | ||
getQueuedUpdatesF = L.foldl (\m (ValidatorUpdate_ ValidatorUpdate{..}) -> | ||
Map.alter (Just . fromMaybe (toWord validatorUpdatePower)) (PubKey_ validatorUpdatePubKey) m) Map.empty updatesList |
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.
What does it mean if two ValidatorUpdate_s have been queued for the same PubKey_? It seems like here we just take the one that happened last as the update and disregard whatever came before it?
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.
Yes that was the intended behavior here. I figured there were roughly 3 options of how to handle multiple updates to the same validator within a single block:
- Don't allow it, which would require turning the updates array into a map to check if the pubkey already existed
- Allow it, and apply only the first update
- Allow it, and apply only the last update
Applying the last update made the most sense to me, as all the updates are replacements not relative changes. So the result of composing those replacements in order would be to just take the last one.
rawKey = iso t f | ||
where | ||
t (PubKey_ p) = encodeMessage $ (p ^. _Wrapped') | ||
f = PubKey_ . fromRight (PubKey "" "") . second (^. _Unwrapped') . decodeMessage |
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 fine, but as a note I'm sort of remembering that there is actually no instance where the from
method of the iso is being used, we're almost always using it as a value of type :: Lens' a ByteString
. This is why the PubKey "" ""
seems awkward, I will get around to fixing this soon.
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.
See #255
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.
re PubKey "" ""
:
I figured this would be okay, since the only time it would be deserializing would be if it was reading the bytes from the db. And they must have been serialized from the pubkey to get put in the DB, so it should never fail. Definitely is awkward thought...
So this is an interesting test failure:
This is being caused by my changing the My reading of this is that it can start with an "Unwrapped" protobuf value which doesn't have the key, and then when it tries to turn it into a ValidatorUpdate object it fails... Is this basically why the value was I can also just switch the type back to |
Yeah to be honest I’m not really sure, but try putting the Maybe back and if it passes we can get this in without worrying too much about it for now |
Initial draft of a module for apps to manage validator sets (#252).
Changes from what was described in that issue:
I'm not very familiar with the Query system, so that is in particular need of review.
Also Weeder is going to fail until this has some tests, and I imagine that is going to take a while because I'm not familiar with the Kepler testing system, and proper testing will require multiple Tendermint docker instances.