-
Notifications
You must be signed in to change notification settings - Fork 114
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
feat: (BitcoinRBF-Step1) zetacore
feeds latest gas price to pending Bitcoin CCTXs
#3377
base: develop
Are you sure you want to change the base?
Conversation
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 📝 WalkthroughWalkthroughThis pull request introduces enhancements to the ZetaChain cross-chain transaction (CCTX) gas price management system, with a primary focus on Bitcoin transaction handling. The changes include updating naming conventions, introducing new methods for gas price updates across different blockchain types, and modifying address handling to ensure consistent string representations. The modifications aim to improve the flexibility and precision of gas price management for cross-chain transactions. Changes
Sequence DiagramsequenceDiagram
participant ZetaCore
participant CCTXKeeper
participant EVMChain
participant BTCChain
ZetaCore->>CCTXKeeper: Initiate Gas Price Update
CCTXKeeper->>CCTXKeeper: Determine Chain Type
alt EVM Chain
CCTXKeeper->>EVMChain: Update EVM Gas Price
else Bitcoin Chain
CCTXKeeper->>BTCChain: Update Bitcoin Gas Price
end
CCTXKeeper-->>ZetaCore: Return Updated Gas Prices
Possibly related PRs
Suggested Labels
Suggested Reviewers
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
Documentation and Community
|
zetacore
feeds latest gas price to pending Bitcoin CCTXszetacore
feeds latest gas price to pending Bitcoin CCTXs
zetacore
feeds latest gas price to pending Bitcoin CCTXszetacore
feeds latest gas price to pending Bitcoin CCTXs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
x/observer/types/crosschain_flags.go (1)
8-10
: LGTM! Consider adding documentation about the rationale.The switch from block-based to time-based intervals is well-aligned with Bitcoin's characteristics. The 10-minute retry interval matches Bitcoin's average block time.
Consider adding a comment explaining why 10 minutes was chosen as the retry interval, relating it to Bitcoin's average block time.
testutil/sample/crypto.go (1)
106-111
: LGTM! Well-structured script generation function.The new function properly generates P2WPKH scripts with appropriate error handling.
Consider adding a comment explaining that this is specifically for testing purposes and shouldn't be used in production code.
x/crosschain/keeper/abci.go (2)
204-217
: Add documentation for Bitcoin fee rate implementation.The repurposing of
GasPriorityFee
for Bitcoin fee rate should be documented more clearly. Consider adding a comment explaining that in Bitcoin's context, this field stores the fee rate in sat/vB.// CheckAndUpdateCCTXGasPriceBTC updates the fee rate for the given Bitcoin chain CCTX +// Note: Bitcoin does not have a priority fee concept. The GasPriorityFee field is +// repurposed to store the current fee rate in satoshis per virtual byte (sat/vB). func CheckAndUpdateCCTXGasPriceBTC(
219-231
: Consider using constants for supported chains.The chain support logic is clear, but consider defining constants for supported chain types to make maintenance easier and prevent magic numbers.
+// Supported chain types for gas price updates +const ( + ChainTypeEVM = "evm" + ChainTypeBitcoin = "bitcoin" + ChainTypeZeta = "zeta" +) func IsCCTXGasPriceUpdateSupported(chainID int64, additionalChains []zetachains.Chain) bool { switch { case zetachains.IsZetaChain(chainID, additionalChains): return false case zetachains.IsEVMChain(chainID, additionalChains): return true case zetachains.IsBitcoinChain(chainID, additionalChains): return true default: return false } }x/crosschain/keeper/abci_test.go (1)
609-672
: Add edge cases to Bitcoin gas price tests.While the basic functionality is well tested, consider adding edge cases such as:
- Zero fee rate handling
- Maximum fee rate handling
- Invalid fee rate handling
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
changelog.md
(1 hunks)testutil/sample/crypto.go
(2 hunks)x/crosschain/keeper/abci.go
(5 hunks)x/crosschain/keeper/abci_test.go
(11 hunks)x/crosschain/module.go
(1 hunks)x/crosschain/types/cctx_test.go
(1 hunks)x/crosschain/types/revert_options_test.go
(1 hunks)x/observer/types/crosschain_flags.go
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
x/observer/types/crosschain_flags.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
x/crosschain/module.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.
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.
testutil/sample/crypto.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
x/crosschain/keeper/abci_test.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
x/crosschain/keeper/abci.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
🔇 Additional comments (8)
x/crosschain/types/revert_options_test.go (1)
52-52
: LGTM! Clean adaptation to the new BtcAddressP2WPKH return type.The test correctly handles the new return type by explicitly converting the address to string format.
x/crosschain/module.go (1)
175-175
: LGTM! Consistent naming convention applied.The method name change follows Go's convention of treating acronyms as single words in camelCase (CCTX → CCTx).
testutil/sample/crypto.go (1)
95-104
: LGTM! Enhanced type safety with structured address type.The return type change from string to
*btcutil.AddressWitnessPubKeyHash
improves type safety and provides direct access to address functionality.x/crosschain/keeper/abci.go (2)
22-24
: LGTM! Function type renamed following Go conventions.The renaming of
CheckAndUpdateCctxGasPriceFunc
toCheckAndUpdateCCTXGasPriceFunc
follows Go's standard naming convention for acronyms.
Line range hint
30-102
: LGTM! Robust implementation of gas price update logic.The implementation correctly:
- Fetches and validates gas price increase flags
- Iterates through supported chains
- Handles errors appropriately
- Emits typed events for gas price increases
x/crosschain/types/cctx_test.go (1)
143-143
: LGTM! Improved Bitcoin address handling in tests.The change correctly uses the string representation of the Bitcoin address, ensuring proper address format handling in tests.
x/crosschain/keeper/abci_test.go (1)
674-729
: LGTM! Comprehensive chain support test coverage.The test cases thoroughly cover all supported and unsupported chains, ensuring proper gas price update behavior.
changelog.md (1)
5-8
: LGTM! Clear and concise feature documentation.The changelog entry clearly describes the new Bitcoin gas price update feature.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3377 +/- ##
===========================================
+ Coverage 62.89% 62.90% +0.01%
===========================================
Files 436 436
Lines 30796 30823 +27
===========================================
+ Hits 19369 19390 +21
- Misses 10615 10619 +4
- Partials 812 814 +2
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same problematic as in the old PR.
The increase in the fee should be paid somewhere. We should pay from the gas stability pool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (9)
x/observer/types/crosschain_flags.go (1)
8-8
: Consider documenting the rationale for the 10-minute interval.The change from block-based to time-based interval aligns well with Bitcoin's block time. Consider adding a comment explaining this relationship to help future maintainers understand the chosen duration.
// RetryInterval is the number of blocks to wait before incrementing the gas price again + // Set to 10 minutes to align with Bitcoin's average block time RetryInterval: time.Minute * 10,
testutil/sample/crypto.go (1)
94-104
: Consider accepting randomness as input for deterministic testing.The function could benefit from accepting a source of randomness for the private key generation, similar to other functions in this file.
-func BtcAddressP2WPKH(t *testing.T, net *chaincfg.Params) *btcutil.AddressWitnessPubKeyHash { +func BtcAddressP2WPKH(t *testing.T, net *chaincfg.Params, r *rand.Rand) *btcutil.AddressWitnessPubKeyHash { - privateKey, err := btcec.NewPrivateKey() + seed := make([]byte, 32) + _, err := r.Read(seed) + require.NoError(t, err) + privateKey, err := btcec.PrivKeyFromBytes(seed) require.NoError(t, err)x/crosschain/keeper/abci.go (3)
59-69
: Add context to error logging.The error logging could be more informative by including additional context about the operation being performed.
- ctx.Logger().Info("GasStabilityPool: fetching pending cctx failed", + ctx.Logger().Info("GasStabilityPool: failed to fetch pending CCTXs for gas price update", "chainID", chain.ChainId, "err", err.Error(), )🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 64-68: x/crosschain/keeper/abci.go#L64-L68
Added lines #L64 - L68 were not covered by tests
208-221
: Enhance documentation for Bitcoin gas price updates.The function's documentation should clarify that for Bitcoin,
GasPriorityFee
is repurposed to store the fee rate in sat/vB.-// CheckAndUpdateCCTXGasPriceBTC updates the fee rate for the given Bitcoin chain CCTX +// CheckAndUpdateCCTXGasPriceBTC updates the fee rate for the given Bitcoin chain CCTX. +// Note: For Bitcoin transactions, GasPriorityFee is repurposed to store the fee rate in sat/vB, +// which zetaclient will use to schedule Replace-By-Fee (RBF) transactions.
223-234
: Consider using a map for better performance.For better performance when checking multiple chain types, consider using a map instead of a switch statement.
+var supportedChainTypes = map[string]bool{ + "evm": true, + "bitcoin": true, +} + func IsCCTXGasPriceUpdateSupported(chainID int64, additionalChains []chains.Chain) bool { - switch { - case chains.IsZetaChain(chainID, additionalChains): + if chains.IsZetaChain(chainID, additionalChains) { return false - case chains.IsEVMChain(chainID, additionalChains), - chains.IsBitcoinChain(chainID, additionalChains): - return true - default: - return false } + chainType := chains.GetChainType(chainID, additionalChains) + return supportedChainTypes[chainType] }x/crosschain/keeper/abci_test.go (3)
Line range hint
66-82
: Consider organizing test cases using table-driven tests.The test setup could be more maintainable using table-driven tests to verify both default and custom crosschain flags behavior.
testCases := []struct { name string flags *observertypes.CrosschainFlags blockHeight int64 expectedCount int expectedFlags observertypes.GasPriceIncreaseFlags }{ { name: "default flags", flags: nil, blockHeight: observertypes.DefaultCrosschainFlags().GasPriceIncreaseFlags.EpochLength + 1, expectedCount: 0, expectedFlags: *observertypes.DefaultCrosschainFlags().GasPriceIncreaseFlags, }, { name: "custom flags", flags: crosschainFlags, blockHeight: observertypes.DefaultCrosschainFlags().GasPriceIncreaseFlags.EpochLength + 1, expectedCount: 0, expectedFlags: customFlags, }, }
88-104
: Add documentation to clarify test expectations.The test verifies gas price updates across multiple chains but lacks clear documentation of the expected behavior. Consider adding comments to explain:
- Why specific number of updates are expected (2 ETH + 5 BTC + 5 BSC = 12)
- The significance of each chain's update count
// Test expects total of 12 updates: // - 2 updates for Ethereum (nonce range 10-11) // - 5 updates for Bitcoin (nonce range 20-24) // - 5 updates for BSC (nonce range 30-34) // ZetaChain updates (nonce range 40-45) are skipped as expected
684-779
: Consider grouping test cases by chain category.The test cases for chain support verification could be better organized by grouping similar chains together (e.g., all EVM chains, all Bitcoin variants, etc.).
// Group test cases by chain category var chainTests = []struct { category string testCases []struct { name string chainID int64 isSupport bool } }{ { category: "EVM Chains", testCases: []struct { name string chainID int64 isSupport bool }{ {"Ethereum", chains.Ethereum.ChainId, true}, {"Ethereum Sepolia", chains.Sepolia.ChainId, true}, // ... other EVM chains }, }, { category: "Bitcoin Chains", testCases: []struct { name string chainID int64 isSupport bool }{ {"Bitcoin Mainnet", chains.BitcoinMainnet.ChainId, true}, {"Bitcoin Testnet", chains.BitcoinTestnet4.ChainId, true}, }, }, // ... other chain categories }changelog.md (1)
5-8
: Enhance the changelog entry with more details.The changelog entry for PR #3377 could be more descriptive to help users understand the impact and benefits of the change.
- * [3377](https://github.com/zeta-chain/node/pull/3377) - have zetacore feed latest gas price to pending Bitcoin cctxs + * [3377](https://github.com/zeta-chain/node/pull/3377) - Enhance Bitcoin transaction efficiency by having zetacore feed latest gas prices to pending Bitcoin CCTXs + - Reduces transaction stuck time in mempool + - Updates gas prices every 10 minutes + - Reduces BTCOutboundGasPriceMultiplier from 2.0 to 1.2 + - Improves balance between transaction finality and withdrawal fees
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
changelog.md
(1 hunks)testutil/sample/crypto.go
(2 hunks)x/crosschain/keeper/abci.go
(7 hunks)x/crosschain/keeper/abci_test.go
(12 hunks)x/crosschain/module.go
(1 hunks)x/crosschain/types/cctx_test.go
(1 hunks)x/crosschain/types/revert_options_test.go
(1 hunks)x/observer/types/crosschain_flags.go
(1 hunks)zetaclient/chains/bitcoin/observer/event_test.go
(3 hunks)zetaclient/chains/bitcoin/observer/inbound_test.go
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
x/observer/types/crosschain_flags.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
x/crosschain/module.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.
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.
zetaclient/chains/bitcoin/observer/event_test.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
testutil/sample/crypto.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
zetaclient/chains/bitcoin/observer/inbound_test.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
x/crosschain/keeper/abci_test.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
x/crosschain/keeper/abci.go (1)
Pattern **/*.go
: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.
📓 Learnings (2)
zetaclient/chains/bitcoin/observer/event_test.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#2987
File: pkg/memo/fields_v0_test.go:270-320
Timestamp: 2024-11-12T13:20:12.658Z
Learning: In the `FieldsV0` struct of the `memo` package, `RevertAddress` may be left empty when `CallOnRevert` is set to true.
zetaclient/chains/bitcoin/observer/inbound_test.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#2899
File: zetaclient/chains/bitcoin/observer/inbound.go:37-38
Timestamp: 2024-11-12T13:20:12.658Z
Learning: In `BTCInboundEvent`, it's acceptable to use `float64` for monetary values (`Value` and `DepositorFee`) because precision is ensured through conversion to integer when building the vote message.
🪛 GitHub Check: codecov/patch
x/crosschain/keeper/abci.go
[warning] 64-68: x/crosschain/keeper/abci.go#L64-L68
Added lines #L64 - L68 were not covered by tests
[warning] 74-74: x/crosschain/keeper/abci.go#L74
Added line #L74 was not covered by tests
[warning] 86-86: x/crosschain/keeper/abci.go#L86
Added line #L86 was not covered by tests
[warning] 96-99: x/crosschain/keeper/abci.go#L96-L99
Added lines #L96 - L99 were not covered by tests
[warning] 142-143: x/crosschain/keeper/abci.go#L142-L143
Added lines #L142 - L143 were not covered by tests
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: start-e2e-test / e2e
🔇 Additional comments (9)
x/crosschain/types/revert_options_test.go (1)
52-52
: LGTM! Explicit string conversion improves clarity.The explicit conversion to string using
.String()
makes the address format clear and consistent.x/crosschain/module.go (1)
175-175
: LGTM! Consistent method naming.The updated method name follows the standard casing convention for the CCTX acronym.
testutil/sample/crypto.go (1)
106-111
: LGTM! Well-structured utility function.The function provides a clean interface for generating P2WPKH scripts with proper error handling.
x/crosschain/keeper/abci.go (2)
22-27
: LGTM! Clean function type declaration.The function type declaration is well-structured and follows Go conventions.
73-75
: Consider inverting the nil check to reduce nesting.Following the feedback from past reviews, let's improve code readability by inverting the nil check.
- if pendingCctx == nil { - continue - } + if pendingCctx != nil { + // Rest of the logic + }🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 74-74: x/crosschain/keeper/abci.go#L74
Added line #L74 was not covered by testsx/crosschain/types/cctx_test.go (1)
143-143
: LGTM! Consistent address type handling.The conversion of Bitcoin address to string representation ensures type consistency and prevents potential type mismatches in cross-chain transactions.
zetaclient/chains/bitcoin/observer/event_test.go (2)
35-35
: LGTM! Standardized address handling in test event creation.Converting the Bitcoin address to string representation in
createTestBtcEvent
ensures consistent type handling across test cases.
252-252
: LGTM! Consistent revert address handling.Converting the Bitcoin address to string in revert options test maintains type consistency and matches production behavior.
zetaclient/chains/bitcoin/observer/inbound_test.go (1)
170-170
: LGTM! Standardized address handling in inbound tests.Converting the Bitcoin address to string representation maintains consistency with the address handling pattern across the codebase.
For the draft PR: In the draft PR, it is the TSS self who pays the additional bump fee. The difficulties I have seen for the
Below are the considerations during RBF implementation and open to discussions
Now, ignore the difference in tx replacement mechanism. I believe a long-term goal for Zetachain will be lowering gas fee for cross-chain service. Here is some understanding around the current The Taking It is reasonable to try If lowering gas fee and multiplier are the goals on our roadmap, a
The moment To accurately track outbound txs fees, we could:
|
I don't understand, in the PR we already have the logic iterating the pending CCTX and increasing the fee in the CCTX, what I'm asking is to pay this increase from the gas stability pool, I don't think this adds up to the problematic you mention based on the current implementation. TSS should never infer the cost for a withdraw. On a second hand I don't think it's problematic increasing all cctx with outdated fee, not paying the fees is problematic. |
A question: What's the purpose of always having Again, the |
…t-bitcoin-RBF-zetacore-change
Here are some diagrams to visualize the current (regular) fee bumping vs. RBF fee bumping.Below is a typical case when outbounds get stuck:
Note: In Bitcoin, TSS signers will stop signing future txs 1. When current fee bumping mechanism bumps fee, it bumps all CCTXs.In below diagram, 2. When RBF fee bumping mechanism bumps fee, it bumps
|
IMO, the following is the use for a gas stability pool at a high level. |
What I see is that the current implementation funds
Accounting is still a separate thing, it just visualizes the system and provides some hints. If the balance becomes negative, then we could increase the charge (by some multiplier) from users; if the balance grows, we could consider lower the charge (by same multiplier). If the balance becomes negative, it doesn't mean we should stop bumping fees, as long as the current gas price isn't suspiciously high. So what we could control are 3 parameters:
Here is the follow-up after discussion with @kingpinXD
|
Again the gas stability pool mechanism is up to be optimized. The overall vision of the mechanism is to have an automated way, that doesn't require supervision, to unblock stuck cctx. On EVM if a nonce is long pending, we make the assumption that it is stuck because of gas price as the blockchain doesn't have access to the external world, we also iterate next cctxs for time gain but this is a part to be optimized as well, tracked by an issue. I think the fact we iterate multiple CCTX even the non-stuck ones for Bitcoin for now is a detail, we can easily subsidized the cost. My original question where I don't think I had an answer yet is who pay for the fee bump?
This doesn't answer the question, where does the fund come from to update the fee rate? If the fee rate is increase, the cost is higher for the outbound, who pay for this difference of cost? |
Description
The problem:
If a tx gets broadcasted to Bitcoin network using latest fee rate, it is less likely to get stuck. In most cases, an outbound tx got stuck when
zetaclient
had used anoutdated lower fee rate
in CCTX to send it out to Bitcoin network.Bitcoin block time is
10 mins
and much longer than other chains. When a Bitcoin tx gets stuck, it can sit in the mempool for hours or days depending on traffic. Reducing the chance of having txs stuck in mempool will address the problem at its root cause. RBF will come as the last remedy.One of the long-term directions that guide us would be lowering the cross-chain gas fee. The gas price in the CCTX indicates how much gas was paid initially on the withdrawal. An outdated gas price should not guild TSS signers to file an outbound tx which will lead to either an
overpaid
orlong pending
outbound tx.We already had the
BTCOutboundGasPriceMultiplier = 2.0
to try avoid stuck outbound in mempool but we still have stuck txs since mainnet launch. This also explains why an outdated gas price misleads TSS signers. This multiplier needs to reduce to some level, like1.2
to balance the quick finality and unnecessary high withdrawal fees.The thoughts:
zetacore
feed latest fee rate (every 10 mins) to pending Bitcoin CCTXs in the methodCheckAndUpdateCCTXGasPriceBTC
.10
pending cctxsCCTX1, CCTX2, CCTX3, CCTX4,... CCTX10
in zetacore, and zetaclient have broadcasted4
outbounds[TX1, TX2, TX3, TX4]
and they all get stuck in mempool, so keysign stopped already.zetacore
has no idea of what had happened for these10 pending CCTXs
. Maybe outbound is pending in mempool (it is just a guess), Maybe TSS signers are not working smoothly, or maybe the RPC is down, nobody knows.4
txs in mempool, onlyTX4
needs to be bumped, so that the average fee rate of the4
txs will increase, making them a marketable package for miners.Tx4
,zetaclient
needs to know the latest fee rate, so it can bump the gas fee that accurately aligns with market.How Has This Been Tested?
Summary by CodeRabbit
Release Notes
New Features
Improvements
Technical Updates