Skip to content

Commit

Permalink
feat(v8)!: validators can have different genesis and self-delegation …
Browse files Browse the repository at this point in the history
…amounts (backport #1028) (#1039)

* feat(v7)!: validators can have different genesis and self-delegation amounts (#1028)

* feat validators can have different genesis and self-delegation amounts

this is done by making ModifyGenesisAmounts take in an index parameter;
the returned values will be used for the validator at that index.

* Add a test for stake distribution in cosmos chains

(cherry picked from commit 2908114)

* fix v7 -> v8 namespace

---------

Co-authored-by: violet <158512193+fastfadingviolets@users.noreply.github.com>
Co-authored-by: Reece Williams <reecepbcups@gmail.com>
  • Loading branch information
3 people authored Mar 30, 2024
1 parent 8114cff commit 5f41f4b
Show file tree
Hide file tree
Showing 4 changed files with 364 additions and 19 deletions.
32 changes: 15 additions & 17 deletions chain/cosmos/cosmos_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -779,28 +779,26 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene

decimalPow := int64(math.Pow10(int(*chainCfg.CoinDecimals)))

genesisAmount := types.Coin{
Amount: sdkmath.NewInt(10_000_000).MulRaw(decimalPow),
Denom: chainCfg.Denom,
}

genesisSelfDelegation := types.Coin{
Amount: sdkmath.NewInt(5_000_000).MulRaw(decimalPow),
Denom: chainCfg.Denom,
}

if chainCfg.ModifyGenesisAmounts != nil {
genesisAmount, genesisSelfDelegation = chainCfg.ModifyGenesisAmounts()
genesisAmounts := make([][]types.Coin, len(c.Validators))
genesisSelfDelegation := make([]types.Coin, len(c.Validators))

for i := range c.Validators {
genesisAmounts[i] = []types.Coin{{Amount: sdkmath.NewInt(10_000_000).MulRaw(decimalPow), Denom: chainCfg.Denom}}
genesisSelfDelegation[i] = types.Coin{Amount: sdkmath.NewInt(5_000_000).MulRaw(decimalPow), Denom: chainCfg.Denom}
if chainCfg.ModifyGenesisAmounts != nil {
amount, selfDelegation := chainCfg.ModifyGenesisAmounts(i)
genesisAmounts[i] = []types.Coin{amount}
genesisSelfDelegation[i] = selfDelegation
}
}

genesisAmounts := []types.Coin{genesisAmount}

configFileOverrides := chainCfg.ConfigFileOverrides

eg := new(errgroup.Group)
// Initialize config and sign gentx for each validator.
for _, v := range c.Validators {
for i, v := range c.Validators {
v := v
i := i
v.Validator = true
eg.Go(func() error {
if err := v.InitFullNodeFiles(ctx); err != nil {
Expand All @@ -824,7 +822,7 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene
}
}
if !c.cfg.SkipGenTx {
return v.InitValidatorGenTx(ctx, &chainCfg, genesisAmounts, genesisSelfDelegation)
return v.InitValidatorGenTx(ctx, &chainCfg, genesisAmounts[i], genesisSelfDelegation[i])
}
return nil
})
Expand Down Expand Up @@ -882,7 +880,7 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene
return err
}

if err := validator0.AddGenesisAccount(ctx, bech32, genesisAmounts); err != nil {
if err := validator0.AddGenesisAccount(ctx, bech32, genesisAmounts[0]); err != nil {
return err
}

Expand Down
99 changes: 99 additions & 0 deletions examples/cosmos/chain_genesis_stake_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package cosmos_test

import (
"context"
"encoding/json"
"strconv"
"testing"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/testreporter"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)

func TestChainGenesisUnequalStake(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
t.Parallel()
const (
denom = "uatom"
val1_stake = 1_000_000_000
val2_stake = 2_000_000_000
balance = 1_000_000_000_000
)
validators := 2
cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{
{
Name: "gaia",
ChainName: "gaia",
Version: "v15.1.0",
NumValidators: &validators,
ChainConfig: ibc.ChainConfig{
Denom: denom,
ModifyGenesisAmounts: func(i int) (sdk.Coin, sdk.Coin) {
if i == 0 {
return sdk.NewCoin(denom, sdkmath.NewInt(balance)), sdk.NewCoin(denom, sdkmath.NewInt(val1_stake))
}
return sdk.NewCoin(denom, sdkmath.NewInt(balance)), sdk.NewCoin(denom, sdkmath.NewInt(val2_stake))
},
},
},
})

chains, err := cf.Chains(t.Name())
require.NoError(t, err)

client, network := interchaintest.DockerSetup(t)

chain := chains[0].(*cosmos.CosmosChain)

ic := interchaintest.NewInterchain().
AddChain(chain)
rep := testreporter.NewNopReporter()

err = ic.Build(context.Background(), rep.RelayerExecReporter(t), interchaintest.InterchainBuildOptions{
TestName: t.Name(),
Client: client,
NetworkID: network,
BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(),
SkipPathCreation: false,
})
require.NoError(t, err)
t.Cleanup(func() {
_ = ic.Close()
})

stdout, _, err := chain.GetNode().ExecQuery(context.Background(), "staking", "validators")
require.NoError(t, err)

var validatorsResp map[string]interface{}
require.NoError(t, json.Unmarshal(stdout, &validatorsResp))
require.Contains(t, validatorsResp, "validators")
validatorsList := validatorsResp["validators"].([]interface{})
require.Len(t, validatorsList, 2)

tokens1 := validatorsList[0].(map[string]interface{})["tokens"].(string)
tokens2 := validatorsList[1].(map[string]interface{})["tokens"].(string)
require.NotEmpty(t, tokens1)
require.NotEmpty(t, tokens2)

tokens1Int, err := strconv.Atoi(tokens1)
require.NoError(t, err)
tokens2Int, err := strconv.Atoi(tokens2)
require.NoError(t, err)

if tokens1Int > tokens2Int {
require.Equal(t, val2_stake, tokens1Int)
require.Equal(t, val1_stake, tokens2Int)
} else {
require.Equal(t, val1_stake, tokens1Int)
require.Equal(t, val2_stake, tokens2Int)
}

}
Loading

0 comments on commit 5f41f4b

Please sign in to comment.