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

fix: fix Bitcoin incorrect 'origin' in zContext caused by revertAddress option #3192

Merged
merged 6 commits into from
Nov 22, 2024

Conversation

ws4charlie
Copy link
Contributor

@ws4charlie ws4charlie commented Nov 20, 2024

Description

The current implementation of Bitcoin revert address simply replaces sender address with revertAddress in zetaclient, so that the refund should go to the custom revertAddress.

// replace 'sender' with 'revertAddress' if specified in the memo, so that
// zetacore will refund to the address specified by the user in the revert options.
sender := event.FromAddress
if event.MemoStd.RevertOptions.RevertAddress != "" {
    sender = event.MemoStd.RevertOptions.RevertAddress 
}

However, the replacement of sender address will allow impersonating the sender. For example, the sender (it is revertAddress on revert) will be set as the zContext.Origin in zetacore, which is incorrect address.

...
if acc != nil && acc.IsContract() {
    context := systemcontract.ZContext{
	Origin:  from, // this will be set to custom 'revertAddress', which is incorrect
	Sender:  eth.Address{},
	ChainID: big.NewInt(senderChainID),
    }
    res, err := k.DepositZRC20AndCallContract(ctx, context, zrc20Contract, to, amount, message)
    return res, true, err
}
...

The solution:

  • Leave the sender address untouched in zetaclient.
  • Provide an crosschaintypes.RevertOptions with 'revertAddress' in the MsgVoteInbound struct to vote (protocol V1).
  • update zetacore code to take the custom revertAddress for V1 AND Bitcoin chain only.

How Has This Been Tested?

  • Tested CCTX in localnet
  • Tested in development environment
  • Go unit tests
  • Go integration tests
  • Tested via GitHub Actions

Copy link
Contributor

coderabbitai bot commented Nov 20, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces several significant updates to the ZetaChain node, including new features such as the ability to whitelist SPL tokens on Solana, enhancements to build reproducibility, and the integration of SPL deposits and withdrawals. It also refactors existing components, removes the HSM signer from the zetaclient, and improves the zetaclientd CLI. Various fixes address issues related to messaging, peer discovery, and transaction handling. Additionally, the changelog has been updated to reflect these changes and provide a comprehensive overview of the improvements made across multiple versions.

Changes

File Path Change Summary
changelog.md Updated to reflect new features, improvements, refactoring, fixes, and documentation enhancements.
testutil/sample/crosschain.go Added CrossChainTxV2 function for creating CrossChainTx with updated protocol version.
x/crosschain/types/cctx.go Updated AddRevertOutbound method for Bitcoin chains; added new import for chains.
x/crosschain/types/cctx_test.go Added tests for Bitcoin and Ethereum revert address handling; updated import statements.
x/crosschain/types/revert_options.go Introduced GetBTCRevertAddress method for validating Bitcoin revert addresses; added import.
x/crosschain/types/revert_options_test.go Added tests for GetBTCRevertAddress method; updated import statements.
zetaclient/chains/bitcoin/observer/event.go Modified NewInboundVoteFromStdMemo to utilize RevertOptions for handling revert addresses.

Possibly related PRs

Suggested labels

breaking:cli, CONSENSUS_BREAKING_ACK

Suggested reviewers

  • fbac
  • skosito
  • kingpinXD
  • brewmaster012
  • swift1337
  • lumtis

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 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.

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.

@ws4charlie ws4charlie added audit Fixes for issues found in audit chain:bitcoin Bitcoin chain related zetaclient Issues related to ZetaClient zetacore Issues related to ZetaCore CONSENSUS_BREAKING_ACK Acknowledge a consensus breaking change CONSENSUS_TESTS Run make start-e2e-consensus-tests and removed CONSENSUS_BREAKING_ACK Acknowledge a consensus breaking change labels Nov 20, 2024
@ws4charlie ws4charlie marked this pull request as ready for review November 20, 2024 19:52
@gartnera gartnera added CONSENSUS_BREAKING_ACK Acknowledge a consensus breaking change and removed CONSENSUS_TESTS Run make start-e2e-consensus-tests labels Nov 20, 2024
@gartnera
Copy link
Member

Removing CONSENSUS_TESTS and adding CONSENSUS_BREAKING_ACK as this is pretty obviously a consensus breaking change right?

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: 2

