Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Testing post halt genesis
  • Loading branch information
agouin committed Apr 6, 2022
commit 3a2a93acdc0de4779a0eca56398f85967916dabd
3 changes: 3 additions & 0 deletions ibc/Chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type Chain interface {
// sets up everything needed (validators, gentx, fullnodes, peering, additional accounts) for chain to start from genesis
Start(testName string, ctx context.Context, additionalGenesisWallets []WalletAmount) error

// start a chain with a provided genesis file. Will override validators for first 2/3 of voting power
StartWithGenesisFile(testName string, ctx context.Context, home string, pool *dockertest.Pool, networkID string, genesisFilePath string) error

// retrieves rpc address that can be reached by other containers in the docker network
GetRPCAddress() string

Expand Down
148 changes: 148 additions & 0 deletions ibc/cosmos_chain.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package ibc

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"math"
"os"
"path"
"sort"
"strconv"
"time"

"github.com/cosmos/cosmos-sdk/types"
authTx "github.com/cosmos/cosmos-sdk/x/auth/tx"
Expand Down Expand Up @@ -181,6 +187,148 @@ func (c *CosmosChain) initializeChainNodes(testName, home string,
c.chainNodes = chainNodes
}

type GenesisValidatorPubKey struct {
Type string `json:"type"`
Value string `json:"value"`
}
type GenesisValidators struct {
Address string `json:"address"`
Name string `json:"name"`
Power string `json:"power"`
PubKey GenesisValidatorPubKey `json:"pub_key"`
}
type GenesisFile struct {
Validators []GenesisValidators `json:"validators"`
}

type ValidatorWithIntPower struct {
Address string
Power int64
PubKeyBase64 string
}

// Bootstraps the chain and starts it from genesis
func (c *CosmosChain) StartWithGenesisFile(testName string, ctx context.Context, home string, pool *dockertest.Pool, networkID string, genesisFilePath string) error {
// copy genesis file to tmp path for modification
genesisTmpFilePath := path.Join(c.getRelayerNode().Dir(), "genesis_tmp.json")
if _, err := copy(genesisFilePath, genesisTmpFilePath); err != nil {
return err
}

genesisJsonBytes, err := ioutil.ReadFile(genesisTmpFilePath)
if err != nil {
return err
}

genesisFile := GenesisFile{}
if err := json.Unmarshal(genesisJsonBytes, &genesisFile); err != nil {
return err
}

genesisValidators := genesisFile.Validators
totalPower := int64(0)

validatorsWithPower := make([]ValidatorWithIntPower, 0)

for _, genesisValidator := range genesisValidators {
power, err := strconv.ParseInt(genesisValidator.Power, 10, 64)
if err != nil {
return err
}
totalPower += power
validatorsWithPower = append(validatorsWithPower, ValidatorWithIntPower{
Address: genesisValidator.Address,
Power: power,
PubKeyBase64: genesisValidator.PubKey.Value,
})
}

sort.Slice(validatorsWithPower, func(i, j int) bool {
return validatorsWithPower[i].Power > validatorsWithPower[j].Power
})

twoThirdsConsensus := int64(math.Ceil(float64(totalPower) * 2 / 3))
totalConsensus := int64(0)

c.chainNodes = []*ChainNode{}

for i, validator := range validatorsWithPower {
tn := &ChainNode{Home: home, Index: i, Chain: c,
Pool: pool, NetworkID: networkID, testName: testName}
tn.MkDir()
c.chainNodes = append(c.chainNodes, tn)

// just need to get pubkey here
// don't care about what goes into this node's genesis file since it will be overwritten with the modified one
if err := tn.InitHomeFolder(ctx); err != nil {
return err
}

testNodePubKeyJsonBytes, err := ioutil.ReadFile(tn.PrivValKeyFilePath())
if err != nil {
return err
}

testNodePrivValFile := PrivValidatorKeyFile{}
if err := json.Unmarshal(testNodePubKeyJsonBytes, &testNodePrivValFile); err != nil {
return err
}

// modify genesis file overwriting validators address with the one generated for this test node
genesisJsonBytes = bytes.Replace(genesisJsonBytes, []byte(validator.Address), []byte(testNodePrivValFile.Address), 5)

// modify genesis file overwriting validators base64 pub_key.value with the one generated for this test node
genesisJsonBytes = bytes.Replace(genesisJsonBytes, []byte(validator.PubKeyBase64), []byte(testNodePrivValFile.PubKey.Value), 5)

totalConsensus += validator.Power

if totalConsensus > twoThirdsConsensus {
break
}
}

for i := 0; i < len(c.chainNodes); i++ {
if err := ioutil.WriteFile(c.chainNodes[i].GenesisFilePath(), genesisJsonBytes, 0644); err != nil { //nolint
return err
}
}

if err := ChainNodes(c.chainNodes).LogGenesisHashes(); err != nil {
return err
}

var eg errgroup.Group

for _, n := range c.chainNodes {
n := n
eg.Go(func() error {
return n.CreateNodeContainer()
})
}
if err := eg.Wait(); err != nil {
return err
}

peers := ChainNodes(c.chainNodes).PeerString()

for _, n := range c.chainNodes {
n.SetValidatorConfigAndPeers(peers)
}

for _, n := range c.chainNodes {
n := n
fmt.Printf("{%s} => starting container...\n", n.Name())
if err := n.StartContainer(ctx); err != nil {
return err
}
time.Sleep(60 * time.Second)
}

// Wait for 5 blocks before considering the chains "started"
_, err = c.getRelayerNode().WaitForBlocks(5)
return err
}

// Bootstraps the chain and starts it from genesis
func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGenesisWallets []WalletAmount) error {
var eg errgroup.Group
Expand Down
26 changes: 26 additions & 0 deletions ibc/test_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,29 @@ func (ibc IBCTestCase) JunoHaltTest(testName string, srcChain Chain, dstChain Ch

return nil
}

func (ibc IBCTestCase) JunoPostHaltGenesis(testName string, srcChain Chain, dstChain Chain, relayerImplementation RelayerImplementation) error {
ctx, home, pool, network, cleanup, err := SetupTestRun(testName)
if err != nil {
return err
}
defer cleanup()

if err := srcChain.Initialize(testName, home, pool, network); err != nil {
return err
}

executablePath, err := os.Executable()
if err != nil {
return err
}
rootPath := filepath.Dir(executablePath)
genesisFilePath := path.Join(rootPath, "assets", "juno-1-96.json")

if err := srcChain.StartWithGenesisFile(testName, ctx, home, pool, network, genesisFilePath); err != nil {
return err
}

_, err = srcChain.WaitForBlocks(20)
return err
}
44 changes: 30 additions & 14 deletions ibc/test_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,21 @@ func (tn *ChainNode) GenesisFilePath() string {
return path.Join(tn.Dir(), "config", "genesis.json")
}

type PrivValidatorKey struct {
Type string `json:"type"`
Value string `json:"value"`
}

type PrivValidatorKeyFile struct {
Address string `json:"address"`
PubKey PrivValidatorKey `json:"pub_key"`
PrivKey PrivValidatorKey `json:"priv_key"`
}

func (tn *ChainNode) PrivValKeyFilePath() string {
return path.Join(tn.Dir(), "config", "priv_validator_key.json")
}

func (tn *ChainNode) TMConfigPath() string {
return path.Join(tn.Dir(), "config", "config.toml")
}
Expand Down Expand Up @@ -546,7 +561,7 @@ func (tn *ChainNode) CreatePool(ctx context.Context, keyName string, contractAdd

func (tn *ChainNode) CreateNodeContainer() error {
chainCfg := tn.Chain.Config()
cmd := []string{chainCfg.Bin, "start", "--home", tn.NodeHome()}
cmd := []string{chainCfg.Bin, "start", "--home", tn.NodeHome(), "--x-crisis-skip-assert-invariants"}
fmt.Printf("{%s} -> '%s'\n", tn.Name(), strings.Join(cmd, " "))

cont, err := tn.Pool.Client.CreateContainer(docker.CreateContainerOptions{
Expand Down Expand Up @@ -603,19 +618,20 @@ func (tn *ChainNode) StartContainer(ctx context.Context) error {
}

time.Sleep(5 * time.Second)
return retry.Do(func() error {
stat, err := tn.Client.Status(ctx)
if err != nil {
// tn.t.Log(err)
return err
}
// TODO: reenable this check, having trouble with it for some reason
if stat != nil && stat.SyncInfo.CatchingUp {
return fmt.Errorf("still catching up: height(%d) catching-up(%t)",
stat.SyncInfo.LatestBlockHeight, stat.SyncInfo.CatchingUp)
}
return nil
}, retry.DelayType(retry.BackOffDelay))
// return retry.Do(func() error {
// stat, err := tn.Client.Status(ctx)
// if err != nil {
// // tn.t.Log(err)
// return err
// }
// // TODO: reenable this check, having trouble with it for some reason
// if stat != nil && stat.SyncInfo.CatchingUp {
// return fmt.Errorf("still catching up: height(%d) catching-up(%t)",
// stat.SyncInfo.LatestBlockHeight, stat.SyncInfo.CatchingUp)
// }
// return nil
// }, retry.DelayType(retry.BackOffDelay))
return nil
}

// InitValidatorFiles creates the node files and signs a genesis transaction
Expand Down