Skip to content

Commit

Permalink
Improve integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
KonradStaniec committed Sep 24, 2022
1 parent c48a6b3 commit 871117c
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 124 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- run: # sudo is needed, so that integration test binary have proper access to nodes keyring
name: Run integration tests
command: |
make localnet-start
make localnet-start-test
sudo -E env "PATH=$PATH" make test-babylon-integration
make localnet-stop
Expand Down
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -443,16 +443,28 @@ localnet-build-env:
localnet-build-dlv:
$(MAKE) -C contrib/images babylond-dlv

localnet-build-nodes-test:
$(DOCKER) run --rm -v $(CURDIR)/.testnets:/data babylonchain/babylond \
testnet init-files --v 4 -o /data \
--starting-ip-address 192.168.10.2 --keyring-backend=test \
--chain-id chain-test --btc-confirmation-depth 2 --additional-sender-account true \
--epoch-interval 5
docker-compose up -d

localnet-build-nodes:
$(DOCKER) run --rm -v $(CURDIR)/.testnets:/data babylonchain/babylond \
testnet init-files --v 4 -o /data \
--starting-ip-address 192.168.10.2 --keyring-backend=test \
--chain-id chain-test --btc-confirmation-depth 2
--chain-id chain-test
docker-compose up -d

# localnet-start will run a testnet with 4 nodes, a bitcoin instance, and a vigilante instance
# localnet-start will run a with 4 nodes with 4 nodes, a bitcoin instance, and a vigilante instance
localnet-start: localnet-stop localnet-build-env localnet-build-nodes

# localnet-start-test will start with 4 nodes with test confiuration and low
# epoch interval
localnet-start-test: localnet-stop localnet-build-env localnet-build-nodes-test

# localnet-debug will run a 4-node testnet locally in debug mode
# you can read more about the debug mode here: ./contrib/images/babylond-dlv/README.md
localnet-debug: localnet-stop localnet-build-dlv localnet-build-nodes
Expand Down
65 changes: 51 additions & 14 deletions cmd/babylond/cmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,20 @@ import (
)

var (
flagNodeDirPrefix = "node-dir-prefix"
flagNumValidators = "v"
flagOutputDir = "output-dir"
flagNodeDaemonHome = "node-daemon-home"
flagStartingIPAddress = "starting-ip-address"
flagBtcNetwork = "btc-network"
flagBtcCheckpointTag = "btc-checkpoint-tag"
flagBtcConfirmationDepth = "btc-confirmation-depth"
flagBtcFinalizationTimeout = "btc-finalization-timeout"
flagEpochInterval = "epoch-interval"
flagBaseBtcHeaderHex = "btc-base-header"
flagBaseBtcHeaderHeight = "btc-base-header-height"
flagMaxActiveValidators = "max-active-validators"
flagNodeDirPrefix = "node-dir-prefix"
flagNumValidators = "v"
flagOutputDir = "output-dir"
flagNodeDaemonHome = "node-daemon-home"
flagStartingIPAddress = "starting-ip-address"
flagBtcNetwork = "btc-network"
flagBtcCheckpointTag = "btc-checkpoint-tag"
flagBtcConfirmationDepth = "btc-confirmation-depth"
flagBtcFinalizationTimeout = "btc-finalization-timeout"
flagEpochInterval = "epoch-interval"
flagBaseBtcHeaderHex = "btc-base-header"
flagBaseBtcHeaderHeight = "btc-base-header-height"
flagMaxActiveValidators = "max-active-validators"
flagAdditionalSenderAccount = "additional-sender-account"
)

