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

Adding gRPC dial capability for mercury #12560

Closed
wants to merge 15 commits into from

Conversation

patrickhuie19
Copy link
Contributor

@patrickhuie19 patrickhuie19 commented Mar 25, 2024

Summary
This adds a grpc (over HTTP/2) mode to the mercury client, in addition to the currently in production wsrpc mode.
We will need to support both modes for ~4-8 weeks while we learn to operate the service with grpc.

Discussion
After lots of iteration, I chose to implement this change by manually changing the autogenerated proto client so that I could add grpc handlers. I found this to be by far the most efficient way to accomplish this - both generics and introducing a new higher level grpc client result in loads of duplicated and unnecessarily complicated code.

What do you need to review?

  • Proper test coverage to ensure no regressions to wsrpc behavior
  • Review the related WSRPC changes: Support wsrpc --> grpc for Mercury wsrpc#59. Includes the update to the autogeneration script
  • Metadata key naming. The key naming of the KV pairs end up in HTTP headers.

Key material in this PR is for testing only and is fine to be leaked.

Copy link
Contributor

github-actions bot commented Mar 25, 2024

I see you updated files related to core. Please run pnpm changeset in the root directory to add a changeset as well as in the text include at least one of the following tags:

  • #added For any new functionality added.
  • #breaking_change For any functionality that requires manual action for the node to boot.
  • #bugfix For bug fixes.
  • #changed For any change to the existing functionality.
  • #db_update For any feature that introduces updates to database schema.
  • #deprecation_notice For any upcoming deprecation functionality.
  • #internal For changesets that need to be excluded from the final changelog.
  • #nops For any feature that is NOP facing and needs to be in the official Release Notes for the release.
  • #removed For any functionality/config that is removed.
  • #updated For any functionality that is updated.
  • #wip For any change that is not ready yet and external communication about it should be held off till it is feature complete.

@cl-sonarqube-production
Copy link

Quality Gate failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube

Catch issues before they fail your Quality Gate with our IDE extension SonarLint SonarLint

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are fixtures that are for testing only and are fine to be made public

Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment than for core/services/ocr2/plugins/mercury/fixtures/domain.key, could we change the name to reflect it is intended for tests?

