Skip to content
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

Add "proposed" optional flag to getValidatorsAt #3531

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

iansuvak
Copy link
Contributor

@iansuvak iansuvak commented Nov 8, 2024

Why this should be merged

I'm not convinced that it should but opening this up for discussion.

Adding this interface was discussed together with adding platform.GetProposedHeight interface in #3530 This is a convenience method to allow for passing "proposed" instead of a numeric height literal to GetValidatorsAt.

The idea is to make it safer to publicly expose GetValidatorsAt interface. This by itself doesn't accomplish it but a different proxy service could use this same interface and call GetProposedHeight and return the cached value if this was called with the same resolved height and subnet.

How this works

Makes the GetValidatorsAt accept either numeric height or a "proposed" string literal that first calls getMinimumHeight and uses that instead of the numerical value. The service side is backward compatible but the client interface has changed.

I'm also not sure if this solution is cleaner than just adding a new boolean flag field to the request. I don't think that the platformVM service uses this kind of type overloading anywhere else.

How this was tested

Added a unit test.

Need to be documented in RELEASES.md?

Added a note to the RELEASES.md but this also introduces a breaking change to the client and not sure what's the best way to handle communication around that

Copy link
Contributor

@marun marun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Why was it necessary to propose a replacement for 3497 instead of evolving that PR?

  • I think it would be cleaner to add a new field instead of adding the complexity of a multi-type field. What suggested this approach?

@@ -102,6 +102,7 @@ var _ = e2e.DescribePChain("[Validator Sets]", func() {
tc.DefaultContext(),
constants.PrimaryNetworkID,
height,
false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(No action required) When using a literal value that doesn't provide context as to what it represents, maybe add a comment (e.g. false, // isProposed)?

@iansuvak
Copy link
Contributor Author

  • Why was it necessary to propose a replacement for 3497 instead of evolving that PR?

The pivot to this approach was to re-use the already existing field and make it more easily cacheable on the backend and keep the number of externally exposed RPC methods limited if they are accomplishing similar things. Given the pivot in strategy we opted for a new PR.

  • I think it would be cleaner to add a new field instead of adding the complexity of a multi-type field. What suggested this approach?

I'm open to either solution. The reasoning behind accepting multi-type field was since it's already an established pattern in the industry, see eth_getBlockByNumber which accepts latest, earliest etc. but if the consensus is to have a separate field I'd be happy to add a separate optional flag or boolean field

Copy link
Contributor

@ceyonur ceyonur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally LGTM, we probably need to update RELEASES.md

vms/platformvm/service.md Show resolved Hide resolved
vms/platformvm/service.md Outdated Show resolved Hide resolved
@@ -1689,7 +1689,7 @@ func (s *Service) GetTimestamp(_ *http.Request, _ *struct{}, reply *GetTimestamp

// GetValidatorsAtArgs is the response from GetValidatorsAt
type GetValidatorsAtArgs struct {
Height avajson.Uint64 `json:"height"`
Height avajson.Height `json:"height"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is to prevent breaking change for that args. However I wonder if a separate bool flag or even using negative values would make this more straightforward.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah indeed, that + custom parsing is to allow either json field. The idea was that eth supports this kind of thing already in eth_getBlockByNumber

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But happy to hear the votes either way!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to have backwards compatibility, so I'm fine with this or using negative values. Should we also add latest here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a new field would be optional regardless so I don't think it would impact backwards compatibility since the go client is already not backwards compatible in this implementation.

Re: latest I do think it makes sense to add but would prefer to do it as a follow up to get this change in before etna rollout. I do think it's slightly odd that platform.getValidatorsAt({height: "latest"}) and platform.getCurrentValidators{} would then return different types but I guess asking for them in the shorter return format that getValidatorsAt uses is a valid usecase

Comment on lines +8 to +11
type Height struct {
Numeric Uint64
IsProposed bool
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to Cey's comments, I wonder if rather than using a struct for this if it would be nicer to have special values for uint64.

Specifically - type Height uint64

  • When json marshaling - Height == MaxUint64 gets mapped to proposed
  • When json unmarshaling - proposed gets mapped to MaxUint64
  • When json unmarshaling - MaxUint64 is considered invalid

That way in the client we could just pass in api.ProposedHeight rather than adding a new bool arg.

(Also I think this should probably live in the api package rather than the json package, this feels more API specific than general to json helpers)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants