Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Enable multiple validators and valset update #918

Closed
3 of 4 tasks
sainoe opened this issue Feb 15, 2022 · 5 comments
Closed
3 of 4 tasks

Feat: Enable multiple validators and valset update #918

sainoe opened this issue Feb 15, 2022 · 5 comments
Labels
testing Testing package and unit/integration tests type: feature New features, sub-features or integrations

Comments

@sainoe
Copy link

sainoe commented Feb 15, 2022

Feat: Enable multiple validators and valset update

In the context of testing validators slashing between connected chains, it may be required
to have more than one validator running per chain. This issue describes the problems faced by
trying to change the TestChain setup accordingly and by executing operations changing validators voting power
against a chain.

A WIP solution is available in this branch. This list shows what has been developed so far:

  • Run a TestChain with more than one genesis accounts
  • Run a TestChain with more than one validators
  • Run multiple validators with same voting power
  • Update validator set of TestChains

Bonded pool balance and genesis supply

SetupWithGenesisValSet creates validators balances using the validator set and genesis accounts.
The validators are bonded with a delegation of 10^6 default token of the first genesis account.
Passing either more than on validators or genesis accounts panics with the following error mmessages:

func TestIssueA(t *testing.T) {
	privVal := mock.NewPV()
	pubKey, err := privVal.GetPubKey()
	require.NoError(t, err)

	// create validator set with single validator
	validator := tmtypes.NewValidator(pubKey, 1)
	valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})

	// generate two genesis accounts
	privKey1 := secp256k1.GenPrivKey()
	acc1 := authtypes.NewBaseAccount(privKey1.PubKey().Address().Bytes(), privKey1.PubKey(), 0, 0)
	balance1 := banktypes.Balance{
		Address: acc1.GetAddress().String(),
		Coins:   sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
	}

	privKey2 := secp256k1.GenPrivKey()
	acc2 := authtypes.NewBaseAccount(privKey2.PubKey().Address().Bytes(), privKey2.PubKey(), 0, 0)
	balance2 := banktypes.Balance{
		Address: acc2.GetAddress().String(),
		Coins:   sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
	}

	SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc1, acc2}, balance1, balance2)
}

$ panic: bonded pool balance is different from bonded coins: 1000000stake <-> 2000000stake
func TestIssueB(t *testing.T) {
	privVal1 := mock.NewPV()
	pubKey1, err := privVal1.GetPubKey()
	if err != nil {
		t.Error(err)
	}

	privVal2 := mock.NewPV()
	pubKey2, err := privVal2.GetPubKey()
	if err != nil {
		t.Error(err)
	}

	// create validator set with two validators
	validator1 := tmtypes.NewValidator(pubKey1, 1)
	validator2 := tmtypes.NewValidator(pubKey2, 1)
	valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator1, validator2})

	// generate genesis account
	senderPrivKey := secp256k1.GenPrivKey()
	acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
	balance := banktypes.Balance{
		Address: acc.GetAddress().String(),
		Coins:   sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
	}

	ibctesting.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance)
}

