Skip to content

Commit

Permalink
WIP tests for inactive validators
Browse files Browse the repository at this point in the history
  • Loading branch information
fastfadingviolets committed Aug 19, 2024
1 parent e5adc74 commit 2b3a92c
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 40 deletions.
82 changes: 60 additions & 22 deletions tests/interchain/chainsuite/chain_ics.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/strangelove-ventures/interchaintest/v8/testutil"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"go.uber.org/multierr"
"golang.org/x/mod/semver"

clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
Expand Down Expand Up @@ -219,7 +220,6 @@ func (p *Chain) DefaultConsumerChainSpec(ctx context.Context, chainID string, co
}
genesisOverrides := []cosmos.GenesisKV{
cosmos.NewGenesisKV("app_state.slashing.params.signed_blocks_window", strconv.Itoa(SlashingWindowConsumer)),
cosmos.NewGenesisKV("consensus_params.block.max_gas", "50000000"),
}
if config.TopN >= 0 {
genesisOverrides = append(genesisOverrides, cosmos.NewGenesisKV("app_state.ccvconsumer.params.soft_opt_out_threshold", "0.0"))
Expand All @@ -235,22 +235,30 @@ func (p *Chain) DefaultConsumerChainSpec(ctx context.Context, chainID string, co
)
}

