Skip to content

Commit

Permalink
fix(validator set): use comet compatible API for validators set wrt h…
Browse files Browse the repository at this point in the history
…ash (#1159)
  • Loading branch information
danwt authored Oct 22, 2024
1 parent a827c37 commit 57bc89e
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 40 deletions.
5 changes: 1 addition & 4 deletions block/initchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ func (m *Manager) RunInitChain(ctx context.Context) error {
if proposer == nil {
return errors.New("failed to get proposer")
}
tmProposer, err := proposer.TMValidator()
if err != nil {
return err
}
tmProposer := proposer.TMValidator()
res, err := m.Executor.InitChain(m.Genesis, []*tmtypes.Validator{tmProposer})
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion block/sequencers.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (m *Manager) CompleteRotation(ctx context.Context, nextSeqAddr string) erro
if seq == nil {
return types.ErrMissingProposerPubKey
}
copy(nextSeqHash[:], seq.Hash())
copy(nextSeqHash[:], seq.MustHash())
}

err := m.CreateAndPostLastBatch(ctx, nextSeqHash)
Expand Down
2 changes: 1 addition & 1 deletion block/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (e *Executor) UpdateProposerFromBlock(s *types.State, block *types.Block) b
}

localSeq := s.Sequencers.GetByConsAddress(e.localAddress)
if localSeq != nil && bytes.Equal(localSeq.Hash(), block.Header.NextSequencersHash[:]) {
if localSeq != nil && bytes.Equal(localSeq.MustHash(), block.Header.NextSequencersHash[:]) {
return true
}

Expand Down
26 changes: 3 additions & 23 deletions rpc/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,31 +512,11 @@ func (c *Client) Validators(ctx context.Context, heightPtr *int64, pagePtr, perP
if err != nil {
return nil, fmt.Errorf("load validators for height %d: %w", height, err)
}

totalCount := len(sequencers.Sequencers)
perPage := validatePerPage(perPagePtr)
page, err := validatePage(pagePtr, perPage, totalCount)
if err != nil {
return nil, err
}

skipCount := validateSkipCount(page, perPage)

var vals []*tmtypes.Validator
for _, s := range sequencers.Sequencers {
val, err := s.TMValidator()
if err != nil {
return nil, fmt.Errorf("convert sequencer to validator: %s :%w", s.SettlementAddress, err)
}
vals = append(vals, val)
}

v := vals[skipCount : skipCount+tmmath.MinInt(perPage, totalCount-skipCount)]
return &ctypes.ResultValidators{
BlockHeight: int64(height),
Validators: v,
Count: len(v),
Total: totalCount,
Validators: sequencers.Proposer.TMValidators(),
Count: 1,
Total: 1,
}, nil
}

Expand Down
45 changes: 45 additions & 0 deletions rpc/client/client_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client_test

import (
stdbytes "bytes"
"context"
crand "crypto/rand"
"encoding/hex"
Expand Down Expand Up @@ -335,6 +336,50 @@ func TestGetCommit(t *testing.T) {
require.NoError(err)
}

// Ensures the results of the commit and validators queries are consistent wrt. val set hash
func TestValidatorSetHashConsistency(t *testing.T) {
require := require.New(t)
mockApp, rpc, node := getRPCAndNode(t)

mockApp.On("BeginBlock", mock.Anything).Return(abci.ResponseBeginBlock{})
mockApp.On("Commit", mock.Anything).Return(abci.ResponseCommit{})
mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{})

v := tmtypes.NewValidator(ed25519.GenPrivKey().PubKey(), 1)
s := types.NewSequencerFromValidator(*v)
node.BlockManager.State.Sequencers.SetProposer(s)

b := getRandomBlock(1, 10)
copy(b.Header.SequencerHash[:], node.BlockManager.State.Sequencers.ProposerHash())

err := node.Start()
require.NoError(err)

_, err = node.Store.SaveBlock(b, &types.Commit{Height: b.Header.Height}, nil)
node.BlockManager.State.SetHeight(b.Header.Height)
require.NoError(err)

batch := node.Store.NewBatch()
batch, err = node.Store.SaveSequencers(b.Header.Height, &node.BlockManager.State.Sequencers, batch)
require.NoError(err)
err = batch.Commit()
require.NoError(err)

h := int64(b.Header.Height)
commit, err := rpc.Commit(context.Background(), &h)
require.NoError(err)
require.NotNil(commit)

vals, err := rpc.Validators(context.Background(), &h, nil, nil)
require.NoError(err)

valsRes, err := tmtypes.ValidatorSetFromExistingValidators(vals.Validators)
require.NoError(err)
hash := valsRes.Hash()
ok := stdbytes.Equal(commit.ValidatorsHash, hash)
require.True(ok)
}

func TestBlockSearch(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
Expand Down
4 changes: 2 additions & 2 deletions testutil/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func generateBlock(height uint64, proposerHash []byte) *types.Block {
func GenerateBlocksWithTxs(startHeight uint64, num uint64, proposerKey crypto.PrivKey, nTxs int) ([]*types.Block, error) {
r, _ := proposerKey.Raw()
seq := types.NewSequencerFromValidator(*tmtypes.NewValidator(ed25519.PrivKey(r).PubKey(), 1))
proposerHash := seq.Hash()
proposerHash := seq.MustHash()

blocks := make([]*types.Block, num)
for i := uint64(0); i < num; i++ {
Expand Down Expand Up @@ -122,7 +122,7 @@ func GenerateBlocksWithTxs(startHeight uint64, num uint64, proposerKey crypto.Pr
func GenerateBlocks(startHeight uint64, num uint64, proposerKey crypto.PrivKey) ([]*types.Block, error) {
r, _ := proposerKey.Raw()
seq := types.NewSequencerFromValidator(*tmtypes.NewValidator(ed25519.PrivKey(r).PubKey(), 1))
proposerHash := seq.Hash()
proposerHash := seq.MustHash()

blocks := make([]*types.Block, num)
for i := uint64(0); i < num; i++ {
Expand Down
38 changes: 29 additions & 9 deletions types/sequencer_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ func (s Sequencer) IsEmpty() bool {
return s.val.PubKey == nil
}

func (s Sequencer) TMValidator() (*types.Validator, error) {
return &s.val, nil
}

func (s Sequencer) ConsAddress() string {
return s.val.Address.String()
}
Expand All @@ -46,10 +42,34 @@ func (s Sequencer) PubKey() tmcrypto.PubKey {
return s.val.PubKey
}

func (s Sequencer) TMValidator() *types.Validator {
return &s.val
}

func (s Sequencer) TMValidators() []*types.Validator {
return []*types.Validator{s.TMValidator()}
}

func (s Sequencer) TMValset() (*types.ValidatorSet, error) {
return types.ValidatorSetFromExistingValidators(s.TMValidators())
}

// Hash returns tendermint compatible hash of the sequencer
func (s Sequencer) Hash() []byte {
tempProposerSet := types.NewValidatorSet([]*types.Validator{&s.val})
return tempProposerSet.Hash()
func (s Sequencer) Hash() ([]byte, error) {
vs, err := s.TMValset()
if err != nil {
return nil, fmt.Errorf("tm valset: %w", err)
}
return vs.Hash(), nil
}

// MustHash returns tendermint compatible hash of the sequencer
func (s Sequencer) MustHash() []byte {
h, err := s.Hash()
if err != nil {
panic(fmt.Errorf("hash: %w", err))
}
return h
}

// SequencerSet is a set of rollapp sequencers and a proposer.
Expand All @@ -75,15 +95,15 @@ func (s *SequencerSet) ProposerHash() []byte {
if s.Proposer == nil {
return make([]byte, 0, 32)
}
return s.Proposer.Hash()
return s.Proposer.MustHash()
}

// SetProposerByHash sets the proposer by hash.
// It returns an error if the hash is not found in the sequencer set
// Used when updating proposer from the L2 blocks (nextSequencerHash header field)
func (s *SequencerSet) SetProposerByHash(hash []byte) error {
for _, seq := range s.Sequencers {
if bytes.Equal(seq.Hash(), hash) {
if bytes.Equal(seq.MustHash(), hash) {
s.SetProposer(&seq)
return nil
}
Expand Down

0 comments on commit 57bc89e

Please sign in to comment.