From 59d1c9954662200f787968ce7d89c53036e33dd0 Mon Sep 17 00:00:00 2001 From: Lei Date: Wed, 24 Jan 2024 08:26:50 -0800 Subject: [PATCH] support customized block number for conditional (#11804) --- core/scripts/chaincli/DEBUGGING.md | 4 ++-- core/scripts/chaincli/handler/debug.go | 24 ++++++++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/core/scripts/chaincli/DEBUGGING.md b/core/scripts/chaincli/DEBUGGING.md index 703261fcb54..6466a40fc31 100644 --- a/core/scripts/chaincli/DEBUGGING.md +++ b/core/scripts/chaincli/DEBUGGING.md @@ -41,10 +41,10 @@ For detailed transaction simulation logs, set up Tenderly credentials. Refer to Execute the following command based on your upkeep type: -- For conditional upkeep: +- For conditional upkeep, if a block number is given we use that block, otherwise we use the latest block: ```bash - go run main.go keeper debug UPKEEP_ID + go run main.go keeper debug UPKEEP_ID [OPTIONAL BLOCK_NUMBER] ``` - For log trigger upkeep: diff --git a/core/scripts/chaincli/handler/debug.go b/core/scripts/chaincli/handler/debug.go index 2c97adace26..8b06937fc2c 100644 --- a/core/scripts/chaincli/handler/debug.go +++ b/core/scripts/chaincli/handler/debug.go @@ -68,8 +68,10 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { } chainID := chainIDBig.Int64() - var triggerCallOpts *bind.CallOpts // use latest block for conditionals, but use block from tx for log triggers - latestCallOpts := &bind.CallOpts{Context: ctx} // always use latest block + // Log triggers: always use block from tx + // Conditional: use latest block if no block number is provided, otherwise use block from user input + var triggerCallOpts *bind.CallOpts // use a certain block + latestCallOpts := &bind.CallOpts{Context: ctx} // use the latest block // connect to registry contract registryAddress := gethcommon.HexToAddress(k.cfg.RegistryAddress) @@ -139,8 +141,21 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { // check upkeep if triggerType == ConditionTrigger { message("upkeep identified as conditional trigger") + + if len(args) > 1 { + // if a block number is provided, use that block for both checkUpkeep and simulatePerformUpkeep + blockNum, err = strconv.ParseUint(args[1], 10, 64) + if err != nil { + failCheckArgs("unable to parse block number", err) + } + triggerCallOpts = &bind.CallOpts{Context: ctx, BlockNumber: new(big.Int).SetUint64(blockNum)} + } else { + // if no block number is provided, use latest block for both checkUpkeep and simulatePerformUpkeep + triggerCallOpts = latestCallOpts + } + var tmpCheckResult iregistry21.CheckUpkeep0 - tmpCheckResult, err = keeperRegistry21.CheckUpkeep0(latestCallOpts, upkeepID) + tmpCheckResult, err = keeperRegistry21.CheckUpkeep0(triggerCallOpts, upkeepID) if err != nil { failUnknown("failed to check upkeep: ", err) } @@ -251,11 +266,12 @@ func (k *Keeper) Debug(ctx context.Context, args []string) { resolveIneligible(fmt.Sprintf("invalid trigger type: %d", triggerType)) } upkeepNeeded, performData = checkResult.UpkeepNeeded, checkResult.PerformData - // handle streams lookup + if checkResult.UpkeepFailureReason != 0 { message(fmt.Sprintf("checkUpkeep failed with UpkeepFailureReason %s", getCheckUpkeepFailureReason(checkResult.UpkeepFailureReason))) } + // handle data streams lookup if checkResult.UpkeepFailureReason == uint8(encoding.UpkeepFailureReasonTargetCheckReverted) { mc := &types2.MercuryCredentials{LegacyURL: k.cfg.DataStreamsLegacyURL, URL: k.cfg.DataStreamsURL, Username: k.cfg.DataStreamsID, Password: k.cfg.DataStreamsKey} mercuryConfig := evm21.NewMercuryConfig(mc, core.StreamsCompatibleABI)