Skip to content

Conversation

@neekolas
Copy link
Contributor

@neekolas neekolas commented Feb 25, 2025

TL;DR

Updated the PayerEnvelope field in UnsignedOriginatorEnvelope to use serialized bytes instead of a nested message.

Warnings

  • This will break all payloads on the network and in the smart contracts. We should replace all the contracts in testnet-staging when we deploy
  • This will require changes to libxmtp (cc@insipix @mchenani)

What changed?

  • Changed PayerEnvelope field to PayerEnvelopeBytes in UnsignedOriginatorEnvelope proto message
  • Updated code to serialize/deserialize PayerEnvelope when reading/writing
  • Added new helper method NewPayerEnvelopeFromBytes to handle deserialization
  • Updated tests to handle the new serialized format
  • Updated proto generation to use new branch with serialized payer envelope

How to test?

  • Run existing tests which have been updated to handle the new serialization format
  • Verify envelope creation and parsing still works as expected
  • Check that proto generation completes successfully with the new branch

Why make this change?

This change improves message handling by serializing the PayerEnvelope rather than nesting it directly. This provides better encapsulation and potentially more efficient processing of envelopes in the system.

Summary by CodeRabbit

  • New Features

    • Introduced a utility to build message envelopes directly from raw data for more efficient processing.
  • Bug Fixes

    • Enhanced error handling and data serialization during message publication and identity updates, leading to improved system stability.
    • Streamlined the envelope signing process by removing unnecessary data conversions.
  • Tests

    • Updated tests to validate the refined envelope handling and error management improvements.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2025

Walkthrough

This pull request refactors various envelope handling workflows across the codebase. It introduces a new variable for unmarshalling the payer envelope in tests, enhances error handling in envelope construction within service methods, and transitions envelope creation to operate on byte representations. Modifications span API service functions, envelope utility methods, and indexing and registrant logic, ensuring that errors are caught earlier and that envelope data is consistently serialized and processed.

Changes

File(s) Summary
pkg/api/message/publish_test.go Modified TestPublishEnvelope: introduced a new payerEnv variable and altered the unmarshalling of the client envelope via payerEnv.GetUnsignedClientEnvelope().
pkg/api/payer/service.go Enhanced error handling in publishToBlockchain; updated buildUnsignedOriginatorEnvelopeFromChain to return an envelope and an error; ensured envelope serialization from a PayerEnvelope struct with proper error checks.
pkg/envelopes/payer.go,
pkg/envelopes/unsignedOriginator.go
Added NewPayerEnvelopeFromBytes function; modified envelope construction to use byte representations; introduced new method PayerEnvelopeBytes() as an accessor for envelope byte data.
pkg/indexer/storer/groupMessage.go,
pkg/indexer/storer/identityUpdate.go
Updated error handling in StoreLog: separated envelope building via buildOriginatorEnvelope, incorporated error checking, and modified function signatures to return errors appropriately during envelope construction for signing.
pkg/registrant/registrant.go,
pkg/registrant/registrant_test.go
Refactored SignStagedEnvelope by removing direct unmarshalling of the payer envelope; now assigns raw envelope bytes directly; updated tests to unmarshal these bytes and validate the result, removing the invalid envelope test case.
pkg/testutils/envelopes/envelopes.go Modified CreateOriginatorEnvelope: replaced direct PayerEnvelope assignment with a marshaling step producing PayerEnvelopeBytes, including error checking for the marshaling process.

Sequence Diagram(s)

sequenceDiagram
    participant APIService
    participant EnvelopeBuilder
    participant BlockchainPublisher

    APIService->>EnvelopeBuilder: buildUnsignedOriginatorEnvelopeFromChain(targetOriginator, sequenceID, clientEnvelope)
    alt Error in envelope construction
        EnvelopeBuilder-->>APIService: error
        APIService-->>APIService: Return error response
    else Successfully constructed envelope
        EnvelopeBuilder-->>APIService: envelope bytes
        APIService->>BlockchainPublisher: publishToBlockchain(envelope bytes)
        BlockchainPublisher-->>APIService: success response
    end
