ift relay support#68
Conversation
…ps and gas block limits
Remove the aggregate Err field from SentTx in both cosmos and ethereum chains. Rename SourceErr to BroadcastErr and RelayerErr to PostBroadcastErr to align with the txMode abstraction. Add Failed() and Error() methods that derive overall status from the specific error fields and TxResponse.
…elay config - add MsgIFTTransfer as a case in both ethereum and cosmos TxFactory BuildTxs/CreateMsg, with baseline support for high-throughput runs - replace implicit HandlePostBroadcast with explicit RelayConfig that specifies a relayer URL and which message types should be relayed - remove txMode interface and mode.go from both chains - move relayer config from ift.relayer to top-level relay in spec - use SuggestGasTipCap instead of hardcoded 2 gwei default for EVM gas fee estimation - fix EVM IFT timeout to use Unix seconds instead of nanoseconds
| } | ||
|
|
||
| maxGas := params.ConsensusParams.Block.MaxGas | ||
| if maxGas == -1 { |
There was a problem hiding this comment.
Our test chain did not have max gas configured causing catalyst to fail on the maxGas check below in lin 196
Greptile SummaryThis PR adds IFT (Inter-chain Fund Transfer) relay support to both the Cosmos and Ethereum load-test runners: new
Confidence Score: 3/5Not safe to merge as-is: the synchronous relay retry loop can stall load-test execution for up to 45 seconds when the relayer is slow, and the EVM address generator silently produces a wrong first recipient. Two P1 findings: a blocking retry loop in the hot send path that defeats the purpose of a load test under relay degradation, and an inconsistent EVM passphrase that silently generates the wrong first recipient address. Both need to be addressed before the relay path is trustworthy. ift/relayer/client.go (blocking retry loop), ift/accounts/evm.go (passphrase inconsistency for index 0) Important Files Changed
|
| for attempt := range maxRelayRetries { | ||
| if attempt > 0 { | ||
| select { | ||
| case <-ctx.Done(): | ||
| return ctx.Err() | ||
| case <-time.After(relayRetryDelay): | ||
| } | ||
| } | ||
|
|
||
| callCtx, cancel := context.WithTimeout(ctx, c.timeout) | ||
| _, err := c.client.Relay(callCtx, &relayerapi.RelayRequest{ | ||
| TxHash: txHash, | ||
| ChainId: c.chainID, | ||
| }) | ||
| cancel() | ||
|
|
||
| if err == nil { | ||
| return nil | ||
| } | ||
| lastErr = err | ||
| } | ||
|
|
||
| return fmt.Errorf("submit tx hash to relayer after %d attempts: %w", maxRelayRetries, lastErr) |
There was a problem hiding this comment.
Synchronous retry loop blocks load-test send goroutines
SubmitTxHash is called synchronously inside the transaction-sending goroutines in all three Ethereum runners (block.go, interval.go, persistent.go) and in the Cosmos runner's broadcastAndHandleResponse. Each call can block for up to 15 × 3 s = 45 s when the relayer is slow or down. Because each sending goroutine holds a wg.Done that the outer wg.Wait() waits on, a relayer outage can stall the entire load-test batch for tens of seconds per round, completely skewing throughput measurements.
Consider running the relay submission in a fire-and-forget background goroutine (storing the result separately) or using a channel-based worker pool so that transaction sending is never gated on relay delivery.
There was a problem hiding this comment.
This is true, but not something I would consider important to address unless it prevents me from generating sufficient load to stress the relayer. For single chain testing, the relayer does not even get called, so there is no impact there.
| r.logger.Debug("processing block", zap.Int64("height", block.Height), | ||
| zap.Time("timestamp", block.Timestamp), zap.Int64("gas_limit", block.GasLimit)) | ||
|
|
||
| if r.spec.SendInterval > 0 && time.Since(lastSendTime) < r.spec.SendInterval { |
There was a problem hiding this comment.
Time based tx submission interval
| Err: nil, | ||
| } | ||
|
|
||
| if err := r.relayTxHash(ctx, msgType, res.TxHash); err != nil { |
There was a problem hiding this comment.
This only executes if the operator has relaying configured.
| wg := sync.WaitGroup{} | ||
| blockStats := make([]loadtesttypes.BlockStat, endBlock-startBlock+1) | ||
| receipts := make(map[uint64]gethtypes.Receipts) | ||
| msgTypeByHash := make(map[common.Hash]loadtesttypes.MsgType, len(sentTxs)) |
There was a problem hiding this comment.
Small refactor to store the msg type by tx hash in a map and look it up when building test stats later instead of inferring based on properties of the tx
| // gasFeeCap = baseFee * 2 + gasTipCap (reasonable default) | ||
| baseFee := header.BaseFee | ||
| if gasTipCap == nil { | ||
| gasTipCap = big.NewInt(2000000000) // 2 gwei default tip |
There was a problem hiding this comment.
These hard coded values were not appropriate for the networks I was testing against.
There was a problem hiding this comment.
I have no idea if changing these does anything negative to our existing eth tests 🤷
There was a problem hiding this comment.
Should the generated protobuf and whatever client code we need for the relayer eventually be in some separate repo that integrators can import instead of having to generate/define client impls everywhere we're using the relayer?
There was a problem hiding this comment.
The client is already importable actually. But I tried just now and the resulting dependency version bumps created some compatibility issues with the CI runner. I'm just going to merge as is for now - if you feel strongly that this should be addressed I'm happy to in another PR.
| // gasFeeCap = baseFee * 2 + gasTipCap (reasonable default) | ||
| baseFee := header.BaseFee | ||
| if gasTipCap == nil { | ||
| gasTipCap = big.NewInt(2000000000) // 2 gwei default tip |
There was a problem hiding this comment.
I have no idea if changing these does anything negative to our existing eth tests 🤷
fc8de08 to
f510461
Compare
Summary
Adds end-to-end IFT transfer support to Catalyst. Senders can drive MsgIFTTransfer load from cosmos or EVM chains to cosmos or EVM destinations and configure Catalyst to forward transactions to an ibc relayer.
Changes
ift/accounts/{cosmos,evm}.go).SuggestGasTipCapfrom the node rather than a hardcoded 2 gwei default — works on L2s without manual tuning.send_intervalconfig.In a future PR, I will extend prometheus metric collection in the runners to capture relaying success/failure and latency.