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

Replace Equivalent call with Equals in proto comparisons #32694

Merged
merged 3 commits into from
Mar 29, 2024

Conversation

yanavlasov
Copy link
Contributor

@yanavlasov yanavlasov commented Mar 4, 2024

Commit Message:
Replace Equivalent call with Equals in proto comparisons. In OSS proto3 these methods have the same behavior, since their difference is only relevant for proto2, in treatment of missing fields with default values.

This only becomes relevant for Google internal builds where proto2 is used. If this change is considered too risky we can abandon it and deal with it internally.

Risk Level: Low.
Testing: Unit Tests
Docs Changes: N/A
Release Notes: N/A
Platform Specific Features: N/A

…q functors.

`eq(k1, k2) -> hash(k1) == hash(k2)` must be true for hashtable usage to be valid.

Signed-off-by: Yan Avlasov <[email protected]>
Copy link

As a reminder, PRs marked as draft will not be automatically assigned reviewers,
or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!

🐱

Caused by: #32694 was opened by yanavlasov.

see: more, trace.

@yanavlasov yanavlasov marked this pull request as ready for review March 4, 2024 21:20
@yanavlasov yanavlasov enabled auto-merge (squash) March 4, 2024 21:22
@@ -224,7 +224,7 @@ class MessageUtil {

// std::equals_to
bool operator()(const Protobuf::Message& lhs, const Protobuf::Message& rhs) const {
return Protobuf::util::MessageDifferencer::Equivalent(lhs, rhs);
return Protobuf::util::MessageDifferencer::Equals(lhs, rhs);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have a test?

@kyessenov
Copy link
Contributor

I think golang intentionally randomizes maps which means Go-based control planes might be triggering this condition.

@jmarantz
Copy link
Contributor

jmarantz commented Mar 5, 2024

@ravenblackx did some work in this area, IIRC, around hashing of protobuf structures. I feel like it might be helpful to bring him into this also. I thought we devised a way to make the hash on a map be order independent.

It looks like the proposed fix makes (a,b) != (b,a). Do we instead want to make them ==, so I guess that means fixing the hasher to be order-independent (which I think @ravenblackx already has code for) rather than fixing the == to be order-dependent? Or am I mixing this up?

This is why a testcase would be helpful :)

@kyessenov
Copy link
Contributor

I think this has a potential to be a breaking change if a control plane doesn't enforce deterministic encoding (and some SDKs do not by default, e.g. Go). With a weaker equality, a new config is going to be applied more often which increases the load on the main to process it and potentially triggers drains that were not triggered before, which can lead to non-graceful connection termination.

@jmarantz
Copy link
Contributor

jmarantz commented Mar 5, 2024

#30761 is Raven's PR that I was thinking of, https://github.com/ravenblackx/envoy/blob/fbed541d563741540e923ea694be13708434acda/source/common/protobuf/deterministic_hash.cc#L84 (reflectionMapField) is the hash function for maps.

@yanavlasov
Copy link
Contributor Author

Looks like I may have been hasty with this change. Let me think through this one a little more.

@yanavlasov yanavlasov marked this pull request as draft March 6, 2024 14:44
auto-merge was automatically disabled March 6, 2024 14:44

Pull request was converted to draft

@yanavlasov yanavlasov marked this pull request as ready for review March 28, 2024 23:56
@yanavlasov yanavlasov changed the title Fix a bug in which an absl hashtable is used with inconsistent hash/eq functors Replace Equivalent call with Equals in proto comparisons Mar 29, 2024
Copy link
Contributor

@kyessenov kyessenov left a comment

Choose a reason for hiding this comment

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

Looks like Equals and Equivalent behave the same. We still have to handle non-deterministic map order elsewhere, but this is not the place.

@yanavlasov yanavlasov merged commit 8c08caa into envoyproxy:main Mar 29, 2024
53 checks passed
@yanavlasov yanavlasov deleted the proto-equals branch March 29, 2024 18:34
alyssawilk pushed a commit to alyssawilk/envoy that referenced this pull request Apr 29, 2024
…oxy#32694)

Replace Equivalent call with Equals in proto comparisons. In OSS proto3 these methods have the same behavior, since their difference is only relevant for proto2, in treatment of missing fields with default values.

---------

Signed-off-by: Yan Avlasov <[email protected]>
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.

3 participants