// get cmd to initialize all files for tendermint testnet and application
Expand Down Expand Up @@ -108,6 +109,7 @@ Example:
// btclightclient args
baseBtcHeaderHex, _ := cmd.Flags().GetString(flagBaseBtcHeaderHex)
baseBtcHeaderHeight, err := cmd.Flags().GetUint64(flagBaseBtcHeaderHeight)
additionalAccount, _ := cmd.Flags().GetBool(flagAdditionalSenderAccount)
if err != nil {
return errors.New("base Bitcoin header height should be a uint64")
}
Expand All @@ -116,7 +118,7 @@ Example:
clientCtx, cmd, config, mbm, genBalIterator, outputDir, chainID, minGasPrices,
nodeDirPrefix, nodeDaemonHome, startingIPAddress, keyringBackend, algo, numValidators,
maxActiveValidators, btcNetwork, btcCheckpointTag, btcConfirmationDepth, btcFinalizationTimeout,
epochInterval, baseBtcHeaderHex, baseBtcHeaderHeight,
epochInterval, baseBtcHeaderHex, baseBtcHeaderHeight, additionalAccount,
)
},
}
Expand All @@ -142,6 +144,7 @@ Example:
cmd.Flags().String(flagBaseBtcHeaderHex, "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a45068653ffff7f2002000000", "Hex of the base Bitcoin header.")
cmd.Flags().Uint64(flagBaseBtcHeaderHeight, 0, "Height of the base Bitcoin header.")
cmd.Flags().Uint32(flagMaxActiveValidators, 10, "Maximum number of validators.")
cmd.Flags().Bool(flagAdditionalSenderAccount, false, "If there should be additional pre funded account per validator")

return cmd
}
Expand Down Expand Up @@ -172,6 +175,7 @@ func InitTestnet(
epochInterval uint64,
baseBtcHeaderHex string,
baseBtcHeaderHeight uint64,
additionalAccount bool,
) error {

if chainID == "" {
Expand Down Expand Up @@ -234,6 +238,7 @@ func InitTestnet(

// generate account key
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf)

if err != nil {
return err
}
Expand Down Expand Up @@ -344,6 +349,38 @@ func InitTestnet(
}
}

if additionalAccount {
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)

// generate account key
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf)

if err != nil {
return err
}
keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos)
if err != nil {
return err
}
addr, _, err := testutil.GenerateSaveCoinKey(kb, "test-spending-key", "", true, algo)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}

coins := sdk.Coins{
sdk.NewCoin("testtoken", sdk.NewInt(1000000000)),
sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(500000000)),
}

genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
}
}

if err := initGenFiles(clientCtx, mbm, chainID, genAccounts, genBalances, genFiles,
genKeys, numValidators, maxActiveValidators, btcConfirmationDepth, btcFinalizationTimeout,
epochInterval, baseBtcHeaderHex, baseBtcHeaderHeight); err != nil {
Expand Down
128 changes: 32 additions & 96 deletions test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,26 @@ func waitForBlock(clients []*grpc.ClientConn, blockNumber int64) {
return
}

<-time.After(2 * time.Second)
<-time.After(1 * time.Second)
}
}

func getCurrentEpoch(conn *grpc.ClientConn) uint64 {
epochingClient := epochingtypes.NewQueryClient(conn)

currentEpochResponse, err := epochingClient.CurrentEpoch(
context.Background(),
&epochingtypes.QueryCurrentEpochRequest{},
)

if err != nil {
errorString := fmt.Sprintf("Query failed, testnet not running. Error: %v", err)
panic(errorString)
}

return currentEpochResponse.CurrentEpoch
}

