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

Signing and SIDs via Registrant, refactor tests #112

Merged
merged 15 commits into from
Aug 15, 2024
Merged

Conversation

richardhuaaa
Copy link
Contributor

Apologies, this one exploded in size once I realized I had to refactor the tests. This PR:

  1. Creates a 'registrant' struct that holds the signing key and node ID:
    • On creation, verify that the specified private key matches both the registry and what is in the database
    • Issue SID's and sign payloads using the signing key and node ID
  2. Refactors the tests:
    • Plumb registrant into existing tests
    • Allow multiple servers to run simultaneously without overwriting each other's state
    • Remove circular dependencies with the new mocks

Comment on lines +44 to +60
db, err := db.NewDB(
ctx,
options.DB.WriterConnectionString,
options.DB.WaitForDB,
options.DB.ReadTimeout,
)
if err != nil {
log.Fatal("initializing database", zap.Error(err))
}

s, err := server.NewReplicationServer(
ctx,
log,
options,
registry.NewFixedNodeRegistry([]registry.Node{}),
db,
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pulled the DB out of the replication server for dependency injection purposes. Otherwise, multiple instantiated servers in a test would share the same database and/or have cleanup issues.

Copy link
Contributor

Choose a reason for hiding this comment

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

That makes sense

Comment on lines +7 to +13
-- name: InsertNodeInfo :one
INSERT INTO node_info(node_id, public_key)
VALUES (@node_id, @public_key)
RETURNING *;

-- name: SelectNodeInfo :one
SELECT * FROM node_info WHERE singleton_id = 1;
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 could have been combined into a single query that fetches the existing record when there is a conflict. Unfortunately, it looks like the methods for doing this in Postgres either impact readability significantly or have weird caveats.

I chose to do this the simple way because server startup performance isn't critical here.

Copy link
Contributor

@neekolas neekolas Aug 15, 2024

Choose a reason for hiding this comment

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

Why does this need to live in the database at all? Can't the NodeRegistry just serve as the source of truth here? Is it purely so that we can error if you change your NodeID/Public Key with the same DB?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, purely so that you get an error if you change either piece of information with the same DB. I imagine it's an easy mistake for partners to make

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. Good to be defensive here. Could definitely see it being an easy mistake to make.

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 just realized, the whole reason I had to refactor the tests was because they weren't passing due to multiple server nodes with different private keys sharing the same DB. So, also an easy mistake for us to make!

db *queries.Queries,
nodeRegistry registry.NodeRegistry,
privateKeyString string,
) (*Registrant, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will split this into util methods

Comment on lines +52 to +53
server1 := NewTestServer(t, dbs[0], registry, privateKey1)
server2 := NewTestServer(t, dbs[1], registry, privateKey2)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we have multiple nodes running with separate DB/private keys but a shared registry

@richardhuaaa richardhuaaa marked this pull request as ready for review August 15, 2024 03:04
@@ -1,4 +1,4 @@
package registry
package registry_test
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Needed to remove circular dependencies - otherwise this test (in the registry package) depends on the mocks package, which depends on the registry package

pkg/utils/sid.go Outdated
const (
nodeIDMask uint64 = 0xFFFF << 48
nodeIDBits uint64 = 16
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to have some really clear comments around how these IDs are supposed to work, since bitmasks are not the most readable.

@richardhuaaa richardhuaaa merged commit 93a8215 into main Aug 15, 2024
4 checks passed
@richardhuaaa richardhuaaa deleted the rich/node-info branch August 15, 2024 18:19
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.

2 participants