diff --git a/pkg/innerring/indexer.go b/pkg/innerring/indexer.go index c42ab309..05fc108d 100644 --- a/pkg/innerring/indexer.go +++ b/pkg/innerring/indexer.go @@ -18,6 +18,7 @@ type innerRingIndexer struct { timeout time.Duration innerRingIndex, innerRingSize int32 + alphabetIndex int32 lastAccess time.Time } @@ -52,6 +53,11 @@ func (s *innerRingIndexer) update() (err error) { return err } + s.alphabetIndex, err = invoke.AlphabetIndex(s.cli, s.key) + if err != nil { + return err + } + s.lastAccess = time.Now() return nil @@ -78,3 +84,14 @@ func (s *innerRingIndexer) InnerRingSize() (int32, error) { return s.innerRingSize, nil } + +func (s *innerRingIndexer) AlphabetIndex() (int32, error) { + if err := s.update(); err != nil { + return 0, errors.Wrap(err, "can't update index state") + } + + s.RLock() + defer s.RUnlock() + + return s.alphabetIndex, nil +} diff --git a/pkg/innerring/invoke/chain.go b/pkg/innerring/invoke/chain.go index dd794f60..ba52e0d1 100644 --- a/pkg/innerring/invoke/chain.go +++ b/pkg/innerring/invoke/chain.go @@ -25,6 +25,21 @@ func InnerRingIndex(cli *client.Client, key *ecdsa.PublicKey) (int32, int32, err return keyPosition(key, innerRing), int32(len(innerRing)), nil } +// AlphabetIndex returns index of the `key` in the alphabet key list from sidechain +// If key is not in the inner ring list, then returns `-1` as index. +func AlphabetIndex(cli *client.Client, key *ecdsa.PublicKey) (int32, error) { + if cli == nil { + return 0, client.ErrNilClient + } + + alphabet, err := cli.Committee() + if err != nil { + return 0, err + } + + return keyPosition(key, alphabet), nil +} + // keyPosition returns "-1" if key is not found in the list, otherwise returns // index of the key. func keyPosition(key *ecdsa.PublicKey, list keys.PublicKeys) (result int32) { diff --git a/pkg/innerring/state.go b/pkg/innerring/state.go index b0722c1e..1a7a3a49 100644 --- a/pkg/innerring/state.go +++ b/pkg/innerring/state.go @@ -24,6 +24,11 @@ func (s *Server) IsActive() bool { return s.InnerRingIndex() >= 0 } +// IsAlphabet is a getter for a global alphabet flag state. +func (s *Server) IsAlphabet() bool { + return s.AlphabetIndex() >= 0 +} + // InnerRingIndex is a getter for a global index of node in inner ring list. Negative // index means that node is not in the inner ring list. func (s *Server) InnerRingIndex() int { @@ -48,6 +53,18 @@ func (s *Server) InnerRingSize() int { return int(size) } +// AlphabetIndex is a getter for a global index of node in alphabet list. +// Negative index means that node is not in the alphabet list. +func (s *Server) AlphabetIndex() int { + index, err := s.statusIndex.AlphabetIndex() + if err != nil { + s.log.Error("can't get alphabet index", zap.String("error", err.Error())) + return -1 + } + + return int(index) +} + func (s *Server) voteForSidechainValidator(validators []keys.PublicKey) error { index := s.InnerRingIndex() if s.contracts.alphabet.indexOutOfRange(index) {