func TestMain(m *testing.M) {

// This is needed so that all address prefixes are in Babylon format
Expand Down Expand Up @@ -154,62 +170,29 @@ func TestBtcLightClientGenesis(t *testing.T) {
}

func TestNodeProgress(t *testing.T) {

// most probably nodes are after block 1 at this point, but to make sure we are waiting
// for block 1
// blocks 1-10 are epoch 1 blocks.
// blocks 1-5 are epoch 1 blocks.
waitForBlock(clients, 1)

for _, c := range clients {
epochingClient := epochingtypes.NewQueryClient(c)

currentEpochResponse, err := epochingClient.CurrentEpoch(
context.Background(),
&epochingtypes.QueryCurrentEpochRequest{},
)

if err != nil {
errorString := fmt.Sprintf("Query failed, testnet not running. Error: %v", err)
panic(errorString)
}

if currentEpochResponse.CurrentEpoch != 1 {
t.Fatalf("Initial epoch should equal 1. Current epoch %d", currentEpochResponse.CurrentEpoch)
currentEpoch := getCurrentEpoch(c)
if currentEpoch != 1 {
t.Fatalf("Initial epoch should equal 1. Current epoch %d", currentEpoch)
}
}

// TODO default epoch interval is equal to 10, we should retrieve it from config
// block 11 is first block of epoch 2, so if all clients are after block 12, they
// should be at epoch 2
waitForBlock(clients, 12)
waitForBlock(clients, 7)

for _, c := range clients {
epochingClient := epochingtypes.NewQueryClient(c)

currentEpochResponse, err := epochingClient.CurrentEpoch(
context.Background(),
&epochingtypes.QueryCurrentEpochRequest{},
)

if err != nil {
errorString := fmt.Sprintf("Query failed, testnet not running. Error: %v", err)
panic(errorString)
}

if currentEpochResponse.CurrentEpoch != 2 {
t.Errorf("Epoch after 10 blocks, should equal 2. Curent epoch %d", currentEpochResponse.CurrentEpoch)
currentEpoch := getCurrentEpoch(c)
if currentEpoch != 2 {
t.Errorf("Epoch after 3 blocks, should equal 2. Curent epoch %d", currentEpoch)
}
}
}

func TestSendTx(t *testing.T) {
// we are waiting for middle of the epoch to avoid race condidions with bls
// signer sending transaction and incrementing account sequence numbers
// which may cause header tx to fail.
// TODO: Create separate account for sending transactions to avoid race
// conditions with validator acounts.
waitForBlock(clients, 14)

// TODO fix hard coded paths
node0dataPath := "../.testnets/node0/babylond"
node0genesisPath := "../.testnets/node0/babylond/config/genesis.json"
Expand Down Expand Up @@ -311,30 +294,12 @@ func TestSubmitCheckpoint(t *testing.T) {
secondSubmission := datagen.CreateBlockWithTransaction(firstSubmission.HeaderBytes.ToBlockHeader(), p2)

// first insert all headers
hresp1, err := sender.insertNewHeader(firstSubmission.HeaderBytes)

if err != nil {
t.Fatalf("Could not insert first header")
}

_, err = WaitBtcForHeight(clients[0], currentTip.Height+1)

if err != nil {
t.Log(hresp1.TxResponse)
t.Fatalf("failed waiting for btc lightclient block")
}

hresp2, err := sender.insertNewHeader(secondSubmission.HeaderBytes)
err = sender.insertBTCHeaders(
[]bbn.BTCHeaderBytes{firstSubmission.HeaderBytes, secondSubmission.HeaderBytes},
)

if err != nil {
t.Fatalf("Could not insert second header")
}

_, err = WaitBtcForHeight(clients[0], currentTip.Height+2)

if err != nil {
t.Log(hresp2.TxResponse)
t.Fatalf("failed waiting for btc lightclient block")
t.Fatalf("Could not insert two headers. Err: %s", err)
}

// At this point light client chain should be 3 long and inserting spv proofs
Expand Down Expand Up @@ -373,40 +338,11 @@ func TestConfirmCheckpoint(t *testing.T) {
panic("failed to init sender")
}

currentTip, err := sender.getBtcTip()

if err != nil {
t.Fatalf("Could not retrieve btc tip")
}

h1 := generateEmptyChildHeaderBytes(currentTip.Header.ToBlockHeader())
h2 := generateEmptyChildHeaderBytes(h1.ToBlockHeader())

// first insert 2 new headers,
hresp1, err := sender.insertNewHeader(h1)

if err != nil {
t.Fatalf("Could not insert first header")
}

_, err = WaitBtcForHeight(clients[0], currentTip.Height+1)
// insert two empty btc headers
err = sender.insertBTCHeaders([]bbn.BTCHeaderBytes{nil, nil})

if err != nil {
t.Log(hresp1.TxResponse)
t.Fatalf("failed waiting for btc lightclient block")
}

hresp2, err := sender.insertNewHeader(h2)

if err != nil {
t.Fatalf("Could not insert second header")
}

_, err = WaitBtcForHeight(clients[0], currentTip.Height+2)

if err != nil {
t.Log(hresp2.TxResponse)
t.Fatalf("failed waiting for btc lightclient block")
t.Fatalf("Could not insert two headers. Err: %s", err)
}

// Btc light client chain has been extended by 2 blocks, it means that our checkpoint
Expand Down
Loading

0 comments on commit 871117c

Please sign in to comment.