Loading
sequenceDiagram
    participant Storer
    participant EnvelopeBuilder
    participant Signer

    Storer->>EnvelopeBuilder: buildOriginatorEnvelope(seqID, message)
    alt Error during envelope building
        EnvelopeBuilder-->>Storer: error
        Storer-->>Storer: Log error and return NewLogStorageError
    else Envelope built successfully
        EnvelopeBuilder-->>Storer: unsigned originator envelope
        Storer->>Signer: buildSignedOriginatorEnvelope(envelope)
        Signer-->>Storer: signed envelope
    end
Loading

Possibly related PRs

Suggested reviewers

  • mkysel
  • fbac

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 golangci-lint (1.62.2)

Error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24)
Failed executing command with error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24)


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 134c35d and 3fa2947.

⛔ Files ignored due to path filters (1)
  • pkg/proto/xmtpv4/envelopes/envelopes.pb.go is excluded by !**/*.pb.go, !pkg/proto/**
📒 Files selected for processing (9)
  • pkg/api/message/publish_test.go (1 hunks)
  • pkg/api/payer/service.go (3 hunks)
  • pkg/envelopes/payer.go (1 hunks)
  • pkg/envelopes/unsignedOriginator.go (1 hunks)
  • pkg/indexer/storer/groupMessage.go (1 hunks)
  • pkg/indexer/storer/identityUpdate.go (2 hunks)
  • pkg/registrant/registrant.go (1 hunks)
  • pkg/registrant/registrant_test.go (1 hunks)
  • pkg/testutils/envelopes/envelopes.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • pkg/envelopes/payer.go
  • pkg/indexer/storer/groupMessage.go
  • pkg/testutils/envelopes/envelopes.go
  • pkg/api/message/publish_test.go
  • pkg/registrant/registrant.go
  • pkg/envelopes/unsignedOriginator.go
  • pkg/api/payer/service.go
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Test (Node)
  • GitHub Check: Build pre-baked anvil-xmtpd
🔇 Additional comments (5)
pkg/registrant/registrant_test.go (1)

277-280: Good implementation of fix for nil pointer dereference.

The code now properly initializes the PayerEnvelope before unmarshalling, which fixes the previously identified issue. This change aligns with the PR objective of transitioning to a bytes representation of the PayerEnvelope.

pkg/indexer/storer/identityUpdate.go (4)

158-162: Improved error handling for envelope creation.

These changes enhance error handling by properly checking and handling potential errors from buildOriginatorEnvelope. This is a good improvement that prevents potential issues from propagating through the system.


164-166: Logical code flow improvement.

The refactoring to first build the envelope and then pass it to the signing function improves code clarity and allows for better error handling. This change aligns with the separation of concerns principle.


170-170: Error handling strategy alignment.

Changed error handling to mark the error as non-retriable (false), which is consistent with the approach in the envelope building error handling on lines 158-162.


252-267:

Details

❓ Verification inconclusive

Payloads serialization implementation meets PR objectives.

This implementation correctly changes the PayerEnvelope field to utilize serialized bytes instead of a nested message. The function now:

  1. Creates a PayerEnvelope with the client envelope bytes
  2. Marshals it to bytes
  3. Assigns the bytes to PayerEnvelopeBytes in the UnsignedOriginatorEnvelope

This change aligns with the PR objectives to enhance message handling efficiency through serialization.

As mentioned in the PR objectives, this change will break existing payloads on the network and smart contracts. Verify that there's a plan for deploying this change and replacing contracts in testnet-staging:


🏁 Script executed:

#!/bin/bash
# Search for related test files to ensure they've been updated for the new serialization format
rg -l "PayerEnvelopeBytes" --type go

Length of output: 266


Payload Serialization Update: Confirm Deployment Strategy on Testnet-Staging

The implementation in pkg/indexer/storer/identityUpdate.go correctly marshals the PayerEnvelope and assigns its serialized bytes to the PayerEnvelopeBytes field. A search for "PayerEnvelopeBytes" across the repository shows that the updated serialization is referenced in several test and service files (e.g., pkg/api/payer/service.go, pkg/api/message/publish_test.go, pkg/testutils/envelopes/envelopes.go, pkg/envelopes/unsignedOriginator.go, pkg/registrant/registrant.go, and pkg/registrant/registrant_test.go), which suggests that tests have been updated accordingly.

Action Required:
Since this change will break existing payloads on the network and smart contracts, please ensure that a robust plan for deploying the change—including updating/replacing contracts in the testnet-staging environment—is in place and clearly communicated.

✨ Finishing Touches
  • 📝 Generate Docstrings

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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 generate docstrings to generate docstrings for this 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.

Copy link
Contributor Author

neekolas commented Feb 25, 2025

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

🧹 Nitpick comments (3)
pkg/api/payer/service.go (3)

273-285: Include additional context in error messages
When returning an error from buildUnsignedOriginatorEnvelopeFromChain, consider logging the SequenceId and desiredOriginatorId for richer diagnostics.


298-309: Use consistent error logging with context
As in the previous block, consider including details like SequenceId and desiredOriginatorId in the error logs for easier troubleshooting.


369-385: Use chain timestamp instead of local time
Currently, time.Now().UnixNano() is used, which might diverge from on-chain data. Consider adopting the block timestamp or another chain-derived time source for better consistency if needed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e0878f and 375c3e7.

⛔ Files ignored due to path filters (1)
  • pkg/proto/xmtpv4/envelopes/envelopes.pb.go is excluded by !**/*.pb.go, !pkg/proto/**
📒 Files selected for processing (10)
  • dev/gen-protos (1 hunks)
  • pkg/api/message/publish_test.go (1 hunks)
  • pkg/api/payer/service.go (3 hunks)
  • pkg/envelopes/payer.go (1 hunks)
  • pkg/envelopes/unsignedOriginator.go (1 hunks)
  • pkg/indexer/storer/groupMessage.go (1 hunks)
  • pkg/indexer/storer/identityUpdate.go (2 hunks)
  • pkg/registrant/registrant.go (1 hunks)
  • pkg/registrant/registrant_test.go (1 hunks)
  • pkg/testutils/envelopes/envelopes.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Push Docker Images to GitHub Packages (xmtpd-cli)
  • GitHub Check: Push Docker Images to GitHub Packages (xmtpd)
  • GitHub Check: Build pre-baked anvil-xmtpd
🔇 Additional comments (13)
dev/gen-protos (1)

4-4:

Details

❓ Verification inconclusive

Branch change for protobuf generation.

The source branch for protobuf generation has been changed from the main branch to nm/serialize-payer-envelope. This aligns with the overall PR objective of changing the payer envelope to a bytes field.

You should ensure that the nm/serialize-payer-envelope branch on the proto repository has been merged or is stable before relying on it for builds. Otherwise, there's a risk of inconsistency if the branch is later modified or deleted.


🏁 Script executed:

#!/bin/bash
# Check if the branch exists in the repo
gh api repos/xmtp/proto/branches/nm/serialize-payer-envelope --silent || echo "Warning: Branch nm/serialize-payer-envelope does not exist or is not accessible"

Length of output: 71


Action Required: Verify the stability of the nm/serialize-payer-envelope branch

The shell script didn’t output any error, which indicates that the branch likely exists, but it doesn’t confirm its stability or merge status. Please manually verify that this branch is stable (or has been merged as needed) before relying on it for protobuf generation.

  • The branch was detected by the CLI check.
  • Manual confirmation of the branch’s stability is still required to avoid potential inconsistencies.
pkg/envelopes/payer.go (1)

36-42: LGTM: New helper function for deserializing PayerEnvelope from bytes.

This new function provides a convenient way to unmarshal bytes into a PayerEnvelope, which is essential for the transition to using byte representation instead of direct objects.

pkg/testutils/envelopes/envelopes.go (1)

121-129: Update to use serialized PayerEnvelope.

The code now correctly serializes the PayerEnvelope to bytes before storing it in the UnsignedOriginatorEnvelope, consistent with the move to byte representation.

pkg/indexer/storer/groupMessage.go (1)

71-75: Good error handling improvement.

Extracting the buildOriginatorEnvelope call and adding explicit error handling before proceeding to buildSignedOriginatorEnvelope makes the code more robust and easier to debug. This improvement isolates the envelope building step and ensures errors are caught and handled earlier in the process.

pkg/api/message/publish_test.go (2)

49-53: Consistent with new envelope bytes approach.

The added code properly unmarshals the payer envelope from bytes, aligning with the architectural change to use byte representations for envelopes throughout the system.


58-58: Updated to use the new payerEnv structure.

This change correctly obtains the unsigned client envelope from the newly created payerEnv instead of the previous approach, maintaining consistency with the architectural changes.

pkg/envelopes/unsignedOriginator.go (2)

26-26: Updated to use byte representation for PayerEnvelope.

This change properly implements the architectural shift to use byte representations for envelopes, using the new NewPayerEnvelopeFromBytes function instead of direct unmarshalling.


34-36: Good addition of accessor method for byte data.

Adding the PayerEnvelopeBytes() method provides a clean way to access the raw byte representation, which is necessary for the new envelope handling approach throughout the codebase.

pkg/registrant/registrant.go (1)

88-88: Simplified envelope handling.

This change directly assigns the raw payer envelope bytes instead of unmarshalling it into an object, which is consistent with the architectural changes across the codebase to use byte representations for envelopes. This approach simplifies the code by removing unnecessary unmarshalling steps.

pkg/indexer/storer/identityUpdate.go (4)

158-162: Well-structured error handling
These lines appropriately capture the error from buildOriginatorEnvelope and mark it as non-retriable, which aligns with the existing error-handling pattern.


165-165: No functional change
The change on this line merely passes the computed originatorEnvelope parameter within the function call, so there's nothing additional to address here.


170-170: Confirm retriability of signature building failures
The code marks this error as non-retriable. If signature failures could be transient (e.g. due to ephemeral system conditions), consider returning a retriable error instead.


253-266: Consistent approach to returning payer envelope bytes
Embedding the PayerEnvelope within UnsignedOriginatorEnvelope is a clear improvement. The usage of time.Now().UnixNano() is acceptable, but be mindful if deterministic timestamps or alignment with on-chain block times become necessary.

@neekolas neekolas force-pushed the 02-25-convert_payer_envelope_to_bytes branch from 375c3e7 to 692804f Compare February 25, 2025 21:26
@mkysel
Copy link
Collaborator

mkysel commented Feb 25, 2025

I can handle the libxmtp stuff

@mkysel
Copy link
Collaborator

mkysel commented Feb 25, 2025

a good practice PR to remind ourselves how to nuke the DB :) We now have some experience with retool, so truncate might be as easy.

Copy link
Contributor Author

If we change the Nodes contract, it'll create a brand new DB. Since we need to migrate GroupMessages and IdentityUpdates contracts as well, and Borja has an updated Nodes contract which needs to go out, we might be able to bundle it all into one release that starts fresh.

@neekolas neekolas force-pushed the 02-24-track_unsettled_usage branch from 3e0878f to e53e8d3 Compare February 26, 2025 16:10
@neekolas neekolas force-pushed the 02-25-convert_payer_envelope_to_bytes branch from 692804f to fd653e2 Compare February 26, 2025 16:10
@neekolas neekolas force-pushed the 02-24-track_unsettled_usage branch from e53e8d3 to 58762d6 Compare February 26, 2025 16:13
@neekolas neekolas force-pushed the 02-25-convert_payer_envelope_to_bytes branch from fd653e2 to 47365e0 Compare February 26, 2025 16:13
@neekolas neekolas marked this pull request as ready for review February 26, 2025 17:19
@neekolas neekolas requested a review from a team as a code owner February 26, 2025 17:19
@neekolas neekolas changed the base branch from 02-24-track_unsettled_usage to graphite-base/553 February 26, 2025 17:44
@neekolas neekolas force-pushed the 02-25-convert_payer_envelope_to_bytes branch 2 times, most recently from 3c18227 to 134c35d Compare February 26, 2025 17:47
@neekolas neekolas changed the base branch from graphite-base/553 to main February 26, 2025 17:47
@neekolas neekolas force-pushed the 02-25-convert_payer_envelope_to_bytes branch 2 times, most recently from 654520e to 134c35d Compare February 26, 2025 18:01
@neekolas neekolas force-pushed the 02-25-convert_payer_envelope_to_bytes branch from 134c35d to 3fa2947 Compare March 4, 2025 18:42
@neekolas neekolas merged commit 165627a into main Mar 4, 2025
8 checks passed
@neekolas neekolas deleted the 02-25-convert_payer_envelope_to_bytes branch March 4, 2025 18:47
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.

4 participants