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

[CT-1161] add signature verification authenticator #2183

Merged
merged 8 commits into from
Sep 17, 2024
Merged

[CT-1161] add signature verification authenticator #2183

merged 8 commits into from
Sep 17, 2024

Conversation

jayy04
Copy link
Contributor

@jayy04 jayy04 commented Sep 3, 2024

Changelist

[Describe or list the changes made in this PR]

Test Plan

[Describe how this PR was tested (if applicable)]

Author/Reviewer Checklist

  • If this PR has changes that result in a different app state given the same prior state and transaction list, manually add the state-breaking label.
  • If the PR has breaking postgres changes to the indexer add the indexer-postgres-breaking label.
  • If this PR isn't state-breaking but has changes that modify behavior in PrepareProposal or ProcessProposal, manually add the label proposal-breaking.
  • If this PR is one of many that implement a specific feature, manually label them all feature:[feature-name].
  • If you wish to for mergify-bot to automatically create a PR to backport your change to a release branch, manually add the label backport/[branch-name].
  • Manually add any of the following labels: refactor, chore, bug.

Summary by CodeRabbit

  • New Features

    • Introduced a robust authentication framework for handling transaction signing and verification within the Cosmos ecosystem.
    • Added various request structures to facilitate authentication processes, including TrackRequest, ConfirmExecutionRequest, and AuthenticationRequest.
    • Implemented a SignatureVerification authenticator to validate transaction signatures.
  • Bug Fixes

    • Enhanced error handling for invalid signature verifications.
  • Tests

    • Established comprehensive test suites for the authenticator module and SignatureVerification functionality, ensuring reliability and robustness in authentication processes.

@jayy04 jayy04 requested a review from a team as a code owner September 3, 2024 02:51
Copy link

linear bot commented Sep 3, 2024

Copy link
Contributor

coderabbitai bot commented Sep 3, 2024

Walkthrough

The changes introduced a new authentication system within the protocol/x/accountplus/authenticator package of the Cosmos SDK. Key components include structures and functions for handling authentication requests, signature verification, and testing frameworks. The implementation encompasses data structures for transaction signing, utility functions for managing signers and signatures, and a robust testing suite to ensure the functionality of the new authenticator. Additionally, interfaces and request structures were defined to facilitate interaction with the authentication system, enhancing the overall architecture for transaction handling and signature verification.

Changes

Files Change Summary
protocol/x/accountplus/authenticator/authentication_request.go Introduced key data structures (SignModeData, LocalAny, SimplifiedSignatureData, ExplicitTxData) and functions for generating authentication requests, managing signers, and extracting signatures.
protocol/x/accountplus/authenticator/base_test.go Created a test suite (BaseAuthenticatorSuite) for the authenticator module, including setup methods for test accounts and transaction generation functions.
protocol/x/accountplus/authenticator/iface.go Defined an InitializedAuthenticator struct and Authenticator interface outlining methods for authentication processes, including initialization, validation, tracking, and confirming execution.
protocol/x/accountplus/authenticator/requests.go Added request structures (TrackRequest, ConfirmExecutionRequest, AuthenticationRequest) to facilitate interactions with the authentication system, encapsulating essential fields for processing authentication-related transactions.
protocol/x/accountplus/authenticator/signature_authenticator.go Implemented SignatureVerification authenticator for secp256k1 signature verification, including methods for initialization, authentication, tracking, and confirming execution, along with error handling for signature validation.
protocol/x/accountplus/authenticator/signature_authenticator_test.go Established a comprehensive test suite (SigVerifyAuthenticationSuite) for the SignatureVerification functionality, validating various scenarios for signature authentication and ensuring robustness through structured tests.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Authenticator
    participant SignatureVerifier
    participant TransactionManager

    User->>Authenticator: Generate Authentication Request
    Authenticator->>TransactionManager: Retrieve Signers and Signatures
    TransactionManager-->>Authenticator: Return Signers and Signatures
    Authenticator->>SignatureVerifier: Verify Signatures
    SignatureVerifier-->>Authenticator: Return Verification Result
    Authenticator-->>User: Return Authentication Result
Loading