modifyGenesis := cosmos.ModifyGenesis(genesisOverrides)
if chainType == strideChain {
genesisOverrides = append(genesisOverrides,
cosmos.NewGenesisKV("app_state.gov.params.voting_period", GovVotingPeriod.String()),
)
modifyGenesis = func(cc ibc.ChainConfig, b []byte) ([]byte, error) {
b, err := cosmos.ModifyGenesis(genesisOverrides)(cc, b)
}
modifyGenesis := func(cc ibc.ChainConfig, b []byte) ([]byte, error) {
b, err := cosmos.ModifyGenesis(genesisOverrides)(cc, b)
if err != nil {
return nil, err
}
if chainType == strideChain {
b, err = sjson.SetBytes(b, "app_state.epochs.epochs.#(identifier==\"day\").duration", "120s")
if err != nil {
return nil, err
}
b, err = sjson.SetBytes(b, "app_state.epochs.epochs.#(identifier==\"day\").duration", "120s")
b, err = sjson.SetBytes(b, "app_state.epochs.epochs.#(identifier==\"stride_epoch\").duration", "30s")
if err != nil {
return nil, err
}
return sjson.SetBytes(b, "app_state.epochs.epochs.#(identifier==\"stride_epoch\").duration", "30s")
}
if gjson.GetBytes(b, "consensus").Exists() {
return sjson.SetBytes(b, "consensus.block.max_gas", "50000000")
}
return sjson.SetBytes(b, "consensus_params.block.max_gas", "50000000")
}

return &interchaintest.ChainSpec{
Expand Down Expand Up @@ -403,6 +411,7 @@ func (p *Chain) consumerAdditionProposal(ctx context.Context, chainID string, co
HistoricalEntries: 10000,
UnbondingPeriod: 1728000000000000,
Deposit: strconv.Itoa(GovMinDepositAmount/2) + p.Config().Denom,
MinStake: uint64(3_999_999),
}
if config.TopN >= 0 {
prop.TopN = uint32(config.TopN)
Expand All @@ -417,7 +426,7 @@ func (p *Chain) consumerAdditionProposal(ctx context.Context, chainID string, co
if err != nil {
return nil, nil, err
}
errCh := make(chan error)
errCh := make(chan error, 1)
go func() {
defer close(errCh)
if err := p.WaitForProposalStatus(ctx, propTx.ProposalID, govv1.StatusDepositPeriod); err != nil {
Expand Down Expand Up @@ -535,26 +544,55 @@ func (p *Chain) IsValoperJailed(ctx context.Context, valoper string) (bool, erro
return gjson.GetBytes(out, "validator.jailed").Bool(), nil
}

func (p *Chain) IsValidatorJailedForConsumerDowntime(ctx context.Context, relayer Relayer, consumer *Chain, validatorIdx int) (jailed bool, err error) {
func (p *Chain) IsValidatorJailedForConsumerDowntime(ctx context.Context, relayer *Relayer, consumer *Chain, validatorIdx int) (jailed bool, err error) {
if err = consumer.Validators[validatorIdx].StopContainer(ctx); err != nil {
return
}
defer func() {
err = consumer.Validators[validatorIdx].StartContainer(ctx)
sErr := consumer.Validators[validatorIdx].StartContainer(ctx)
if sErr != nil {
err = multierr.Append(err, sErr)
return
}
time.Sleep(10 * CommitTimeout)
if jailed && err == nil {
if _, err = p.Validators[validatorIdx].ExecTx(ctx, p.ValidatorWallets[validatorIdx].Moniker, "slashing", "unjail"); err != nil {
return
}
var stillJailed bool
if stillJailed, err = p.IsValoperJailed(ctx, p.ValidatorWallets[validatorIdx].ValoperAddress); stillJailed {
err = fmt.Errorf("validator %d is still jailed after unjailing", validatorIdx)
}
}
}()
channel, err := relayer.GetChannelWithPort(ctx, consumer, p, "consumer")
if err != nil {
return
}
if err = testutil.WaitForBlocks(ctx, SlashingWindowConsumer+1, consumer); err != nil {
return
}
rs := relayer.Exec(ctx, GetRelayerExecReporter(ctx), []string{
"hermes", "clear", "packets", "--port", "consumer", "--channel", channel.ChannelID,
"--chain", consumer.Config().ChainID,
}, nil)
if rs.Err != nil {
return false, rs.Err
if p.Config().ChainID != consumer.Config().ChainID {
var channel *ibc.ChannelOutput
channel, err = relayer.GetChannelWithPort(ctx, consumer, p, "consumer")
if err != nil {
return
}
rs := relayer.Exec(ctx, GetRelayerExecReporter(ctx), []string{
"hermes", "clear", "packets", "--port", "consumer", "--channel", channel.ChannelID,
"--chain", consumer.Config().ChainID,
}, nil)
if rs.Err != nil {
return false, rs.Err
}
tCtx, tCancel := context.WithTimeout(ctx, (SlashingWindowConsumer+3)*CommitTimeout)
defer tCancel()
if err = testutil.WaitForBlocks(tCtx, SlashingWindowConsumer+1, consumer); err != nil {
if tCtx.Err() != nil {
err = fmt.Errorf("chain %s is stopped: %w", consumer.Config().ChainID, err)
}
return
}
rs = relayer.Exec(ctx, GetRelayerExecReporter(ctx), []string{
"hermes", "clear", "packets", "--port", "consumer", "--channel", channel.ChannelID,
"--chain", consumer.Config().ChainID,
}, nil)
if rs.Err != nil {
return false, rs.Err
}
}
tCtx, tCancel := context.WithTimeout(ctx, 30*CommitTimeout)
defer tCancel()
Expand Down
138 changes: 138 additions & 0 deletions tests/interchain/consensus_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package interchain_test

import (
"encoding/json"
"fmt"
"testing"

"github.com/cosmos/gaia/v20/tests/interchain/chainsuite"
"github.com/stretchr/testify/suite"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)

type ConsensusSuite struct {
*chainsuite.Suite
}

func (s *ConsensusSuite) TestInactiveValidators() {
authority, err := s.Chain.GetGovernanceAddress(s.GetContext())
s.Require().NoError(err)

stakingProposal := fmt.Sprintf(`{
"@type": "/cosmos.staking.v1beta1.MsgUpdateParams",
"authority": "%s",
"params": {
"unbonding_time": "1814400s",
"max_validators": 5,
"max_entries": 7,
"historical_entries": 10000,
"bond_denom": "%s",
"min_commission_rate": "0.050000000000000000",
"validator_bond_factor": "250.000000000000000000",
"global_liquid_staking_cap": "0.250000000000000000",
"validator_liquid_staking_cap": "0.500000000000000000"
}
}`, authority, s.Chain.Config().Denom)

prop, err := s.Chain.BuildProposal(nil, "update staking params", "update staking params", "", chainsuite.GovDepositAmount, "", false)
s.Require().NoError(err)
prop.Messages = []json.RawMessage{json.RawMessage(stakingProposal)}
result, err := s.Chain.SubmitProposal(s.GetContext(), s.Chain.ValidatorWallets[0].Moniker, prop)
s.Require().NoError(err)
s.Require().NoError(s.Chain.PassProposal(s.GetContext(), result.ProposalID))
s.UpgradeChain()

stakingParams, _, err := s.Chain.GetNode().ExecQuery(s.GetContext(), "staking", "params")
s.Require().NoError(err)
s.Require().Equal(uint64(200), gjson.GetBytes(stakingParams, "params.max_validators").Uint(), string(stakingParams))

providerParams, _, err := s.Chain.GetNode().ExecQuery(s.GetContext(), "provider", "params")
s.Require().NoError(err)
s.Require().Equal(uint64(180), gjson.GetBytes(providerParams, "max_provider_consensus_validators").Uint(), string(providerParams))
providerParams, err = sjson.SetBytes(providerParams, "max_provider_consensus_validators", 4)
s.Require().NoError(err)
providerProposal, err := sjson.SetRaw(fmt.Sprintf(`{
"@type": "/interchain_security.ccv.provider.v1.MsgUpdateParams",
"authority": "%s"
}`, authority), "params", string(providerParams))
s.Require().NoError(err)

stakingProposal, err = sjson.Set(stakingProposal, "params.max_validators", 5)
s.Require().NoError(err)
prop, err = s.Chain.BuildProposal(nil, "update staking params", "update staking params", "", chainsuite.GovDepositAmount, "", false)
s.Require().NoError(err)
prop.Messages = append(prop.Messages, json.RawMessage(stakingProposal))
result, err = s.Chain.SubmitProposal(s.GetContext(), s.Chain.ValidatorWallets[0].Moniker, prop)
s.Require().NoError(err)
s.Require().NoError(s.Chain.PassProposal(s.GetContext(), result.ProposalID))

prop, err = s.Chain.BuildProposal(nil, "update provider params", "update provider params", "", chainsuite.GovDepositAmount, "", false)
s.Require().NoError(err)
prop.Messages = []json.RawMessage{json.RawMessage(providerProposal)}
result, err = s.Chain.SubmitProposal(s.GetContext(), s.Chain.ValidatorWallets[0].Moniker, prop)
s.Require().NoError(err)
s.Require().NoError(s.Chain.PassProposal(s.GetContext(), result.ProposalID))

for i := 1; i < 4; i++ {
jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, s.Chain, i)
s.Require().NoError(err)
s.Assert().True(jailed, "validator %d should be jailed", i)
}
for i := 4; i < 6; i++ {
jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, s.Chain, i)
s.Require().NoError(err)
s.Assert().False(jailed, "validator %d should not be jailed", i)
}

cfg := chainsuite.ConsumerConfig{
ChainName: "ics-consumer",
Version: "v5.0.0",
ShouldCopyProviderKey: allProviderKeysCopied(),
Denom: chainsuite.Ucon,
TopN: 100,
}
consumer, err := s.Chain.AddConsumerChain(s.GetContext(), s.Relayer, cfg)
s.Require().NoError(err)

vals, err := consumer.QueryJSON(s.GetContext(), "validators", "comet-validator-set")
s.Require().NoError(err)
s.Require().Equal(4, len(vals.Array()), vals)

err = s.Chain.CheckCCV(s.GetContext(), consumer, s.Relayer, 1_000_000, 0, 1)
s.Require().NoError(err)

vals, err = consumer.QueryJSON(s.GetContext(), "validators", "comet-validator-set")
s.Require().NoError(err)
s.Require().Equal(4, len(vals.Array()), vals)

for i := 1; i < 4; i++ {
jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer, i)
s.Require().NoError(err)
s.Assert().True(jailed, "validator %d should be jailed", i)
}
for i := 4; i < 6; i++ {
jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer, i)
s.Require().NoError(err)
s.Assert().False(jailed, "validator %d should not be jailed", i)
}

_, err = s.Chain.Validators[4].ExecTx(s.GetContext(), s.Chain.ValidatorWallets[4].Moniker, "provider", "opt-in", consumer.Config().ChainID)
s.Require().NoError(err)
jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer, 4)
s.Require().NoError(err)
s.Assert().True(jailed, "validator 4 should be jailed")

_, err = s.Chain.Validators[5].ExecTx(s.GetContext(), s.Chain.ValidatorWallets[5].Moniker, "provider", "opt-in", consumer.Config().ChainID)
s.Require().Error(err)
jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer, 5)
s.Require().NoError(err)
s.Assert().False(jailed, "validator 5 should not be jailed")
}

func TestConsensus(t *testing.T) {
s := &ConsensusSuite{
Suite: chainsuite.NewSuite(chainsuite.SuiteConfig{CreateRelayer: true}),
}
suite.Run(t, s)
}
8 changes: 4 additions & 4 deletions tests/interchain/consumer_launch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ func (s *ConsumerLaunchSuite) TestChainLaunch() {
s.Require().NoError(err)
s.Require().NoError(chainsuite.SendSimpleIBCTx(s.GetContext(), s.Chain, consumer, s.Relayer))

jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), *s.Relayer, consumer, 1)
jailed, err := s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer, 1)
s.Require().NoError(err)
s.Require().True(jailed, "validator 1 should be jailed for downtime")
jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), *s.Relayer, consumer, 5)
jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer, 5)
s.Require().NoError(err)
s.Require().False(jailed, "validator 5 should not be jailed for downtime")