return &client{
csaKey: clientPrivKey,
serverPubKey: serverPubKey,
serverURL: serverURL,
logger: lggr.Named("WSRPC").Named(serverURL).With("serverURL", serverURL),
logger: lggr.Named("Client").Named(serverURL),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there are alerts defined on this logger name its likely best to leave alone

@cl-sonarqube-production
Copy link

Quality Gate failed Quality Gate failed

Failed conditions
8 New Major Issues (required ≤ 5)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube

Catch issues before they fail your Quality Gate with our IDE extension SonarLint SonarLint

@@ -159,11 +159,17 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G

loopRegistry := plugins.NewLoopRegistry(appLggr, cfg.Tracing())

// TOML config + env var protected usage of grpc mercury pool
var mercuryTlsCertFile *string
if os.Getenv("CHAINLINK_MERCURY_USE_GRPC") == "true" {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably better as a config variable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is true now that many of our smoke tests are moving to using TOML.

@@ -533,7 +543,7 @@ func NewEthMocksWithTransactionsOnBlocksAssertions(t testing.TB) *evmclimocks.Cl
}

// Start starts the chainlink app and registers Stop to clean up at end of test.
func (ta *TestApplication) Start(ctx context.Context) error {
func (ta TestApplication) Start(ctx context.Context) error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This change seems like a mistake

Copy link
Contributor Author

Choose a reason for hiding this comment

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

given how the application interface works in the testing this was the simplest change to not require a lot of code changes. Potentially an opportunity for cleanup?

@jmank88 are there any long term code organization/styling difference son using a pointer receiver vs non-pointer receiver for methods?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is functionally different and likely breaks tests, no? The linter sees the problem on 548.

Comment on lines +1 to +28
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCswr7N//BPhAkF
mtvwOge2j536x8IJygZZNccLmOGXG2aj0FI9xD2kBBlzpk+/Ma5WIGbcVgcum49m
b5+upEY8nmZK74yGluNKUi2Zoiw3f7uBA2EwFI4irfDT3WUGr7N54hdIWi0GgegP
KjAqkPfNrd3ZP3mJcTfDR0KbgT/Gv65MLHEPkdkh7dHlsdSIRVKkfrAZ+Vr8uSZq
TZlapwZHn1RaeYdta11zvFwEyRxmHFDNZUpwpr8pk8ytjQwgkIe9lzIWN8esO5An
7yT9AICEXcumVjvU6DTXOwtexTPfegKN7S4eFU4b5ctY/TLaxws0xbxL+/tAytNf
qcFou22fAgMBAAECggEAD9723GyOInVExukKb4VFPsuZfc0VfFoSPzvQ2gs6HkGm
1OxxwbmM2CEwSA7tSz6V1NUL3g4L1tz0+Dok90xMJOGAZZNK25/HqFo9qjGF0mC/
qa3VIy+gPHtc9nm5ADuVR2CH4bO3EzP396dZNBqL9ASXBDrv6rp7SaClnoI/M6jd
lreoedH5TxDQ+tS+smmOhOVXYr8H/y3I2Kt4GrcuvZVp7ftL0zcN7q2l4TAvPE/B
a/t8Vp4kdMAOHMCAGXs4YeQ+kDpgKzUrDrRhpxoC4EBkHZNDcd4ww9Bb9hSFNzFk
oNZYaB6Lxm7Gw7cVtz6IYCJhrIQEj7J5ddCR3/CesQKBgQDicvOhUaERiyjKgWib
mzinGkAgPFTupKH+VEFcQww7VuUS7lyRv2LFaUB2iJTKt39zipht1p3ZZDIGdoEL
J3lMqw3wPMhkhrnu509ma+0XWJG/4mW/tVPfeGLhWQb8FwR41BT2mVCw6jEUpApT
rjFq5AFPmxR5fx39YRDWkToRmwKBgQDDTjZ+NdtUbalVBTG271z3Hyf1JSwAs806
H6wcLHhKGZGZPPLYNKv+KFKZiXCJuyDUfAzwsfelNzq0PLfymhnmsYG52YIxVJ5c
vl2uX9LH853TNwaGDabCpbEj4X7OxTOjp0rwsESpOnEOP8w7HgDvX+3Rrk89HNni
78yM0neGTQKBgQCYiz87iLWsD8ZmxE4npKTBTJmuHXZJXHYT0cZF1JTE1IB0BEYv
mHF88q4OK2uwM3ST7OVJ+K1U6H4ahHHhhbHcx84X65pCvc869G80W7fXZj6ouGY6
gngBriNOEp716ruEebm1dQo6Y0i00txyCoIXs4h+i8V7Ivqc2WpyYFpxyQKBgQCx
lsTmLoKpWq3GqVpzRWP7MVFcD9jbKqNKXtJZK/aVKnrCJDGNdxeNm4zAH8E8+/L2
Q3ZgxvKwQHAYw71f09AJfQ7At48y3AbDvjXhATDgsByqmjZMXs1r4M4aGkj8K0Sx
YsU55o4IcyOqGUjT2IxxHYFaUG2s3Dcjq3kL87TLYQKBgGcBQz2mhwaTAMSpo6n5
QWtYYmLmE3DCsAH1l0GcgSNYY4ZsZ1066xw7t1BABWScInlkA3BbeQJEYclhVli/
9cRv+xUORGHQ08btRxLdDKX0qw50LmRJONYjHDPQnUJSxY2pWGi9JBIaE5uMAqBl
FxIhwpSwH/dcU8gRXU4yllLA
-----END PRIVATE KEY-----
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you mean to commit a private key?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, these are just test fixtures.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can the filename be changed to something like domain_test.key to emphasize this is for tests?

Comment on lines +85 to +99
if s.tlsCertFile != nil {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, errors.New("could not extract public key from grpc outgoing context")
}
peerID = md.Get("csa-key")[0]
signature := md.Get("signature")[0]
require.NoError(s.t, VerifySignature(peerID, req, signature), "signature verification failed")
} else {
p, ok := peer.FromContext(ctx)
if !ok {
return nil, errors.New("could not extract public key")
}

peerID = p.PublicKey.String()
Copy link
Collaborator

Choose a reason for hiding this comment

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

This will need audit I think

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes definitely

@patrickhuie19 patrickhuie19 marked this pull request as ready for review May 14, 2024 15:11
@patrickhuie19 patrickhuie19 requested a review from a team as a code owner May 14, 2024 15:11
@patrickhuie19 patrickhuie19 requested a review from a team May 14, 2024 15:11
@patrickhuie19 patrickhuie19 requested a review from a team as a code owner May 14, 2024 15:11
@patrickhuie19 patrickhuie19 requested review from jmank88 and obelisk May 14, 2024 15:11
var mercuryTlsCertFile *string
if os.Getenv("CHAINLINK_MERCURY_USE_GRPC") == "true" {
tlsCertFile := cfg.Mercury().TLS().CertFile()
mercuryTlsCertFile = &tlsCertFile
Copy link
Collaborator

Choose a reason for hiding this comment

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

Comment on lines +33 to 34
ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the purpose of the duplication here?

}

// Adapting Grpc Client Conn to Conn interface
type AdapatedGrpcClientConn struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo

@timweri
Copy link
Collaborator

timweri commented Jul 19, 2024

We should separate the logic for gRPC and WS more clearly, especially when authentication is involved. Also, we shouldn't use the presence of a config tlsCertFile to decide on the control flow between gRPC and WS. We need something more explicit.

@patrickhuie19
Copy link
Contributor Author

patrickhuie19 commented Sep 6, 2024

We should separate the logic for gRPC and WS more clearly, especially when authentication is involved.

Do you have ideas?
If its by separating the higher level abstractions, like Pool, I'm very hesitant to revisit that - I've already tried that and the code is an absolute mess. Most maintainers should not even be aware of this low level detail, so the code is isolated about as cleanly as I could make it.

Also, we shouldn't use the presence of a config tlsCertFile to decide on the control flow between gRPC and WS. We need something more explicit.

It also requires the env var CHAINLINK_MERCURY_USE_GRPC

@patrickhuie19 patrickhuie19 requested review from a team as code owners September 8, 2024 18:08
@pkcll pkcll self-requested a review September 12, 2024 15:05
Copy link
Contributor

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale label Nov 12, 2024
@github-actions github-actions bot closed this Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants