-
Notifications
You must be signed in to change notification settings - Fork 72
ZK to MPT #827
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
ZK to MPT #827
Changes from 1 commit
2cdfb07
7c11f8c
98925c5
c34bee9
e39a59a
105c335
a3d76f2
8ae80bd
d5f2d8d
fa2307f
c38ea30
8b2a833
c9f508d
0968304
f4d7b0c
32512d0
b5e977c
5f6ad17
8631ca8
5dea362
772df41
75181a7
6120b0a
89218d0
0a63c6b
a438b20
8abcf7c
d6dd008
abcc805
57cf1e4
0f74ddb
0ec7bda
fd31a72
fae4ad8
ffa5e6d
f11e92a
f34a133
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,9 +2,6 @@ package types | |
|
|
||
| import ( | ||
| "context" | ||
| "math/big" | ||
| "strings" | ||
|
|
||
| "github.com/cenkalti/backoff/v4" | ||
| "github.com/morph-l2/go-ethereum" | ||
| "github.com/morph-l2/go-ethereum/common" | ||
|
|
@@ -13,6 +10,9 @@ import ( | |
| "github.com/morph-l2/go-ethereum/ethclient" | ||
| "github.com/morph-l2/go-ethereum/ethclient/authclient" | ||
| tmlog "github.com/tendermint/tendermint/libs/log" | ||
| "math/big" | ||
| "strings" | ||
| "time" | ||
| ) | ||
|
|
||
| const ( | ||
|
|
@@ -27,27 +27,47 @@ const ( | |
| ) | ||
|
|
||
| type RetryableClient struct { | ||
| authClient *authclient.Client | ||
| ethClient *ethclient.Client | ||
| b backoff.BackOff | ||
| logger tmlog.Logger | ||
| legacyAuthClient *authclient.Client | ||
| legacyEthClient *ethclient.Client | ||
| authClient *authclient.Client | ||
| ethClient *ethclient.Client | ||
| mptTime uint64 // TODO rename | ||
| b backoff.BackOff | ||
| logger tmlog.Logger | ||
| } | ||
|
|
||
| // NewRetryableClient make the client retryable | ||
| // Will retry calling the api, if the connection is refused | ||
| func NewRetryableClient(authClient *authclient.Client, ethClient *ethclient.Client, logger tmlog.Logger) *RetryableClient { | ||
| func NewRetryableClient(legacyAuthClient *authclient.Client, legacyEthClient *ethclient.Client, authClient *authclient.Client, ethClient *ethclient.Client, logger tmlog.Logger) *RetryableClient { | ||
| logger = logger.With("module", "retryClient") | ||
| return &RetryableClient{ | ||
| authClient: authClient, | ||
| ethClient: ethClient, | ||
| b: backoff.NewExponentialBackOff(), | ||
| logger: logger, | ||
| legacyAuthClient: legacyAuthClient, | ||
| legacyEthClient: legacyEthClient, | ||
| authClient: authClient, | ||
| ethClient: ethClient, | ||
| b: backoff.NewExponentialBackOff(), | ||
| logger: logger, | ||
| } | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| func (c *RetryableClient) aClient(timeStamp uint64) *authclient.Client { | ||
| if c.mptTime >= timeStamp { | ||
| return c.legacyAuthClient | ||
| } | ||
| return c.authClient | ||
| } | ||
|
|
||
| func (c *RetryableClient) eClient(timeStamp uint64) *ethclient.Client { | ||
| if c.mptTime >= timeStamp { | ||
| return c.legacyEthClient | ||
| } | ||
|
Comment on lines
+250
to
293
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Blocking loop lacks timeout and context cancellation, risking indefinite hang. The polling loop that waits for the next geth to sync has no exit conditions other than successful synchronization:
This could cause the entire node to hang during an upgrade if the next geth is unavailable. Proposed fix for {
+ select {
+ case <-ctx.Done():
+ rc.logger.Error("Context cancelled while waiting for next geth to sync",
+ "error", ctx.Err(),
+ "wait_duration", time.Since(startTime))
+ return
+ default:
+ }
+
remote, err := rc.nextEthClient.BlockNumber(ctx)
if err != nil {
rc.logger.Error("Failed to get next geth block number",
"error", err,
"hint", "Please ensure next geth is running and accessible")
- <-ticker.C
+ select {
+ case <-ctx.Done():
+ return
+ case <-ticker.C:
+ }
continue
}Consider also adding a maximum wait timeout (e.g., configurable or a sensible default like 30 minutes) to prevent indefinite blocking in production. 🤖 Prompt for AI Agents |
||
| return c.ethClient | ||
| } | ||
|
Comment on lines
+224
to
294
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Infinite blocking loop can halt the node permanently. The Additionally:
Consider adding:
🛠️ Suggested approach with timeout func (rc *RetryableClient) switchClient(ctx context.Context, timeStamp uint64, number uint64) {
if rc.switched.Load() {
return
}
if timeStamp < rc.switchTime {
return
}
+ // Add a reasonable timeout for the switch operation
+ switchCtx, cancel := context.WithTimeout(ctx, 30*time.Minute)
+ defer cancel()
// ... existing logging ...
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
+ select {
+ case <-switchCtx.Done():
+ rc.logger.Error("Switch timeout exceeded, failing switch operation")
+ return // or panic, depending on desired behavior
+ default:
+ }
+
remote, err := rc.nextEthClient.BlockNumber(ctx)
// ... rest of loop ...
}
}🤖 Prompt for AI Agents |
||
|
|
||
| func (rc *RetryableClient) AssembleL2Block(ctx context.Context, number *big.Int, transactions eth.Transactions) (ret *catalyst.ExecutableL2Data, err error) { | ||
| timestamp := uint64(time.Now().Unix()) | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.authClient.AssembleL2Block(ctx, number, transactions) | ||
| resp, respErr := rc.aClient(timestamp).AssembleL2Block(ctx, ×tamp, number, transactions) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to AssembleL2Block", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -65,7 +85,7 @@ func (rc *RetryableClient) AssembleL2Block(ctx context.Context, number *big.Int, | |
|
|
||
| func (rc *RetryableClient) ValidateL2Block(ctx context.Context, executableL2Data *catalyst.ExecutableL2Data) (ret bool, err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.authClient.ValidateL2Block(ctx, executableL2Data) | ||
| resp, respErr := rc.aClient(executableL2Data.Timestamp).ValidateL2Block(ctx, executableL2Data) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to ValidateL2Block", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -83,7 +103,7 @@ func (rc *RetryableClient) ValidateL2Block(ctx context.Context, executableL2Data | |
|
|
||
| func (rc *RetryableClient) NewL2Block(ctx context.Context, executableL2Data *catalyst.ExecutableL2Data, batchHash *common.Hash) (err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| respErr := rc.authClient.NewL2Block(ctx, executableL2Data, batchHash) | ||
| respErr := rc.aClient(executableL2Data.Timestamp).NewL2Block(ctx, executableL2Data, batchHash) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to NewL2Block", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -100,7 +120,7 @@ func (rc *RetryableClient) NewL2Block(ctx context.Context, executableL2Data *cat | |
|
|
||
| func (rc *RetryableClient) NewSafeL2Block(ctx context.Context, safeL2Data *catalyst.SafeL2Data) (ret *eth.Header, err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.authClient.NewSafeL2Block(ctx, safeL2Data) | ||
| resp, respErr := rc.aClient(safeL2Data.Timestamp).NewSafeL2Block(ctx, safeL2Data) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to NewSafeL2Block", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -118,7 +138,8 @@ func (rc *RetryableClient) NewSafeL2Block(ctx context.Context, safeL2Data *catal | |
|
|
||
| func (rc *RetryableClient) CommitBatch(ctx context.Context, batch *eth.RollupBatch, signatures []eth.BatchSignature) (err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| respErr := rc.authClient.CommitBatch(ctx, batch, signatures) | ||
| // TODO timestamp | ||
| respErr := rc.aClient(0).CommitBatch(ctx, batch, signatures) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to CommitBatch", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -135,7 +156,8 @@ func (rc *RetryableClient) CommitBatch(ctx context.Context, batch *eth.RollupBat | |
|
|
||
| func (rc *RetryableClient) AppendBlsSignature(ctx context.Context, batchHash common.Hash, signature eth.BatchSignature) (err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| respErr := rc.authClient.AppendBlsSignature(ctx, batchHash, signature) | ||
| // TODO timestamp | ||
| respErr := rc.aClient(0).AppendBlsSignature(ctx, batchHash, signature) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to call AppendBlsSignature", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -152,7 +174,8 @@ func (rc *RetryableClient) AppendBlsSignature(ctx context.Context, batchHash com | |
|
|
||
| func (rc *RetryableClient) BlockNumber(ctx context.Context) (ret uint64, err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.ethClient.BlockNumber(ctx) | ||
| // TODO timestamp | ||
| resp, respErr := rc.eClient(0).BlockNumber(ctx) | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| if respErr != nil { | ||
| rc.logger.Info("failed to call BlockNumber", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -170,7 +193,8 @@ func (rc *RetryableClient) BlockNumber(ctx context.Context) (ret uint64, err err | |
|
|
||
| func (rc *RetryableClient) HeaderByNumber(ctx context.Context, blockNumber *big.Int) (ret *eth.Header, err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.ethClient.HeaderByNumber(ctx, blockNumber) | ||
| // TODO timestamp | ||
| resp, respErr := rc.eClient(0).HeaderByNumber(ctx, blockNumber) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to call BlockNumber", "error", respErr) | ||
|
curryxbo marked this conversation as resolved.
|
||
| if retryableError(respErr) { | ||
|
|
@@ -188,7 +212,8 @@ func (rc *RetryableClient) HeaderByNumber(ctx context.Context, blockNumber *big. | |
|
|
||
| func (rc *RetryableClient) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) (ret []byte, err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.ethClient.CallContract(ctx, call, blockNumber) | ||
| // TODO timestamp | ||
| resp, respErr := rc.eClient(0).CallContract(ctx, call, blockNumber) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to call eth_call", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
@@ -206,7 +231,8 @@ func (rc *RetryableClient) CallContract(ctx context.Context, call ethereum.CallM | |
|
|
||
| func (rc *RetryableClient) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (ret []byte, err error) { | ||
| if retryErr := backoff.Retry(func() error { | ||
| resp, respErr := rc.ethClient.CodeAt(ctx, contract, blockNumber) | ||
| // TODO timestamp | ||
| resp, respErr := rc.eClient(0).CodeAt(ctx, contract, blockNumber) | ||
| if respErr != nil { | ||
| rc.logger.Info("failed to call eth_getCode", "error", respErr) | ||
| if retryableError(respErr) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.