Expand All @@ -59,10 +59,10 @@ func (s *ConsumerLaunchSuite) TestChainLaunch() {
s.Require().NoError(err)
s.Require().NoError(chainsuite.SendSimpleIBCTx(s.GetContext(), s.Chain, consumer2, s.Relayer))

jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), *s.Relayer, consumer2, 1)
jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer2, 1)
s.Require().NoError(err)
s.Require().True(jailed, "validator 1 should be jailed for downtime")
jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), *s.Relayer, consumer2, 5)
jailed, err = s.Chain.IsValidatorJailedForConsumerDowntime(s.GetContext(), s.Relayer, consumer2, 5)
s.Require().NoError(err)
s.Require().False(jailed, "validator 5 should not be jailed for downtime")
}
Expand Down
12 changes: 6 additions & 6 deletions tests/interchain/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ replace (
github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d
github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0
github.com/btcsuite/btcd/btcec/v2 => github.com/btcsuite/btcd/btcec/v2 v2.3.2 // 2.3.4 breaks api
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.50.8
github.com/cosmos/interchain-security/v5 => github.com/cosmos/interchain-security/v5 v5.0.1-0.20240718110115-76496d08f129
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.50.9-lsm
github.com/cosmos/interchain-security/v5 => github.com/cosmos/interchain-security/v5 v5.0.0-20240806104629-29327696b8e6
github.com/docker/distribution => github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker => github.com/docker/docker v24.0.9+incompatible
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
Expand All @@ -17,15 +17,16 @@ replace (

require (
cosmossdk.io/math v1.3.0
github.com/cometbft/cometbft v0.38.10
github.com/cosmos/cosmos-sdk v0.50.8
github.com/cosmos/ibc-go/v8 v8.3.2
github.com/cosmos/interchain-security/v5 v5.1.0
github.com/cosmos/ibc-go/v8 v8.4.0
github.com/cosmos/interchain-security/v5 v5.1.1
github.com/docker/docker v24.0.9+incompatible
github.com/google/go-github/v62 v62.0.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/strangelove-ventures/interchaintest/v8 v8.6.1
github.com/stretchr/testify v1.9.0
github.com/tidwall/gjson v1.17.1
github.com/tidwall/gjson v1.17.3
github.com/tidwall/sjson v1.2.5
go.uber.org/zap v1.27.0
golang.org/x/mod v0.19.0
Expand Down Expand Up @@ -79,7 +80,6 @@ require (
github.com/cockroachdb/pebble v1.1.1 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft v0.38.10 // indirect
github.com/cometbft/cometbft-db v0.12.0 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.2 // indirect
Expand Down
16 changes: 8 additions & 8 deletions tests/interchain/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,8 @@ github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAK
github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA=
github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA=
github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec=
github.com/cosmos/cosmos-sdk v0.50.8 h1:2UJHssUaGHTl4/dFp8xyREKAnfiRU6VVfqtKG9n8w5g=
github.com/cosmos/cosmos-sdk v0.50.8/go.mod h1:Zb+DgHtiByNwgj71IlJBXwOq6dLhtyAq3AgqpXm/jHo=
github.com/cosmos/cosmos-sdk v0.50.9-lsm h1:nYQVX0YinJ3Zu3PHEee36OeZ8yAw42ctE52S2K3MleM=
github.com/cosmos/cosmos-sdk v0.50.9-lsm/go.mod h1:efdTFdUndXfLpSMkE1Kv/ra8pux9l1glcojMIhNreiA=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
Expand All @@ -387,12 +387,12 @@ github.com/cosmos/iavl v1.2.0 h1:kVxTmjTh4k0Dh1VNL046v6BXqKziqMDzxo93oh3kOfM=
github.com/cosmos/iavl v1.2.0/go.mod h1:HidWWLVAtODJqFD6Hbne2Y0q3SdxByJepHUOeoH4LiI=
github.com/cosmos/ibc-go/modules/capability v1.0.1 h1:ibwhrpJ3SftEEZRxCRkH0fQZ9svjthrX2+oXdZvzgGI=
github.com/cosmos/ibc-go/modules/capability v1.0.1/go.mod h1:rquyOV262nGJplkumH+/LeYs04P3eV8oB7ZM4Ygqk4E=
github.com/cosmos/ibc-go/v8 v8.3.2 h1:8X1oHHKt2Bh9hcExWS89rntLaCKZp2EjFTUSxKlPhGI=
github.com/cosmos/ibc-go/v8 v8.3.2/go.mod h1:WVVIsG39jGrF9Cjggjci6LzySyWGloz194sjTxiGNIE=
github.com/cosmos/ibc-go/v8 v8.4.0 h1:K2PfX0AZ+1XKZytHGEMuSjQXG/MZshPb83RSTQt2+cE=
github.com/cosmos/ibc-go/v8 v8.4.0/go.mod h1:zh6x1osR0hNvEcFrC/lhGD08sMfQmr9wHVvZ/mRWMCs=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cosmos/interchain-security/v5 v5.0.1-0.20240718110115-76496d08f129 h1:DQSMnKnsfSNIVFpg4qCXwB3ZNwacMf9Q9ggaHABZII4=
github.com/cosmos/interchain-security/v5 v5.0.1-0.20240718110115-76496d08f129/go.mod h1:vmeTcTxFCl1eV0o6xpl/IRT7Basz0szVVGzbppnInMg=
github.com/cosmos/interchain-security/v5 v5.0.0-20240806104629-29327696b8e6 h1:aFwnbEdeMUaQg9ZU+Pm8fE3CzZM2gG5jSeAvYOd+hoU=
github.com/cosmos/interchain-security/v5 v5.0.0-20240806104629-29327696b8e6/go.mod h1:sT6a/OIwwkXuH9fBzt5IBa4lrlWO8etgQ+b59pIE8k4=
github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM=
github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
Expand Down Expand Up @@ -1092,8 +1092,8 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM
github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI=
github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
Expand Down

0 comments on commit 2b3a92c

Please sign in to comment.