Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 44 additions & 9 deletions cmd/workflow/simulate/chain/evm/chaintype.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"strconv"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
Expand All @@ -33,6 +34,7 @@ func init() {
}, []chain.CLIFlagDef{
{Name: TriggerInputTxHash, Description: "EVM trigger transaction hash (0x...)", FlagType: chain.CLIFlagString},
{Name: TriggerInputEventIndex, Description: "EVM trigger log index (0-based)", DefaultValue: "-1", FlagType: chain.CLIFlagInt},
{Name: TriggerInputReceiptTimeout, Description: "Timeout for waiting on an EVM transaction receipt (e.g. 30s, 2m)", DefaultValue: "1m", FlagType: chain.CLIFlagString},
})
}

Expand Down Expand Up @@ -266,8 +268,9 @@ func isHexString(s string) bool {

// CLI input keys consumed from chain.TriggerParams.ChainTypeInputs.
const (
TriggerInputTxHash = "evm-tx-hash"
TriggerInputEventIndex = "evm-event-index"
TriggerInputTxHash = "evm-tx-hash"
TriggerInputEventIndex = "evm-event-index"
TriggerInputReceiptTimeout = "evm-receipt-timeout"
)

func (ct *EVMChainType) CollectCLIInputs(v *viper.Viper) map[string]string {
Expand All @@ -278,11 +281,15 @@ func (ct *EVMChainType) CollectCLIInputs(v *viper.Viper) map[string]string {
if idx := v.GetInt(TriggerInputEventIndex); idx >= 0 {
inputs[TriggerInputEventIndex] = strconv.Itoa(idx)
}
if timeout := strings.TrimSpace(v.GetString(TriggerInputReceiptTimeout)); timeout != "" {
inputs[TriggerInputReceiptTimeout] = timeout
}
return inputs
}

// ResolveTriggerData fetches the EVM log payload for the given selector from
// CLI-supplied or interactively-prompted inputs.
// CLI-supplied inputs, falling back to live log subscription in interactive mode
// when no replay tx hash is given.
func (ct *EVMChainType) ResolveTriggerData(ctx context.Context, selector uint64, params chain.TriggerParams) (interface{}, error) {
clientIface, ok := params.Clients[selector]
if !ok {
Expand All @@ -293,18 +300,46 @@ func (ct *EVMChainType) ResolveTriggerData(ctx context.Context, selector uint64,
return nil, fmt.Errorf("invalid client type for EVM chain selector %d", selector)
}

if params.Interactive {
return GetEVMTriggerLog(ctx, client)
receiptTimeout := time.Minute // default
if raw := strings.TrimSpace(params.ChainTypeInputs[TriggerInputReceiptTimeout]); raw != "" {
d, err := time.ParseDuration(raw)
if err != nil {
return nil, fmt.Errorf("invalid --%s %q: %w", TriggerInputReceiptTimeout, raw, err)
}
receiptTimeout = d
}

txHash := strings.TrimSpace(params.ChainTypeInputs[TriggerInputTxHash])
eventIndexStr := strings.TrimSpace(params.ChainTypeInputs[TriggerInputEventIndex])
if txHash == "" || eventIndexStr == "" {

// Replay path: explicit --evm-tx-hash. Works in both interactive and
// non-interactive modes for deterministic testing / CI.
if txHash != "" {
if eventIndexStr == "" {
return nil, fmt.Errorf("--evm-event-index is required when --evm-tx-hash is provided")
}
eventIndex, err := strconv.ParseUint(eventIndexStr, 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid --evm-event-index %q: %w", eventIndexStr, err)
}
if params.Interactive {
printEVMTriggerReplayHeader(selector, txHash, eventIndex)
}
return GetEVMTriggerLogFromValues(ctx, client, txHash, eventIndex, receiptTimeout)
}

if !params.Interactive {
return nil, fmt.Errorf("--evm-tx-hash and --evm-event-index are required for EVM triggers in non-interactive mode")
}
eventIndex, err := strconv.ParseUint(eventIndexStr, 10, 64)

// Interactive wait-for-log path.
cfg, err := decodeLogTriggerConfig(params.TriggerPayload)
if err != nil {
return nil, fmt.Errorf("invalid --evm-event-index %q: %w", eventIndexStr, err)
return nil, fmt.Errorf("failed to decode EVM log trigger config: %w", err)
}
return GetEVMTriggerLogFromValues(ctx, client, txHash, eventIndex)
return WaitForEVMTriggerLog(ctx, client, WaitForLogConfig{
Selector: selector,
Filter: cfg,
WorkflowName: params.WorkflowName,
})
}
Loading
Loading