diff --git a/deployment/common/proposalutils/propose.go b/deployment/common/proposalutils/propose.go index a404e6d3258..2e87860af00 100644 --- a/deployment/common/proposalutils/propose.go +++ b/deployment/common/proposalutils/propose.go @@ -34,6 +34,7 @@ type TimelockConfig struct { MCMSAction types.TimelockAction `json:"mcmsAction"` OverrideRoot bool `json:"overrideRoot"` // if true, override the previous root with the new one. TimelockQualifierPerChain map[uint64]string `json:"timelockQualifierPerChain,omitempty"` // optional qualifier to fetch timelock address from datastore + ValidDuration *time.Duration `json:"validDuration" yaml:"validDuration"` } func (tc *TimelockConfig) MCMBasedOnActionSolana(s state.MCMSWithTimelockStateSolana) (string, error) { @@ -212,7 +213,11 @@ func BuildProposalFromBatchesV2( return nil, err } - validUntil := time.Now().Unix() + int64(DefaultValidUntil.Seconds()) + proposalDuration := DefaultValidUntil + if mcmsCfg.ValidDuration != nil { + proposalDuration = *mcmsCfg.ValidDuration + } + validUntil := time.Now().Add(proposalDuration).Unix() builder := mcmslib.NewTimelockProposalBuilder() builder. diff --git a/deployment/cre/common/strategies/mcms_transaction_test.go b/deployment/cre/common/strategies/mcms_transaction_test.go index aecc996fd68..cc7ccad1dc0 100644 --- a/deployment/cre/common/strategies/mcms_transaction_test.go +++ b/deployment/cre/common/strategies/mcms_transaction_test.go @@ -3,6 +3,7 @@ package strategies_test import ( "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/common" mcmstypes "github.com/smartcontractkit/mcms/types" @@ -201,4 +202,31 @@ func TestMCMSTransaction_BuildProposal(t *testing.T) { assert.True(t, ok) assert.Equal(t, mcmsContracts.CancellerMcm.Address().String(), metadata.MCMAddress) }) + + t.Run("uses custom ValidDuration value to set the proposal duration", func(t *testing.T) { + m := getMCMSTransaction(t, *fixture.Env) + validDuration := 2 * time.Second + cfg := contracts.MCMSConfig{ + MinDelay: 0, + TimelockQualifierPerChain: map[uint64]string{ + fixture.RegistrySelector: "", + }, + ValidDuration: &validDuration, + } + mcmsContracts, err := strategies.GetMCMSContracts(*fixture.Env, fixture.RegistrySelector, cfg) + require.NoError(t, err) + m.Config = &cfg + m.MCMSContracts = mcmsContracts + m.ChainSel = fixture.RegistrySelector + + op, err := proposalutils.BatchOperationForChain(m.ChainSel, m.Address.Hex(), []byte{0x01, 0x02, 0x03}, big.NewInt(0), "", nil) + require.NoError(t, err) + + p, err := m.BuildProposal([]mcmstypes.BatchOperation{op}) + require.NoError(t, err) + + expectedValidUntil := time.Now().Add(validDuration).Unix() + // Using InDelta to allow for slight timing differences during test execution + assert.InDelta(t, uint32(expectedValidUntil), p.ValidUntil, 1, "ValidUntil should be within 1 second of expected value") //nolint:gosec // G115 + }) } diff --git a/deployment/cre/contracts/contracts.go b/deployment/cre/contracts/contracts.go index 8a73d9cd314..b2c63a82ede 100644 --- a/deployment/cre/contracts/contracts.go +++ b/deployment/cre/contracts/contracts.go @@ -7,15 +7,13 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink/deployment/common/changeset/state" - "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" - - "github.com/smartcontractkit/chainlink-deployments-framework/datastore" - cldf_evm "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/changeset/state" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/deployment/common/types" capabilities_registry "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0"