🐰 In a world of blocks and chains,
A rabbit hops through code terrains.
With signatures verified, oh what a sight,
Transactions dance in the moonlight!
New requests and tests, all in a row,
Hooray for the changes, let the blockchain glow! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai generate interesting stats about this repository and render them as a table.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Comment on lines +184 to +186
if txSigners[i].Equals(account) {
msgSignature = single.Signature
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that I am skipping ReplayProtection here.

Osmosis's implementation only compares sequence numbers. since we have our own timestamp nonce logic, probably better to leave it out of the smart account's authenticator flows

Copy link
Contributor Author

@jayy04 jayy04 Sep 3, 2024

Choose a reason for hiding this comment

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

Copy link
Contributor

@teddyding teddyding Sep 16, 2024

Choose a reason for hiding this comment

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

Does GenerateAuthenticationRequest flow get invoked in a new antehandler? And is the regular sigVerficationHandler bypassed when this authenticator is in effect? I assume yes since the regular sigVerificationHandler doesn't understand the alternative authenticator? And if yes, wouldn't we need to protect against replay here?

Lmk if I'm misunderstanding sth

Base automatically changed from jy/smart-account-proto to main September 15, 2024 19:58
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Outside diff range and nitpick comments (1)
protocol/x/accountplus/authenticator/requests.go (1)

7-16: LGTM!

The TrackRequest struct contains all the necessary fields to track an authentication request. The field names are clear and self-explanatory.

Consider adding a comment to explain the purpose of the LocalAny type for clarity. For example:

// LocalAny represents a custom message type used for authentication requests.
Msg LocalAny `json:"msg"`
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between cbd23b1 and c827be1.

Files selected for processing (6)
  • protocol/x/accountplus/authenticator/authentication_request.go (1 hunks)
  • protocol/x/accountplus/authenticator/base_test.go (1 hunks)
  • protocol/x/accountplus/authenticator/iface.go (1 hunks)
  • protocol/x/accountplus/authenticator/requests.go (1 hunks)
  • protocol/x/accountplus/authenticator/signature_authenticator.go (1 hunks)
  • protocol/x/accountplus/authenticator/signature_authenticator_test.go (1 hunks)
Additional comments not posted (26)
protocol/x/accountplus/authenticator/requests.go (1)

29-49: LGTM!

The AuthenticationRequest struct contains all the necessary fields to sign and process an authentication request. The field names are clear and self-explanatory, and the comments provide additional clarity on the purpose of some fields.

protocol/x/accountplus/authenticator/iface.go (2)

8-11: LGTM!

The InitializedAuthenticator struct is well-defined and serves its purpose of wrapping an Authenticator instance with a unique identifier.


15-51: LGTM!

The Authenticator interface is well-designed and comprehensively covers the essential methods required for authentication processes within a blockchain context. The interface methods enable robust transaction verification, management of gas consumption, and ensure the integrity and security of account-authenticator relationships.

protocol/x/accountplus/authenticator/signature_authenticator.go (7)

42-44: LGTM!

The function correctly initializes a new SignatureVerification instance with the provided AccountKeeper.


47-53: LGTM!

The function correctly initializes the PubKey field based on the provided config byte slice. It handles the case when the config length is not equal to the expected secp256k1.PubKeySize by setting the PubKey to nil.


57-80: LGTM!

The function correctly verifies the signature against the transaction data. It consumes gas for the signature verification and handles various scenarios such as simulations, re-checks, and missing public keys. The error messages provide useful information for debugging signature verification failures.


90-105: LGTM!

The function correctly validates the public key size when an authenticator is added. It allows users to pass no data or a valid public key for signature verification. The error message provides clear information about the expected and actual public key sizes.


32-34: LGTM!

The function correctly returns the type of the authenticator as SignatureVerificationType.


36-39: LGTM!

The function correctly returns 0 as the static gas cost. The comment provides clarity on how the gas is consumed based on the public key type in the Authenticate function.


27-30: LGTM!

The SignatureVerification struct correctly defines the necessary fields for a signature authenticator. The AccountKeeper field is used for managing account-related operations, and the PubKey field is used for signature verification. The struct implements the Authenticator interface, ensuring compatibility with the authentication system.

protocol/x/accountplus/authenticator/base_test.go (5)

25-35: LGTM!

The BaseAuthenticatorSuite struct is well-defined and contains all the necessary fields for setting up and running tests. The field names and types are appropriate, making the purpose of each field clear.


37-80: LGTM!

The SetupKeys method correctly sets up the necessary test accounts and keys. It follows a clear sequence of steps for initializing the test environment, including decoding private keys, generating public keys, populating the account keeper, and initializing the test app with a custom genesis state. The implementation is well-structured and free of any apparent issues.


82-122: LGTM!

The GenSimpleTx method correctly generates a simple transaction with the provided messages and signers. It retrieves the account numbers and sequences for the signers from the account keeper, handling the case where an account does not exist by creating a new base account. The transaction is properly generated using the GenTx function with the provided parameters. The implementation is well-structured and free of any apparent issues.


124-174: LGTM!

The GenSimpleTxWithSelectedAuthenticators method correctly generates a simple transaction with the provided messages, signers, and selected authenticators. It retrieves the account numbers and sequences for the signers from the account keeper and creates a base transaction builder using the MakeTxBuilder function with the provided parameters. The selected authenticators are properly set as a non-critical extension option in the transaction builder. The implementation is well-structured and free of any apparent issues.


176-180: LGTM!

The FundAcc method correctly funds a target account with the specified amount using the testutil.FundAccount function. It properly asserts that no error occurs during the funding process. The function is concise and serves its purpose well, with no apparent issues in its logic or implementation.

protocol/x/accountplus/authenticator/authentication_request.go (4)

59-98: LGTM!

The function correctly retrieves signers and signatures from the transaction and validates their lengths. The error handling looks good.


101-120: LGTM!

The function correctly retrieves the signer data for the given account. The logic for handling the genesis block and retrieving the account number and sequence looks good.


124-156: LGTM!

The function correctly extracts the explicit transaction data from the provided transaction and signer data. The error handling for the type assertions and message encoding looks good.


192-284: LGTM!

The function correctly generates an AuthenticationRequest for the provided transaction. The logic for retrieving the signers, signatures, signer data, explicit transaction data, and sign bytes looks good. The handling of the simulate flag and the building of the AuthenticationRequest struct are also correct.

protocol/x/accountplus/authenticator/signature_authenticator_test.go (7)

1-23: LGTM!

The import statements are correctly formatted, organized, and relevant to the functionality of the test file. There are no unused imports.


25-29: LGTM!

The test suite struct definition is correctly formatted and follows the common pattern of embedding a base suite. The SigVerificationAuthenticator field is of the correct type for testing.


31-49: LGTM!

The test function and setup/teardown methods are correctly defined. The SetupTest method properly initializes the SigVerificationAuthenticator for testing, and the TearDownTest method ensures cleanup of the test environment.


51-66: LGTM!

The struct definitions for SignatureVerificationTestData and SignatureVerificationTest are correctly formatted. The fields in SignatureVerificationTestData cover various scenarios for testing signature verification, and the SignatureVerificationTest struct provides a convenient way to define test cases.


68-314: LGTM!

The test function TestSignatureAuthenticator is well-structured and follows the table-driven testing approach. The test cases cover various scenarios for signature verification, including successful and unsuccessful cases, single and multiple signers, and different combinations of messages and signatures.

The test logic is comprehensive and checks for the expected outcomes based on the test case data. The use of helper functions GenTx and GenerateAuthenticationRequest enhances the readability and maintainability of the test code.

Overall, the test function provides thorough coverage for the signature verification functionality.


316-386: LGTM!

The helper function MakeTxBuilder is well-implemented and correctly creates a transaction builder with the provided messages, fees, gas, and signatures. The function properly sets up the signature data and populates the transaction builder with the necessary information.

The function also handles the signing of the transaction using the provided private keys, ensuring that the transaction is properly signed. The function returns the transaction builder and any error encountered during the process, providing a convenient way to create signed transactions for testing purposes.

Overall, the MakeTxBuilder function is a useful utility for generating signed transactions in the test suite.


388-406: LGTM!

The helper function GenTx is a convenient utility for generating signed mock transactions. It leverages the MakeTxBuilder function to create a transaction builder with the provided parameters, ensuring that the transaction is properly constructed and signed.

The function retrieves the signed transaction from the transaction builder using the GetTx method and returns it along with any error encountered during the process. This makes it easy to generate signed transactions for testing purposes.

Overall, the GenTx function is a useful addition to the test suite, simplifying the process of creating signed mock transactions.

Comment on lines +18 to +27
type ConfirmExecutionRequest struct {
AuthenticatorId string `json:"authenticator_id"`
Account sdk.AccAddress `json:"account"`
FeePayer sdk.AccAddress `json:"fee_payer"`
FeeGranter sdk.AccAddress `json:"fee_granter,omitempty"`
Fee sdk.Coins `json:"fee"`
Msg LocalAny `json:"msg"`
MsgIndex uint64 `json:"msg_index"`
AuthenticatorParams []byte `json:"authenticator_params,omitempty"`
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider merging TrackRequest and ConfirmExecutionRequest into a single struct.

The ConfirmExecutionRequest struct is identical to TrackRequest in terms of fields and their types. Having two identical structs with different names may lead to confusion and duplication of code.

Consider merging TrackRequest and ConfirmExecutionRequest into a single struct to avoid duplication. For example:

type AuthenticationRequest struct {
	AuthenticatorId     string         `json:"authenticator_id"`
	Account             sdk.AccAddress `json:"account"`
	FeePayer            sdk.AccAddress `json:"fee_payer"`
	FeeGranter          sdk.AccAddress `json:"fee_granter,omitempty"`
	Fee                 sdk.Coins      `json:"fee"`
	Msg                 LocalAny       `json:"msg"`
	MsgIndex            uint64         `json:"msg_index"`
	AuthenticatorParams []byte         `json:"authenticator_params,omitempty"`
	RequestType         string         `json:"request_type"` // "track" or "confirm_execution"
}

If there are specific reasons for keeping them separate, add comments to explain the difference in their purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

2 participants