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

Nitro Payments #1691

Closed
wants to merge 442 commits into from
Closed

Nitro Payments #1691

wants to merge 442 commits into from

Conversation

husobee
Copy link
Contributor

@husobee husobee commented Nov 4, 2022

Summary

Includes commits from following PRs:
#1387
#1385
#1384
#1219

Type of change ( select one )

  • Product feature
  • Bug fix
  • Performance improvement
  • Refactor
  • Other

Tested Environments

  • Development
  • Staging
  • Production

Before submitting this PR:

  • Does your code build cleanly without any errors or warnings?
  • Have you used auto closing keywords?
  • Have you added tests for new functionality?
  • Have validated query efficiency for new database queries?
  • Have documented new functionality in README or in comments?
  • Have you squashed all intermediate commits?
  • Is there a clear title that explains what the PR does?
  • Have you used intuitive function, variable and other naming?
  • Have you requested security / privacy review if needed
  • Have you performed a self review of this PR?

Manual Test Plan:

@husobee husobee self-assigned this Nov 4, 2022
@DJAndries
Copy link
Collaborator

@husobee Any updates on this by chance? Would be nice to see nitro-utils merged so we can get the STAR randomness server up and running in prod. Thanks in advance

nitro-shim/tools/viproxy/main.go Fixed Show fixed Hide fixed
nitro-shim/tools/viproxy/main.go Fixed Show fixed Hide fixed
services/nitro/nitro.go Fixed Show fixed Hide fixed
services/nitro/nitro.go Fixed Show fixed Hide fixed
services/nitro/nitro.go Fixed Show fixed Hide fixed
services/nitro/nitro.go Fixed Show fixed Hide fixed
nitro-shim/tools/kafkaproxy/main.go Outdated Show resolved Hide resolved
services/payments/cmd/rest_run.go Show resolved Hide resolved
services/payments/cmd/rest_run.go Show resolved Hide resolved
// pprof attaches routes to default serve mux
// host:6061/debug/pprof/
go func() {
logger.Error().Err(http.ListenAndServe(":6061", http.DefaultServeMux))

Choose a reason for hiding this comment

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

reported by reviewdog 🐶
[semgrep] Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information.

Source: https://semgrep.dev/r/go.lang.security.audit.net.use-tls.use-tls

Cc @brave/sec-team @thypon @bcaller

Copy link
Member

Choose a reason for hiding this comment

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

I believe this is expected, but a comment should be added to clarify this. If I remember correctly, we may be ignoring the use of TLS because we're achieving the same goals via the nitro enclave.

TODO: I need to double check this

services/payments/cmd/rest_run.go Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

What prompted this change and the one below for brave-skus/free_time_imited_v2_dev in this PR?

cmd/root.go Outdated
@@ -31,9 +31,6 @@ func Execute(version, commit, buildTime string) {
ctx = context.WithValue(ctx, appctx.EnvironmentCTXKey, viper.Get("environment"))
ctx = context.WithValue(ctx, appctx.DebugLoggingCTXKey, viper.GetBool("debug"))
ctx, logger = logging.SetupLogger(ctx)
// setup ratios service values
Copy link
Member

Choose a reason for hiding this comment

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

Is this meant to be in this PR as well?

Copy link
Member

Choose a reason for hiding this comment

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

nit - we could make this a bit more generic to reduce duplication of code for the clients.

@kdenhartog
Copy link
Member

I'm confused as to what parts here are relevant specifically to the nitro-shim utilities that we need done ASAP to get the star randomness server unblocked versus what's specific to the payments services that can be reviewed separately.

What's the motivation for merging all of the PRs together into one large change?

@husobee
Copy link
Contributor Author

husobee commented Mar 29, 2023

I'm confused as to what parts here are relevant specifically to the nitro-shim utilities that we need done ASAP to get the star randomness server unblocked versus what's specific to the payments services that can be reviewed separately.

This directory is specifically what should be focused on: https://github.com/brave-intl/bat-go/tree/nitro-payments-dev/nitro-shim and https://github.com/brave-intl/bat-go/tree/nitro-payments-dev/services/nitro for how we are running services in the enclave.

The rest of this PR is for the payments service which runs within the enclave.

What's the motivation for merging all of the PRs together into one large change?

It was becoming a nightmare to keep each branch up to date and make any progress since each of these are tightly integrated.

Copy link
Member

@kdenhartog kdenhartog left a comment

Choose a reason for hiding this comment

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

Just spotted one minor issue with the ports which allowed invalid port numbers. Other than that just basic version bumping and this is good to go. @husobee do you mind bumping the versions when you're cherry picking the commits?

nitro-shim/Dockerfile Outdated Show resolved Hide resolved
nitro-shim/tools/viproxy/go.mod Outdated Show resolved Hide resolved

require (
github.com/brave-experiments/viproxy v0.0.0-20220310233634-c31e539539bf
github.com/mdlayher/vsock v1.1.1
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
github.com/mdlayher/vsock v1.1.1
github.com/mdlayher/vsock v1.2.0

nitro-shim/tools/viproxy/go.mod Outdated Show resolved Hide resolved
if err != nil {
l.Fatal("Couldn't turn CID into integer.")
}
port, err := strconv.ParseUint(fields[1], 10, 32)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
port, err := strconv.ParseUint(fields[1], 10, 32)
port, err := strconv.ParseUint(fields[1], 0, 16)

This can return an invalid port number, so here's a fix for it.

Choose a reason for hiding this comment

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

Unlike TCP ports, CID ports are 32 bits in size, so this should be correct after all. Probably worth a comment though!

Copy link
Member

Choose a reason for hiding this comment

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

Ahh thank you, I wasn't aware there was a different addressing scheme for this. I just did a bit more research on it and found this doc: https://www.man7.org/linux/man-pages/man7/vsock.7.html where it defines the address format as you describe.

Are there any ports that we should be excluding support from there?

services/nitro/nitro.go Outdated Show resolved Hide resolved
nitro-shim/tools/viproxy/go.mod Outdated Show resolved Hide resolved
nitro-shim/tools/gvproxy/go.mod Outdated Show resolved Hide resolved
nitro-shim/tools/gvproxy/go.mod Outdated Show resolved Hide resolved
nitro-shim/tools/gvproxy/gvproxy.go Outdated Show resolved Hide resolved
@kdenhartog
Copy link
Member

Looks like all the port suggestions I made were incorrect because I misunderstood that a different addressing scheme is in use with these sockets. I've resolved them. Looking at what's left the only thing blocking would be bumping versions and making sure the brave-experiment references point at all of the brave packages now and the nitro-shim work is G2G then.

@husobee
Copy link
Contributor Author

husobee commented Mar 30, 2023

Looks like all the port suggestions I made were incorrect because I misunderstood that a different addressing scheme is in use with these sockets. I've resolved them. Looking at what's left the only thing blocking would be bumping versions and making sure the brave-experiment references point at all of the brave packages now and the nitro-shim work is G2G then.

#1803 has the suggested implementations from security review for nitro-shim/nitro-utils

@husobee husobee force-pushed the nitro-payments-dev branch 2 times, most recently from 88c40cc to ddd8c42 Compare May 4, 2023 22:00
Comment on lines 62 to 65
imageSha384 := ""
pcr0 := ""
pcr1 := ""
pcr2 := ""
Copy link
Member

Choose a reason for hiding this comment

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

Security blocking: let's pull these in via an environment variable rather than hardcoding them here (or some other method to configure this) so that we're not forced to utilize the same value across an environment.

Sneagan and others added 2 commits March 20, 2024 19:59
* Update Zebpay State Machine

- Change Zebpay Pay function to proceed with submission when checking
  the status of a transaction results in a 404.
- Update live Zebpay test to work correctly with the new changes.

Co-authored-by: Pavel Brm <5097196+pavelbrm@users.noreply.github.com>
* Add prior PCRs
onyb and others added 2 commits April 30, 2024 12:36
Solana state machine, payout key generation and approval, as well as some improvements to transaction submission.

---------

Co-authored-by: Anirudha Bose <anirudha.bose@alumni.cern>
Co-authored-by: Jackson <jegan@brave.com>
Co-authored-by: eV <evq@brave.com>
Co-authored-by: Kyle Den Hartog <kdenhartog@users.noreply.github.com>
Copy link
Contributor

@pavelbrm pavelbrm left a comment

Choose a reason for hiding this comment

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

Okay, I've gone over this PR. Please don't consider this review full or thorough by any measure – 16k of changes across 200 files without knowing the specifics of the project.

It's a weird review – it's neither high- nor sufficiently low-level. Rather something in between, because otherwise is impossible in the circumstances this set of changes has put us in.

I appreciate that people have spent long hours working on it, and I also appreciate the fact that this code is able to do something.

However, the point of review is to explore and establish some facts about the proposed implementation. Therefore, please don't take what follows personally.

Main concerns:

  • this PR introduces 15 (!!!) new Go modules, which makes me think that there is little understanding of what a Go module is for, when to create one, and what are the implications of doing it in general, and in this repository in particular;
    • this is already enough to turn this PR down;
  • this PR changes code that is shared and used by other services;
    • this too is enough to reject this PR as it is;
    • and specifically with regards to SKUs;
      • as I pointed out in the comments (please do find it), it's not OK to merge this and change SKUs at the same time;
      • either pull the middleware changes in a separate PR;
      • or add the new code you need, leave the old code used by SKUs where it is, and then do a clean up;
  • the majority of the code is hardly maintainable, testable, readable;
  • the majority of the code does not have proper unit testing;
  • the abstractions this PR has offered seem to be created upfront (instead of derived from observation and experience) leading to the implementations bending backwards to fit in;
  • the code continues to build on and perpetuates the broken patterns that Bat-Go has been plagued with, making it almost impossible to change;
    • @clD11 and I have been working on improving Wallet and SKUs, but with the addition of the new 16k lines it's hard to see the light at the end of the tunnel.

On the one hand, there has been a big effort behind this PR. On the other, the engineering quality of it not where it can and should be, hence I am leaving it to others to approve.

Please, however, take a note of the changes that touch SKUs, and address that in one of the offered ways. Thank you!


Comment on lines +259 to +274
serverURL, ok := ctx.Value(appctx.BitflyerServerURLCTXKey).(string)
if !ok || len(serverURL) == 0 {
return nil, ErrInvalidServerURL
}

// get the proxy url if applicable
proxyURL, ok := ctx.Value(appctx.BitflyerProxyURLCTXKey).(string)
if !ok || len(proxyURL) == 0 {
proxyURL = ""
}

// get the token
token, ok := ctx.Value(appctx.BitflyerTokenCTXKey).(string)
if !ok || len(token) == 0 {
token = ""
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Preferably, these must be handled outside of this constructor, ideally – in the main function, and then passed down here in as arguments.

The use of ctx as a container for configuration completely obscures the dependencies this client has, and is just wrong.

This is a pattern throughout the entire codebase, so I won't point out it again.

)

// TransferLimit is the limit of BAT any client can transfer
var TransferLimit = decimal.NewFromInt(300)
Copy link
Contributor

Choose a reason for hiding this comment

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

Global variables are bad. Global public variables are twice as bad. Global public variables in new code – threefold. This should have been a configuration value passed to where it's needed and held by what's calling the thing that needs the limit (and outlives the calls).

defer cancel()
if c.client.Timeout > 0 {
// put a timeout on the request context
reqCtx, cancel := context.WithTimeout(context.Background(), c.client.Timeout)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should not be context.Background() replaced with the incoming ctx?

Comment on lines +219 to +234
serverURL, ok := ctx.Value(appctx.GeminiServerURLCTXKey).(string)
if !ok || len(serverURL) == 0 {
return nil, ErrInvalidServerURL
}

// get the proxy url if applicable
proxyURL, ok := ctx.Value(appctx.GeminiProxyURLCTXKey).(string)
if !ok || len(proxyURL) == 0 {
proxyURL = ""
}

// get the token
token, ok := ctx.Value(appctx.GeminiTokenCTXKey).(string)
if !ok || len(token) == 0 {
return nil, ErrInvalidToken
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same issue as pointed above for Bitflyer.

}

// Client abstracts over the underlying client
type Client interface {
Copy link
Contributor

Choose a reason for hiding this comment

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

Interfaces like this should be declared at the call site, and preferably be private.

In some cases, like with the context package, a constructor may return an interface instead of a concrete type. This is often used in combination with the concrete type itself being unexported (private) whilst the interface is exported (public). Such an arrangement is a pattern for preventing the call site from knowing any details about the implementation. (There can be other situations when returning an interface instead of a concrete type is valid).

On the other hand, things such as bytes.Buffer don't declare any of the interfaces they implement upfront. This allows it to implement multiple interfaces, and each call site to impose its own restrictions.

Most clients fall in to the second group. It's the call site's responsibility to decide what is needed. So they impose restrictions. This allows for more focussed control over dependencies and testing.

Interfaces declared upfront are a huge pain for the call site. That's the reason we've got so many fundamentally wrong mock generators. They are not, strictly speaking, necessary, when the call site is conscious of its dependencies. It allows then for focussed mocking with little code.

Constructors in this package should return *HTTPClient. The Client interface should be gone. The call site should declare a private interface declaring the requirements for a client.

When we declare interfaces like it's done in this code, it goes against the most important and distinguishing features of Go – that interfaces can and generally should be declared where used. This code could have instead been written in a classic OOP language (Java, C#, etc) if this feature is ignored. And when ignored, we get all the pains that are so widespread in Bat Go (though services/skus has been getting healthier recently).

Comment on lines +34 to +38
baseURI := os.Getenv("NITRO_API_BASE")

client, err := client.NewWithHTTPClient(baseURI, "", &http.Client{
Timeout: time.Second * 60,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Configuration and client should be obtained and constructed once at the worker creation time and re-used.

@@ -839,3 +840,340 @@ func (mr *MockDatastoreMockRecorder) UpdateTransaction(orderID, externalTransact
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTransaction", reflect.TypeOf((*MockDatastore)(nil).UpdateTransaction), orderID, externalTransactionID, status, currency, kind, amount)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Leave SKUs alone.

@@ -85,7 +85,7 @@ func (ucr *UpholdCreationRequest) Decode(ctx context.Context, v []byte) error {
return fmt.Errorf("failed to decode signed creation request: %w", err)
}

var signedTx uphold.HTTPSignedRequest
var signedTx httpsignature.HTTPSignedRequest
Copy link
Contributor

Choose a reason for hiding this comment

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

Has this been tested?

@@ -0,0 +1,195 @@
package payments
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see many tests for this package.

if err != nil {
log.Fatalf("failed to open prepared report file: %v\n", err)
}
defer preparedReportFile.Close()
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 not going to work because of the Fatal below (and above). Don't call Fatal from random places. Log with error and return, if returning an error is not an option.

Sneagan and others added 20 commits May 6, 2024 17:26
* Add disaster recovery command
* Preserve solana key and improve logging

* Remove unneeded import

* Fix error logging
- makefile: new pcrs target combining chained reproducible image build and enclave build
- eifbuild: allow for direct enclave build without pulling from image registry
- makefile: add cache used during reproducible image builds
- eifbuild: split command if passed as a single string
- eifbuild: prompt on empty env or command
* Change Authorize function to match spec

* Add IsAuthorized helper to avoid magic number proliferation

* Simplify bool check

Co-authored-by: eV <8796196+evq@users.noreply.github.com>

---------

Co-authored-by: eV <8796196+evq@users.noreply.github.com>
* Add ipython profile implementing payments shell

* update README
@kdenhartog
Copy link
Member

Closing since this PR isn't of much use to us at this point.

From the sounds of it we're planning to either split this code into a separate repository or if the intent is to keep it in here we'll re-open a new PR to merge this code in. At this point though it's clear it won't be done with this PR and next steps for us is to get back to using the normal PR process to merge onto this feature branch like we've been doing more recently.

@kdenhartog kdenhartog closed this May 24, 2024
This was referenced May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet