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 networked-signer tests #3613

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

Add networked-signer tests #3613

wants to merge 39 commits into from

Conversation

richardpringle
Copy link
Contributor

@richardpringle richardpringle commented Dec 19, 2024

  • Move local-signer to its own package
  • Split bls tests into signing tests and other generic bls operations
  • Add test for networked signer

Why this should be merged

I moved the tests to make it easier to test multiple signer implementations.

How this works

I split the tests up. There are tests in the bls package as well as the individual signers. There are also a couple of tests in the blstest package as well.

How this was tested

See above

Need to be documented in RELEASES.md?

nope

utils/crypto/bls/signers/local/local.go Outdated Show resolved Hide resolved
utils/crypto/bls/signers/local/local.go Outdated Show resolved Hide resolved
utils/crypto/bls/signers/local/local.go Outdated Show resolved Hide resolved
utils/crypto/bls/signers/local/local.go Outdated Show resolved Hide resolved
utils/crypto/bls/signers/local/local.go Outdated Show resolved Hide resolved
utils/crypto/bls/signers/local/local.go Outdated Show resolved Hide resolved
utils/crypto/bls/test/bls_benchmark_test.go Outdated Show resolved Hide resolved
@richardpringle richardpringle marked this pull request as ready for review January 7, 2025 22:30
@richardpringle richardpringle requested a review from marun as a code owner January 7, 2025 22:30
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.

(No action required) Would it make sense to separate the functional changes introduced by this PR from the considerable number of non-functional changes (e.g. renames) to simplify review of such an otherwise large PR?

@richardpringle
Copy link
Contributor Author

(No action required) Would it make sense to separate the functional changes introduced by this PR from the considerable number of non-functional changes (e.g. renames) to simplify review of such an otherwise large PR?

Great question... maybe?

I would argue that the overall cost of review doesn't change that much as most files just contain renames. I would have had to change the tests no matter what. I could have added the json-rpc signer in a second PR, but is that really beneficial?

I can do that if you (@marun) or any other reviewers would like, I don't mind.

@richardpringle richardpringle requested a review from marun January 8, 2025 15:49
config/config.md Outdated
@@ -399,7 +399,6 @@ specified. If not given, uses default genesis data.

See the documentation for the genesis JSON format [here](https://github.com/ava-labs/avalanchego/blob/master/genesis/README.md) and an example used for the local network genesis [here](https://github.com/ava-labs/avalanchego/blob/master/genesis/).


Copy link
Contributor

Choose a reason for hiding this comment

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

nit: undo diff in this line since it's unrelated

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: rename this path to bls/signer/localsigner. Plural package names read weirdly (e.g if we start writing code in signers and have an array of signers how do we refer to that? signerses?)

"errors"
"runtime"

"github.com/ava-labs/avalanchego/utils/crypto/bls" // Import the parent package
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Comments on why we're importing a package are unnecessary unless there's some side-effect of the import we depend on

Comment on lines +8 to +9
Sign(msg []byte) *Signature
SignProofOfPossession(msg []byte) *Signature
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like this interface looks cleaner if we just merge these two function signatures and just add the ciphertext as a parameter. Having a separate function signature for each ciphertext feels like it just bloats the interface... but not sure what others think.

Copy link
Contributor Author

@richardpringle richardpringle Jan 14, 2025

Choose a reason for hiding this comment

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

I actually think that we should have a ProofOfPossession() (no parameters) method. We shouldn't really be doing proof-of-possession signatures of anything other than the pubkey.

Regardless, that change would be beyond the scope of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to elaborate here, the reason that I prefer to have both APIs over a single function where one has to pass in the digest is because I think this should be opaque to the caller. It's an implementation detail that these two methods only differ in the digest used for signing.

@@ -35,7 +37,7 @@ var (
)

func BenchmarkSign(b *testing.B) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Something awkward about this test structure from the perspective of localsigner is that this test benchmarks the localsigner implementation (knows how to sign), not bls (knows operations across bls keys like aggregation/verification), so it feels like this belongs under something like signer/localsigner/local_signer_test.go since bls isn't even used here.

Maybe an alternative to this structure would be to have:

  1. bls/bls_test.go - tests bls (operations across keys)
  2. signer/signertest/signertest.go - has a common test suite that you can plug in any implementation of Signer into to verify that the interface implementation is correct
  3. signer/localsigner/localsigner_test.go - uses the test suite in signertest
  4. signer/jsonrpc - uses the test suite in signertest

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: message.go, or just define these types server.go

listener net.Listener
}

func NewSignerService() *signerService {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: export signerService since it's being used from an exported function

Comment on lines +31 to +33
if err != nil {
panic(err)
}
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 bubble up the error here instead of panic'ing? I think for the other panics it's reasonable if we don't want to make the diff bigger because it's an interface change + the panic's wont trigger because the network signer isn't actually used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The constructor isn't actually part of the interface. Easy to add this, 👍

Comment on lines 65 to 69
var signerFns = []func() (Signer, error){
localSignerFn,
serverSignerFn,
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the tests in this file are a bit complex and also are now testing integration across the jsonrpc signer and localsigner which I feel like is unnecessary - if they correctly implement the Signer interface they're just returning plain data types and not interfaces so the operations in bls should still work across them. I think if we go with the earlier comment's suggestion we can probably get rid of a lot of these tests.

// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package jsonrpc
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this package name is inconsistent with localsigner... maybe we rename localsigner to local or jsonrpc to jsonrpcsigner. Alternatively we can pull this out of the PR and put it into a subsequent one.

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 we're happy with how testing is split up, I don't mind pulling it out. The only thing is that the way I split up the testing might look a little silly with only a single implementation.

I'm easy though, either way works.

I also think jsonrpcsigner makes the most sense here and will make that change regardless.

@richardpringle richardpringle marked this pull request as draft January 13, 2025 22:59
}

return bls.Verify(aggPK, aggSig, message), nil
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I just expose this function from the bls library?

}
})
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to individual implementations

}

return Verify(aggPK, aggSig, message), nil
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function is only used in tests right now. I'm not sure if there's a better way to expose it

Copy link
Contributor

Choose a reason for hiding this comment

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

The preferred approach (in this repo) is to use *test packages for test-only code: #3238

As for this functions utility outside of tests, I can't think of a use case off the top of my head where the caller would be both the signer and verifier.

@richardpringle richardpringle marked this pull request as ready for review January 14, 2025 22:47
Copy link
Contributor

@cam-schultz cam-schultz left a comment

Choose a reason for hiding this comment

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

The structure makes sense to me, and I appreciate the comprehensive test coverage you included. I left some comments that should hopefully be straightforward to answer/address.

}

return Verify(aggPK, aggSig, message), nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The preferred approach (in this repo) is to use *test packages for test-only code: #3238

As for this functions utility outside of tests, I can't think of a use case off the top of my head where the caller would be both the signer and verifier.

)

func BenchmarkSign(b *testing.B) {
server, privateKey, _ := NewSigner(require.New(b))
Copy link
Contributor

Choose a reason for hiding this comment

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

What "server" is running here? Trying to understand what this benchmark measures distinct from the local signer benchmark.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's the motivation to use gorilla/rpc/v2/json2 instead of avalanchego/utils/rpc to build out this package? Most other rpc packages in Avalanchego use avalanchego/utils/rpc/avalanchego/utils/json, both of which use gorilla internally.

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.

5 participants