Skip to content

Commit b29fa5f

Browse files
authored
feat(x/evmengine): support exec engine snap sync (#506)
Previously, when the execution engine was syncing, it would keep retrying until evm syncing is done. However, evm syncing is stuck while downloading chain data because the requested head falls behind by more than 128 blocks, making it impossible to retrieve the missing data from other peers. To support snap sync, `newPayloadV3` and `forkChoiceUpdatedV3` requests are now made with the latest head while the execution engine is syncing. During syncing, `prepareProposal`, `processProposal`, and `postFinalize` are skipped. issue: #505
1 parent e045276 commit b29fa5f

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

client/x/evmengine/keeper/abci.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ const prepareTimeout = time.Second * 10
2929
func (k *Keeper) PrepareProposal(ctx sdk.Context, req *abci.RequestPrepareProposal) (
3030
*abci.ResponsePrepareProposal, error,
3131
) {
32+
if k.IsExecEngSyncing() {
33+
log.Warn(ctx, "Skip PrepareProposal while execution engine is syncing", nil)
34+
return nil, ErrExecEngSyncing
35+
}
36+
3237
// Only allow 10s to prepare a proposal. Propose empty block otherwise.
3338
timeoutCtx, timeoutCancel := context.WithTimeout(ctx.Context(), prepareTimeout)
3439
defer timeoutCancel()
@@ -189,6 +194,11 @@ func (k *Keeper) PostFinalize(ctx sdk.Context) error {
189194
return nil // Not enabled.
190195
}
191196

197+
if k.IsExecEngSyncing() {
198+
log.Warn(ctx, "Skip PostFinalize while execution engine is syncing", nil)
199+
return nil
200+
}
201+
192202
// Extract context values
193203
height := ctx.BlockHeight()
194204
timestamp := ctx.BlockTime()

client/x/evmengine/keeper/keeper.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828
"github.com/piplabs/story/lib/k1util"
2929
)
3030

31+
var ErrExecEngSyncing = errors.New("execution engine is syncing")
32+
3133
type Keeper struct {
3234
cdc codec.BinaryCodec
3335
storeService store.KVStoreService
@@ -56,6 +58,8 @@ type Keeper struct {
5658
Height uint64
5759
UpdatedAt time.Time
5860
}
61+
62+
isExecEngSyncing bool
5963
}
6064

6165
func NewKeeper(
@@ -128,6 +132,15 @@ func (k *Keeper) SetValidatorAddress(addr common.Address) {
128132
k.validatorAddr = addr
129133
}
130134

135+
// IsExecEngSyncing returns if execution engine is syncing or not.
136+
func (k *Keeper) IsExecEngSyncing() bool {
137+
return k.isExecEngSyncing
138+
}
139+
140+
func (k *Keeper) SetIsExecEngSyncing(isSyncing bool) {
141+
k.isExecEngSyncing = isSyncing
142+
}
143+
131144
// RegisterProposalService registers the proposal service on the provided router.
132145
// This implements abci.ProcessProposal verification of new proposals.
133146
func (k *Keeper) RegisterProposalService(server grpc1.Server) {

client/x/evmengine/keeper/msg_server.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,11 @@ func (s msgServer) ExecutionPayload(ctx context.Context, msg *types.MsgExecution
100100

101101
return false, err // Don't retry, error out.
102102
} else if isSyncing(status) {
103-
log.Warn(ctx, "Processing finalized payload; evm syncing", nil)
104-
} /* else isValid(status) */
103+
s.SetIsExecEngSyncing(true)
104+
log.Warn(ctx, "Push finalized payload while evm syncing", nil)
105+
} else if s.IsExecEngSyncing() {
106+
s.SetIsExecEngSyncing(false)
107+
}
105108

106109
return true, nil // We are done, don't retry
107110
})
@@ -124,9 +127,7 @@ func (s msgServer) ExecutionPayload(ctx context.Context, msg *types.MsgExecution
124127

125128
return false, nil // Retry
126129
} else if isSyncing(fcr.PayloadStatus) {
127-
log.Warn(ctx, "Processing finalized payload halted while evm syncing (will retry)", nil, "payload_height", payload.Number)
128-
129-
return false, nil // Retry
130+
log.Warn(ctx, "Processing finalized payload while evm syncing", nil, "payload_height", payload.Number)
130131
} else if invalid, err := isInvalid(fcr.PayloadStatus); invalid {
131132
// This should never happen. This node will stall now.
132133
log.Error(ctx, "Processing finalized payload failed; forkchoice update invalid [BUG]", err,

client/x/evmengine/keeper/proposal_server.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ type proposalServer struct {
1919

2020
// ExecutionPayload handles a new execution payload proposed in a block.
2121
func (s proposalServer) ExecutionPayload(ctx context.Context, msg *types.MsgExecutionPayload) (*types.ExecutionPayloadResponse, error) {
22+
if s.IsExecEngSyncing() {
23+
log.Warn(ctx, "Skip ProcessProposal while execution engine is syncing", nil)
24+
return nil, ErrExecEngSyncing
25+
}
26+
2227
payload, err := s.parseAndVerifyProposedPayload(ctx, msg)
2328
if err != nil {
2429
return nil, errors.Wrap(err, "unmarshal payload")
@@ -41,8 +46,10 @@ func (s proposalServer) ExecutionPayload(ctx context.Context, msg *types.MsgExec
4146
return false, errors.Wrap(err, "invalid payload, rejecting proposal") // Don't retry
4247
} else if isSyncing(status) {
4348
// If this is initial sync, we need to continue and set a target head to sync to, so don't retry.
44-
log.Warn(ctx, "Can't properly verifying proposal: evm syncing", err,
49+
log.Warn(ctx, "Can't properly verifying proposal: evm syncing", nil,
4550
"payload_height", payload.Number)
51+
52+
return false, ErrExecEngSyncing
4653
} /* else isValid(status) */
4754

4855
return true, nil // We are done, don't retry.

0 commit comments

Comments
 (0)