diff --git a/cmd/flags.go b/cmd/flags.go index 3fc671294..bf43350e9 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -11,55 +11,56 @@ import ( ) const ( - flagHome = "home" - flagURL = "url" - flagSkip = "skip" - flagTimeout = "timeout" - flagJSON = "json" - flagYAML = "yaml" - flagFile = "file" - flagForceAdd = "force-add" - flagPath = "path" - flagTestnet = "testnet" - flagMaxMsgLength = "max-msgs" - flagIBCDenoms = "ibc-denoms" - flagTimeoutHeightOffset = "timeout-height-offset" - flagTimeoutTimeOffset = "timeout-time-offset" - flagMaxRetries = "max-retries" - flagThresholdTime = "time-threshold" - flagUpdateAfterExpiry = "update-after-expiry" - flagUpdateAfterMisbehaviour = "update-after-misbehaviour" - flagClientTrustingPeriod = "client-tp" - flagClientUnbondingPeriod = "client-unbonding-period" - flagOverride = "override" - flagSrcPort = "src-port" - flagDstPort = "dst-port" - flagOrder = "order" - flagVersion = "version" - flagDebugAddr = "debug-addr" - flagOverwriteConfig = "overwrite" - flagLimit = "limit" - flagHeight = "height" - flagPage = "page" - flagPageKey = "page-key" - flagCountTotal = "count-total" - flagReverse = "reverse" - flagProcessor = "processor" - flagInitialBlockHistory = "block-history" - flagFlushInterval = "flush-interval" - flagMemo = "memo" - flagFilterRule = "filter-rule" - flagFilterChannels = "filter-channels" - flagSrcChainID = "src-chain-id" - flagDstChainID = "dst-chain-id" - flagSrcClientID = "src-client-id" - flagDstClientID = "dst-client-id" - flagSrcConnID = "src-connection-id" - flagDstConnID = "dst-connection-id" - flagOutput = "output" - flagStuckPacketChainID = "stuck-packet-chain-id" - flagStuckPacketHeightStart = "stuck-packet-height-start" - flagStuckPacketHeightEnd = "stuck-packet-height-end" + flagHome = "home" + flagURL = "url" + flagSkip = "skip" + flagTimeout = "timeout" + flagJSON = "json" + flagYAML = "yaml" + flagFile = "file" + flagForceAdd = "force-add" + flagPath = "path" + flagTestnet = "testnet" + flagMaxMsgLength = "max-msgs" + flagIBCDenoms = "ibc-denoms" + flagTimeoutHeightOffset = "timeout-height-offset" + flagTimeoutTimeOffset = "timeout-time-offset" + flagMaxRetries = "max-retries" + flagThresholdTime = "time-threshold" + flagUpdateAfterExpiry = "update-after-expiry" + flagUpdateAfterMisbehaviour = "update-after-misbehaviour" + flagClientTrustingPeriod = "client-tp" + flagClientUnbondingPeriod = "client-unbonding-period" + flagClientTrustingPeriodPercentage = "client-tp-percentage" + flagOverride = "override" + flagSrcPort = "src-port" + flagDstPort = "dst-port" + flagOrder = "order" + flagVersion = "version" + flagDebugAddr = "debug-addr" + flagOverwriteConfig = "overwrite" + flagLimit = "limit" + flagHeight = "height" + flagPage = "page" + flagPageKey = "page-key" + flagCountTotal = "count-total" + flagReverse = "reverse" + flagProcessor = "processor" + flagInitialBlockHistory = "block-history" + flagFlushInterval = "flush-interval" + flagMemo = "memo" + flagFilterRule = "filter-rule" + flagFilterChannels = "filter-channels" + flagSrcChainID = "src-chain-id" + flagDstChainID = "dst-chain-id" + flagSrcClientID = "src-client-id" + flagDstClientID = "dst-client-id" + flagSrcConnID = "src-connection-id" + flagDstConnID = "dst-connection-id" + flagOutput = "output" + flagStuckPacketChainID = "stuck-packet-chain-id" + flagStuckPacketHeightStart = "stuck-packet-height-start" + flagStuckPacketHeightEnd = "stuck-packet-height-end" ) const blankValue = "blank" @@ -323,7 +324,12 @@ func clientParameterFlags(v *viper.Viper, cmd *cobra.Command) *cobra.Command { cmd.Flags().Duration( flagClientTrustingPeriod, 0, - "custom light client trusting period ex. 24h (default: 85% of chains reported unbonding time)", + "custom light client trusting period ex. 24h (default: 85% of chains reported unbonding time)`", + ) + cmd.Flags().Int64( + flagClientTrustingPeriodPercentage, + 85, + "custom light client trusting period percentage ex. 66 (default: 85); this flag overrides the client-tp flag", ) if err := v.BindPFlag(flagUpdateAfterExpiry, cmd.Flags().Lookup(flagUpdateAfterExpiry)); err != nil { @@ -337,6 +343,11 @@ func clientParameterFlags(v *viper.Viper, cmd *cobra.Command) *cobra.Command { if err := v.BindPFlag(flagClientTrustingPeriod, cmd.Flags().Lookup(flagClientTrustingPeriod)); err != nil { panic(err) } + + if err := v.BindPFlag(flagClientTrustingPeriodPercentage, cmd.Flags().Lookup(flagClientTrustingPeriodPercentage)); err != nil { + panic(err) + } + return cmd } diff --git a/cmd/tx.go b/cmd/tx.go index f986f97f3..fba474708 100644 --- a/cmd/tx.go +++ b/cmd/tx.go @@ -4,10 +4,10 @@ import ( "context" "errors" "fmt" + "github.com/avast/retry-go/v4" "strings" "time" - "github.com/avast/retry-go/v4" sdk "github.com/cosmos/cosmos-sdk/types" chantypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "github.com/cosmos/relayer/v2/relayer" @@ -79,6 +79,11 @@ func createClientsCmd(a *appState) *cobra.Command { return err } + customClientTrustingPeriodPercentage, err := cmd.Flags().GetInt64(flagClientTrustingPeriodPercentage) + if err != nil { + return err + } + override, err := cmd.Flags().GetBool(flagOverride) if err != nil { return err @@ -106,6 +111,7 @@ func createClientsCmd(a *appState) *cobra.Command { allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, + customClientTrustingPeriodPercentage, a.config.memo(cmd), ) if err != nil { @@ -152,6 +158,11 @@ func createClientCmd(a *appState) *cobra.Command { return err } + customClientTrustingPeriodPercentage, err := cmd.Flags().GetInt64(flagClientTrustingPeriodPercentage) + if err != nil { + return err + } + overrideUnbondingPeriod, err := cmd.Flags().GetDuration(flagClientUnbondingPeriod) if err != nil { return err @@ -239,6 +250,7 @@ func createClientCmd(a *appState) *cobra.Command { allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, + customClientTrustingPeriodPercentage, overrideUnbondingPeriod, a.config.memo(cmd), ) @@ -374,6 +386,11 @@ $ %s tx conn demo-path --timeout 5s`, return err } + customClientTrustingPeriodPercentage, err := cmd.Flags().GetInt64(flagClientTrustingPeriodPercentage) + if err != nil { + return err + } + pathName := args[0] c, src, dst, err := a.config.ChainsFromPath(pathName) @@ -420,6 +437,7 @@ $ %s tx conn demo-path --timeout 5s`, allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, + customClientTrustingPeriodPercentage, memo, ) if err != nil { @@ -649,6 +667,11 @@ $ %s tx connect demo-path --src-port transfer --dst-port transfer --order unorde return err } + customClientTrustingPeriodPercentage, err := cmd.Flags().GetInt64(flagClientTrustingPeriodPercentage) + if err != nil { + return err + } + pathName := args[0] pth, err := a.config.Paths.Get(pathName) @@ -724,6 +747,7 @@ $ %s tx connect demo-path --src-port transfer --dst-port transfer --order unorde allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, + customClientTrustingPeriodPercentage, memo, ) if err != nil { diff --git a/relayer/chain.go b/relayer/chain.go index 76d26433e..dfcf728cb 100644 --- a/relayer/chain.go +++ b/relayer/chain.go @@ -4,10 +4,10 @@ import ( "context" "encoding/json" "fmt" + "github.com/avast/retry-go/v4" "net/url" "time" - "github.com/avast/retry-go/v4" "github.com/cosmos/cosmos-sdk/crypto/hd" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/cosmos/relayer/v2/relayer/provider" @@ -96,8 +96,8 @@ func (c *Chain) GetSelfVersion() uint64 { } // GetTrustingPeriod returns the trusting period for the chain -func (c *Chain) GetTrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration) (time.Duration, error) { - return c.ChainProvider.TrustingPeriod(ctx, overrideUnbondingPeriod) +func (c *Chain) GetTrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration, percentage int64) (time.Duration, error) { + return c.ChainProvider.TrustingPeriod(ctx, overrideUnbondingPeriod, percentage) } func (c *Chain) String() string { diff --git a/relayer/chains/cosmos/provider.go b/relayer/chains/cosmos/provider.go index f7c82b9dd..82ea7b98a 100644 --- a/relayer/chains/cosmos/provider.go +++ b/relayer/chains/cosmos/provider.go @@ -237,7 +237,7 @@ func (cc *CosmosProvider) AccountFromKeyOrAddress(keyOrAddress string) (out sdk. return } -func (cc *CosmosProvider) TrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration) (time.Duration, error) { +func (cc *CosmosProvider) TrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration, percentage int64) (time.Duration, error) { unbondingTime := overrideUnbondingPeriod var err error @@ -248,13 +248,13 @@ func (cc *CosmosProvider) TrustingPeriod(ctx context.Context, overrideUnbondingP } } - // We want the trusting period to be 85% of the unbonding time. + // We want the trusting period to be `percentage` of the unbonding time. // Go mentions that the time.Duration type can track approximately 290 years. // We don't want to lose precision if the duration is a very long duration // by converting int64 to float64. // Use integer math the whole time, first reducing by a factor of 100 - // and then re-growing by 85x. - tp := unbondingTime / 100 * 85 + // and then re-growing by the `percentage` param. + tp := time.Duration(int64(unbondingTime) / 100 * percentage) // And we only want the trusting period to be whole hours. // But avoid rounding if the time is less than 1 hour diff --git a/relayer/chains/penumbra/provider.go b/relayer/chains/penumbra/provider.go index a580322ee..94de76884 100644 --- a/relayer/chains/penumbra/provider.go +++ b/relayer/chains/penumbra/provider.go @@ -208,7 +208,7 @@ func (cc *PenumbraProvider) Address() (string, error) { return out, err } -func (cc *PenumbraProvider) TrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration) (time.Duration, error) { +func (cc *PenumbraProvider) TrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration, percentage int64) (time.Duration, error) { // TODO return time.Hour * 2, nil /* @@ -223,7 +223,7 @@ func (cc *PenumbraProvider) TrustingPeriod(ctx context.Context, overrideUnbondin // by converting int64 to float64. // Use integer math the whole time, first reducing by a factor of 100 // and then re-growing by 85x. - tp := res.UnbondingTime / 100 * 85 + tp := res.UnbondingTime / 100 * 85 // TODO: replace with percentage // And we only want the trusting period to be whole hours. return tp.Truncate(time.Hour), nil diff --git a/relayer/client.go b/relayer/client.go index 3e4f10da2..393875b7b 100644 --- a/relayer/client.go +++ b/relayer/client.go @@ -3,8 +3,6 @@ package relayer import ( "context" "fmt" - "time" - "github.com/avast/retry-go/v4" codectypes "github.com/cosmos/cosmos-sdk/codec/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -13,10 +11,11 @@ import ( "github.com/cosmos/relayer/v2/relayer/provider" "go.uber.org/zap" "golang.org/x/sync/errgroup" + "time" ) // CreateClients creates clients for src on dst and dst on src if the client ids are unspecified. -func (c *Chain) CreateClients(ctx context.Context, dst *Chain, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour, override bool, customClientTrustingPeriod time.Duration, memo string) (string, string, error) { +func (c *Chain) CreateClients(ctx context.Context, dst *Chain, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour, override bool, customClientTrustingPeriod time.Duration, customClientTrustingPeriodPercentage int64, memo string) (string, string, error) { // Query the latest heights on src and dst and retry if the query fails var srch, dsth int64 if err := retry.Do(func() error { @@ -63,7 +62,7 @@ func (c *Chain) CreateClients(ctx context.Context, dst *Chain, allowUpdateAfterE eg.Go(func() error { var err error // Create client on src for dst if the client id is unspecified - clientSrc, err = CreateClient(egCtx, c, dst, srcUpdateHeader, dstUpdateHeader, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, overrideUnbondingPeriod, memo) + clientSrc, err = CreateClient(egCtx, c, dst, srcUpdateHeader, dstUpdateHeader, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, customClientTrustingPeriodPercentage, overrideUnbondingPeriod, memo) if err != nil { return fmt.Errorf("failed to create client on src chain{%s}: %w", c.ChainID(), err) } @@ -73,7 +72,7 @@ func (c *Chain) CreateClients(ctx context.Context, dst *Chain, allowUpdateAfterE eg.Go(func() error { var err error // Create client on dst for src if the client id is unspecified - clientDst, err = CreateClient(egCtx, dst, c, dstUpdateHeader, srcUpdateHeader, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, overrideUnbondingPeriod, memo) + clientDst, err = CreateClient(egCtx, dst, c, dstUpdateHeader, srcUpdateHeader, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour, override, customClientTrustingPeriod, customClientTrustingPeriodPercentage, overrideUnbondingPeriod, memo) if err != nil { return fmt.Errorf("failed to create client on dst chain{%s}: %w", dst.ChainID(), err) } @@ -105,6 +104,7 @@ func CreateClient( allowUpdateAfterMisbehaviour bool, override bool, customClientTrustingPeriod time.Duration, + customClientTrustingPeriodPercentage int64, overrideUnbondingPeriod time.Duration, memo string) (string, error) { // If a client ID was specified in the path and override is not set, ensure the client exists. @@ -126,7 +126,7 @@ func CreateClient( if tp == 0 { if err := retry.Do(func() error { var err error - tp, err = dst.GetTrustingPeriod(ctx, overrideUnbondingPeriod) + tp, err = dst.GetTrustingPeriod(ctx, overrideUnbondingPeriod, customClientTrustingPeriodPercentage) if err != nil { return fmt.Errorf("failed to get trusting period for chain{%s}: %w", dst.ChainID(), err) } diff --git a/relayer/provider/provider.go b/relayer/provider/provider.go index b962e8735..df2b3e6dc 100644 --- a/relayer/provider/provider.go +++ b/relayer/provider/provider.go @@ -404,7 +404,7 @@ type ChainProvider interface { Key() string Address() (string, error) Timeout() string - TrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration) (time.Duration, error) + TrustingPeriod(ctx context.Context, overrideUnbondingPeriod time.Duration, percentage int64) (time.Duration, error) WaitForNBlocks(ctx context.Context, n int64) error Sprint(toPrint proto.Message) (string, error)