🧹 Outside diff range and nitpick comments (7)
x/crosschain/types/revert_options_test.go (1)

50-50: Consider adding more test cases for broader coverage.

Consider adding these test cases to strengthen the test suite:

  1. Mainnet Bitcoin addresses to ensure proper network validation
  2. Specific error message validation for each failure case

Example addition:

t.Run("mainnet address on testnet chain", func(t *testing.T) {
    addr := sample.BtcAddressP2WPKH(t, &chaincfg.MainNetParams)
    actualAddr, valid := types.RevertOptions{
        RevertAddress: addr,
    }.GetBTCRevertAddress(chains.BitcoinTestnet.ChainId)

    require.False(t, valid)
    require.Empty(t, actualAddr)
})
x/crosschain/types/revert_options.go (1)

79-90: Enhance documentation while maintaining solid implementation

The implementation is robust and aligns well with the PR objectives. However, the documentation could be more detailed.

Consider enhancing the documentation to be more explicit about the return values and chainID parameter:

-// GetBTCRevertAddress validates and returns the BTC revert address
+// GetBTCRevertAddress validates and returns the BTC revert address.
+// Parameters:
+//   - chainID: The Bitcoin network chain ID (e.g., mainnet, testnet)
+// Returns:
+//   - string: The encoded Bitcoin address if valid, empty string otherwise
+//   - bool: true if the address is valid and supported, false otherwise
zetaclient/chains/bitcoin/observer/event.go (1)

224-225: Enhance comment clarity regarding security implications

The current comment could be more explicit about the security implications and the relationship to the sender impersonation fix.

Consider updating the comment to:

-	// inject the 'revertAddress' specified in the memo, so that
-	// zetacore will create a revert outbound that points to the custom revert address.
+	// Use RevertOptions to specify the custom revert address from memo while preserving
+	// the original sender address, preventing potential sender impersonation issues.
x/crosschain/types/cctx_test.go (2)

139-154: Consider enhancing Bitcoin-specific test assertions