$ panic: genesis supply is incorrect, expected 200000002000000stake, got 200000001000000stake```

Validators with equal voting power

By setting two validators with equal voting power we get the following error:

vote.ValidatorAddress (99E79C17A14F3A5B552240FFC25D60664FDF9061) does not match address (43E1112B1ACA8CF46013E0AD7C28C528A38EF69D) for vote.ValidatorIndex (0) Ensure the genesis file is correct across all validators: invalid validator address Test:           TestParentTestSuite/TestNewTestChainSetup

The error message indicates that the validator addresses and their respective signing key get mixed up. This side effect comes from the validator sets constructor operations. CompareProposerPriority method returns validators ordered by voting powers or and by address lexical order when equal.

func (v *Validator) CompareProposerPriority(other *Validator) *Validator {
	if v == nil {
		return other
	}
	switch {
	case v.ProposerPriority > other.ProposerPriority:
		return v
	case v.ProposerPriority < other.ProposerPriority:
		return other
	default:
		result := bytes.Compare(v.Address, other.Address)
		switch {
		case result < 0:
			return v
		case result > 0:
			return other
		default:
			panic("Cannot compare identical validators")
		}
	}
}

Validator set update

After testing slashing or delegation against a TestChain, we can observe that its validator set values remain unchanged. This discrepancy with the validator states in the staking module makes IBC panics. In checkTrustedHeader The header validator hash field and the trusted validators hash differs and throws the following error.

failed to execute message; message index: 0: cannot update client with ID 07-tendermint-0: trusted validators validators:<address:"k\335\321\2726\030l\337\252\n\036\215\007\271\265K\217H\311\022" pub_key:<ed25519:"\022J\251\177\212\276\3017\372\222/p\205U\344\335\002\342\376e\266\225\252\001\262\364B\242\312\2119Z" > voting_power:2 > proposer:<address:"k\335\321\2726\030l\337\252\n\036\215\007\271\265K\217H\311\022" pub_key:<ed25519:"\022J\251\177\212\276\3017\372\222/p\205U\344\335\002\342\376e\266\225\252\001\262\364B\242\312\2119Z" > voting_power:2 > , does not hash to latest trusted validators. Expected: D552D2C59A8A61A1AD5306B156C476D06402684C117DD1374F53AE5CC47E8252, got: 260205B437210256D4AE663A5C88530074EC429EA9E405A0E876ADCDF45D5EC7: invalid validator set

This gist is available to reproduce most of the errors.

@sainoe sainoe changed the title ##Feat: Enable multiple validators and valset update Feat: Enable multiple validators and valset update Feb 15, 2022
@crodriguezvega
Copy link
Contributor

Thanks for opening this issue, @sainoe. Since you have a WiP solution to fix these problems, will you open a PR once it is ready to review or do you need any help from us in the meantime?

@crodriguezvega crodriguezvega added type: feature New features, sub-features or integrations testing Testing package and unit/integration tests labels Feb 15, 2022
@sainoe
Copy link
Author

sainoe commented Feb 17, 2022

A PR is on the way @crodriguezvega, thanks for asking!
The valset update issue still needs an elegant solution.

In the meantime, an easy fix is available here.

sainoe added a commit to sainoe/ibc-go that referenced this issue Feb 17, 2022
* Patch cosmos#918:
  - [x] Run a TestChain with more than one genesis accounts
  - [x] Run a TestChain with more than one validators
  - [x] Run multiple validators with same voting power
  - [ ] Update validator set of TestChains (elegant solution is still WIP)

* Easy fix for the valset update is available in the issue
sainoe added a commit to sainoe/ibc-go that referenced this issue Feb 18, 2022
* Patch cosmos#918:
  - [x] Run a TestChain with more than one genesis accounts
  - [x] Run a TestChain with more than one validators
  - [x] Run multiple validators with same voting power
  - [ ] Update validator set of TestChains (elegant solution is still WIP)

* Easy fix for the valset update is available in the issue
sainoe added a commit to sainoe/interchain-security that referenced this issue Feb 21, 2022
- Use reverse iterator to get last VSCId: [comment-ref](https://github.com)

- Implement Producer chain slashing packet acknowledgement: [comment-ref](cosmos#28 (comment))

- Make unit-tests pass using custom [IBC-GO branch](https://github.com/sainoe/ibc-go/tree/sainoe/valset-update-fixes) with [cosmos#28](cosmos/ibc-go#918 (comment)) fixes
@colin-axner
Copy link
Contributor

I believe this issue has been addressed? The testing pkg has a Vals and NextVals field which should allow for multiple validators and updates to the validator sets

looks like #942 and #1003 solved this issue?

@crodriguezvega
Copy link
Contributor

@sainoe Considering @colin-axner's comment above, do you think this issue is solved now and can be closed?

@sainoe
Copy link
Author

sainoe commented Sep 23, 2023

@crodriguezvega Yes I do. Thanks for asking!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
testing Testing package and unit/integration tests type: feature New features, sub-features or integrations
Projects
None yet
Development

No branches or pull requests

3 participants