While the test comprehensively verifies the revert outbound parameters, consider adding assertions specific to Bitcoin:

  • Verify the Bitcoin address format validity
  • Assert that the address belongs to the correct Bitcoin network (testnet)
 t.Run("successfully set BTC revert address V1", func(t *testing.T) {
     cctx := sample.CrossChainTx(t, "test")
     cctx.InboundParams.SenderChainId = chains.BitcoinTestnet.ChainId
     cctx.OutboundParams = cctx.OutboundParams[:1]
     btcAddress := sample.BtcAddressP2WPKH(t, &chaincfg.TestNet3Params)
     cctx.RevertOptions.RevertAddress = btcAddress
+    
+    // Verify Bitcoin address format and network
+    _, err := btcutil.DecodeAddress(btcAddress, &chaincfg.TestNet3Params)
+    require.NoError(t, err, "should be a valid Bitcoin testnet address")
 
     err := cctx.AddRevertOutbound(100)
     require.NoError(t, err)

156-170: Consider adding Ethereum address format validation

The test should verify that the revert address follows the Ethereum address format:

 t.Run("successfully set EVM revert address V2", func(t *testing.T) {
     cctx := sample.CrossChainTxV2(t, "test")
     cctx.OutboundParams = cctx.OutboundParams[:1]
-    cctx.RevertOptions.RevertAddress = sample.EthAddress().Hex()
+    ethAddress := sample.EthAddress().Hex()
+    cctx.RevertOptions.RevertAddress = ethAddress
+    
+    // Verify Ethereum address format
+    require.True(t, common.IsHexAddress(ethAddress), "should be a valid Ethereum address")
 
     err := cctx.AddRevertOutbound(100)
     require.NoError(t, err)
testutil/sample/crosschain.go (1)

220-234: Consider adding Bitcoin-specific test data generation.

Given that this PR addresses Bitcoin's incorrect 'origin' in zContext, it would be beneficial to add specific test data generation for Bitcoin transactions with the new protocol version.

Consider adding a helper function like:

func BitcoinCrossChainTxV2(t *testing.T, index string, revertAddress string) *types.CrossChainTx {
    cctx := CrossChainTxV2(t, index)
    cctx.InboundParams.CoinType = coin.CoinType_Bitcoin
    if revertAddress != "" {
        cctx.RevertOptions = types.NewRevertOptions(revertAddress)
    }
    return cctx
}
changelog.md (1)

37-37: Consider enhancing the changelog entry to better reflect security implications.

The current entry could be more descriptive about the security implications of the fix. Based on the PR objectives, consider expanding it to:

-* [3192](https://github.com/zeta-chain/node/pull/3192) - fix incorrect zContext origin caused by the replacement of 'sender' with 'revertAddress'
+* [3192](https://github.com/zeta-chain/node/pull/3192) - fix Bitcoin incorrect zContext origin to prevent sender impersonation when revertAddress is specified in memo
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f5e5adb and 0970fb5.

📒 Files selected for processing (7)
  • changelog.md (1 hunks)
  • testutil/sample/crosschain.go (1 hunks)
  • x/crosschain/types/cctx.go (2 hunks)
  • x/crosschain/types/cctx_test.go (2 hunks)
  • x/crosschain/types/revert_options.go (2 hunks)
  • x/crosschain/types/revert_options_test.go (2 hunks)
  • zetaclient/chains/bitcoin/observer/event.go (3 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
testutil/sample/crosschain.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/crosschain/types/cctx.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/crosschain/types/cctx_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/crosschain/types/revert_options.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/crosschain/types/revert_options_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

zetaclient/chains/bitcoin/observer/event.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

🔇 Additional comments (7)
x/crosschain/types/revert_options_test.go (2)

4-11: LGTM: Import statements are well-organized and necessary.

The new imports for Bitcoin address handling (btcd/chaincfg and chains) are appropriately added and organized according to Go conventions.


50-89: LGTM: Well-structured and comprehensive test cases.

The test function follows good testing practices with:

  • Clear test case descriptions
  • Comprehensive coverage of edge cases
  • Consistent assertion patterns
  • Proper use of test helpers
x/crosschain/types/revert_options.go (2)

9-9: LGTM: Import addition is appropriate

The addition of the chains package import is necessary and well-placed for the new Bitcoin address validation functionality.


79-90: Verify test coverage for Bitcoin address validation

The implementation looks solid, but let's ensure comprehensive test coverage exists.

✅ Verification successful

Test coverage for Bitcoin address validation is comprehensive

The implementation is thoroughly tested with:

  • Valid Bitcoin testnet P2WPKH address validation
  • Invalid network address detection (regtest vs testnet)
  • Empty address handling
  • Unsupported address format rejection
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for test coverage of the new GetBTCRevertAddress method

# Look for test files and relevant test cases
rg -l "TestRevertOptions_GetBTCRevertAddress" --type go
rg "func.*Test.*BTCRevertAddress" --type go

# Check for test cases with different Bitcoin address types
rg "TestCase.*btc.*address" --type go -A 5

Length of output: 289


Script:

#!/bin/bash
# Let's examine the actual test implementation
cat x/crosschain/types/revert_options_test.go

Length of output: 3324

zetaclient/chains/bitcoin/observer/event.go (1)

Line range hint 226-251: Implementation looks good with minor suggestions

The implementation correctly addresses the sender impersonation issue by:

  1. Preserving the original sender address
  2. Using RevertOptions for custom revert addresses
  3. Maintaining V1 protocol compatibility

Consider adding validation for RevertOptions before message creation, although the upstream ValidateStandardMemo function already handles this.

Let's verify the validation of revert addresses:

✅ Verification successful

Revert address validation is properly implemented

The implementation correctly validates revert addresses through multiple layers:

  1. The Bitcoin observer's ValidateStandardMemo function (lines 145-165) performs thorough validation:

    • Checks if the revert address is a valid BTC address for the given chain
    • Verifies the address format is supported
    • Returns descriptive errors for invalid addresses
  2. The core types provide chain-specific validation through:

    • GetBTCRevertAddress for Bitcoin addresses
    • GetEVMRevertAddress for Ethereum addresses
  3. The validation is consistently used across the codebase, with proper error handling and chain-specific address format verification.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if revert address validation is consistent across the codebase

# Search for revert address validation patterns
ast-grep --pattern 'func $_ ($_ *memo.InboundMemo, $_ int64) error {
  $$$
  revertAddress := $_.RevertOptions.RevertAddress
  if revertAddress != "" {
    $$$
  }
  $$$
}'

Length of output: 174


Script:

#!/bin/bash
# Let's search for revert address validation patterns with a broader approach

# Search for RevertOptions validation
rg -A 5 "RevertOptions.*RevertAddress" 

# Search for ValidateStandardMemo implementations
ast-grep --pattern 'func ValidateStandardMemo($$$) error {
  $$$
}'

# Search for any validation related to revert addresses
rg -A 5 "validate.*[Rr]evert"

Length of output: 17700

x/crosschain/types/cctx_test.go (2)

7-7: LGTM: Required imports added correctly

The new imports are necessary for Bitcoin network parameters and chain identifiers, properly organized in alphabetical order.

Also applies to: 10-10


139-170: LGTM: Comprehensive test coverage for revert address handling

The test cases effectively cover both Bitcoin V1 and Ethereum V2 revert address scenarios, aligning well with the PR objectives to fix Bitcoin's incorrect 'origin' in zContext. While some enhancements for address validation have been suggested, the current implementation provides solid test coverage.

testutil/sample/crosschain.go Show resolved Hide resolved
x/crosschain/types/cctx.go Show resolved Hide resolved
Copy link

codecov bot commented Nov 20, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 62.74%. Comparing base (495235e) to head (79bb388).
Report is 2 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #3192      +/-   ##
===========================================
+ Coverage    62.70%   62.74%   +0.03%     
===========================================
  Files          425      425              
  Lines        30209    30226      +17     
===========================================
+ Hits         18942    18964      +22     
+ Misses       10429    10425       -4     
+ Partials       838      837       -1     
Files with missing lines Coverage Δ
x/crosschain/types/cctx.go 47.52% <100.00%> (+4.15%) ⬆️
x/crosschain/types/revert_options.go 75.43% <100.00%> (+4.60%) ⬆️
zetaclient/chains/bitcoin/observer/event.go 95.74% <100.00%> (+0.06%) ⬆️
---- 🚨 Try these New Features:

Copy link
Member

@lumtis lumtis left a comment

Choose a reason for hiding this comment

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

Looks good to me but we should add assertions in the standard memo E2E test that check sender and revert addresses in the CCTX

Copy link
Contributor

@skosito skosito left a comment

Choose a reason for hiding this comment

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

lgtm, +1 on adding more assertions in e2e test if possible

x/crosschain/types/cctx.go Show resolved Hide resolved
@ws4charlie
Copy link
Contributor Author

Looks good to me but we should add assertions in the standard memo E2E test that check sender and revert addresses in the CCTX

check added: d0cc073

@ws4charlie ws4charlie requested a review from lumtis November 21, 2024 17:06
@ws4charlie ws4charlie enabled auto-merge November 21, 2024 17:06
@ws4charlie ws4charlie added this pull request to the merge queue Nov 21, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 21, 2024
@ws4charlie ws4charlie added this pull request to the merge queue Nov 21, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 21, 2024
@ws4charlie ws4charlie added this pull request to the merge queue Nov 21, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 21, 2024
@ws4charlie ws4charlie added this pull request to the merge queue Nov 21, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 21, 2024
@lumtis lumtis added this pull request to the merge queue Nov 22, 2024
Merged via the queue into develop with commit 64edb40 Nov 22, 2024
41 checks passed
@lumtis lumtis deleted the fix-incorrect-zContext-origin branch November 22, 2024 10:32
@@ -249,5 +248,6 @@ func (ob *Observer) NewInboundVoteFromStdMemo(
0,
crosschaintypes.ProtocolContractVersion_V1,
false, // not relevant for v1
crosschaintypes.WithRevertOptions(revertOptions),

Choose a reason for hiding this comment

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

Why not use event.MemoStd.RevertOptions here instead of revertOptions which only contains RevertAddress and omitting CallOnRevert, AbortAddress, etc.?

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 zetacored currently only takes the field of RevertAddress from RevertOptions struct in the V1 architecture. So zetaclientd screens out all noises except the RevertAddress before migration to V2 architecture. In V2, we'll open them up in both zetacored and zetaclientd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audit Fixes for issues found in audit chain:bitcoin Bitcoin chain related CONSENSUS_BREAKING_ACK Acknowledge a consensus breaking change zetaclient Issues related to ZetaClient zetacore Issues related to ZetaCore
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants