Skip to content

Commit

Permalink
Merge pull request #13 from bcdevtools/fix/fix-val-oper-addr-in-for-r…
Browse files Browse the repository at this point in the history
…ollapp-evm

fix(rpc): fix validator operator address not mapped in RollApp EVM
  • Loading branch information
0xbcdev authored May 3, 2024
2 parents 4a0044c + a17e3db commit 5bc5cbc
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 91 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ Templates for Unreleased:

## Unreleased

## v1.1.4 - 2024-05-03

### Bug Fixes

- (rpc) [#13](https://github.com/bcdevtools/block-explorer-rpc-cosmos/pull/13) Fix validators not listed correctly

## v1.1.3 - 2024-05-03

### Bug Fixes
Expand Down
19 changes: 16 additions & 3 deletions be_rpc/backend/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,24 @@ func (m *Backend) GetValidatorAccount(consOrValAddr string) (berpctypes.GenericB
res = res.ReInitializeIfNil()
}

valAddr, consAddr, found, err := m.validatorsConsAddrToValAddr.GetValAddrAndConsAddr(consOrValAddr)
stakingValidators, err := m.stakingValidatorsCache.GetValidators()
if err != nil {
return nil, err
return nil, status.Error(codes.Internal, errors.Wrap(err, "failed to get staking validators").Error())
}
if len(stakingValidators) < 1 {
return nil, status.Error(codes.NotFound, "validator could not be found")
}

var valAddr, consAddr string
for _, validator := range stakingValidators {
if validator.consAddr == consOrValAddr || validator.validator.OperatorAddress == consOrValAddr {
valAddr = validator.validator.OperatorAddress
consAddr = validator.consAddr
break
}
}
if !found {

if valAddr == "" || consAddr == "" {
return nil, status.Error(codes.NotFound, "validator could not be found")
}

Expand Down
8 changes: 4 additions & 4 deletions be_rpc/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ type Backend struct {
externalServices berpctypes.ExternalServices

// cache
bech32Cfg berpctypes.Bech32Config
tendermintValidatorsCache *tendermintValidatorsCache
validatorsConsAddrToValAddr *validatorsConsAddrToValAddr
bech32Cfg berpctypes.Bech32Config
tendermintValidatorsCache *tendermintValidatorsCache
stakingValidatorsCache *stakingValidatorsCache
}

// NewBackend creates a new Backend instance for RollApp Block Explorer
Expand Down Expand Up @@ -124,7 +124,7 @@ func NewBackend(
tendermintValidatorsCache: NewTendermintValidatorsCache(
clientCtx.Client,
),
validatorsConsAddrToValAddr: NewValidatorsConsAddrToValAddrCache(
stakingValidatorsCache: NewStakingValidatorsCache(
clientCtx.Client,
queryClient.StakingQueryClient,
clientCtx.Codec,
Expand Down
103 changes: 31 additions & 72 deletions be_rpc/backend/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (vc *tendermintValidatorsCache) GetValidators() (vals []*tmtypes.Validator,
}

if !isExpired {
return vc.validators, nil
return vc.validators[:], nil
}

vc.cacheController.rwMutex.Lock()
Expand All @@ -74,7 +74,7 @@ func (vc *tendermintValidatorsCache) GetValidators() (vals []*tmtypes.Validator,
return
}
if !isExpired { // prevent race condition by re-checking after acquiring the lock
return vc.validators, nil
return vc.validators[:], nil
}

errReloadCache := vc.reloadCacheWithoutLock(height)
Expand All @@ -83,7 +83,7 @@ func (vc *tendermintValidatorsCache) GetValidators() (vals []*tmtypes.Validator,
return
}

return vc.validators, nil
return vc.validators[:], nil
}

func (vc *tendermintValidatorsCache) IsCacheExpired() (expired bool, err error) {
Expand Down Expand Up @@ -123,82 +123,40 @@ func (vc *tendermintValidatorsCache) reloadCacheWithoutLock(height int64) error
return nil
}

type validatorsConsAddrToValAddr struct {
cacheController *baseCacheController
validatorsConsAddrToValAddr map[string]string
tmClient client.Client
stakingQueryClient stakingtypes.QueryClient
codec codec.Codec
type stakingValidatorsCache struct {
cacheController *baseCacheController
validators []cachedValidator
tmClient client.Client
stakingQueryClient stakingtypes.QueryClient
codec codec.Codec
}

func NewValidatorsConsAddrToValAddrCache(tmClient client.Client, stakingQueryClient stakingtypes.QueryClient, codec codec.Codec) *validatorsConsAddrToValAddr {
funcIsExpired := func(expirationAnchor, valueToCompare any) bool {
return valueToCompare.(int64) > expirationAnchor.(int64)
}
return &validatorsConsAddrToValAddr{
cacheController: NewBaseCacheController(funcIsExpired),
validatorsConsAddrToValAddr: make(map[string]string),
tmClient: tmClient,
stakingQueryClient: stakingQueryClient,
codec: codec,
}
type cachedValidator struct {
consAddr string
validator stakingtypes.Validator
}

func (vc *validatorsConsAddrToValAddr) GetValAddrFromConsAddr(consAddr string) (valAddr string, found bool, err error) {
isExpired, errCheckExpired := vc.IsCacheExpired()
if errCheckExpired != nil {
err = errCheckExpired
return
}

if !isExpired {
valAddr, found = vc.validatorsConsAddrToValAddr[consAddr]
return
}

vc.cacheController.rwMutex.Lock()
defer vc.cacheController.rwMutex.Unlock()

isExpired, height, errCheckExpired := vc.isCacheExpired(false)
if errCheckExpired != nil {
err = errCheckExpired
return
}
if !isExpired { // prevent race condition by re-checking after acquiring the lock
valAddr, found = vc.validatorsConsAddrToValAddr[consAddr]
return
func NewStakingValidatorsCache(tmClient client.Client, stakingQueryClient stakingtypes.QueryClient, codec codec.Codec) *stakingValidatorsCache {
funcIsExpired := func(expirationAnchor, valueToCompare any) bool {
return valueToCompare.(int64) > expirationAnchor.(int64)
}

errReloadCache := vc.reloadCacheWithoutLock(height)
if errReloadCache != nil {
err = errReloadCache
return
return &stakingValidatorsCache{
cacheController: NewBaseCacheController(funcIsExpired),
tmClient: tmClient,
stakingQueryClient: stakingQueryClient,
codec: codec,
}

valAddr, found = vc.validatorsConsAddrToValAddr[consAddr]
return
}

func (vc *validatorsConsAddrToValAddr) GetValAddrAndConsAddr(consOrValAddr string) (valAddr, consAddr string, found bool, err error) {
func (vc *stakingValidatorsCache) GetValidators() (vals []cachedValidator, err error) {
isExpired, errCheckExpired := vc.IsCacheExpired()
if errCheckExpired != nil {
err = errCheckExpired
return
}

lookupUnexpiredData := func() (valAddr, consAddr string, found bool) {
for consAddr, valAddr := range vc.validatorsConsAddrToValAddr {
if consAddr == consOrValAddr || valAddr == consOrValAddr {
return valAddr, consAddr, true
}
}

return "", "", false
}

if !isExpired {
valAddr, consAddr, found = lookupUnexpiredData()
return
return vc.validators[:], nil
}

vc.cacheController.rwMutex.Lock()
Expand All @@ -210,8 +168,7 @@ func (vc *validatorsConsAddrToValAddr) GetValAddrAndConsAddr(consOrValAddr strin
return
}
if !isExpired { // prevent race condition by re-checking after acquiring the lock
valAddr, consAddr, found = lookupUnexpiredData()
return
return vc.validators[:], nil
}

errReloadCache := vc.reloadCacheWithoutLock(height)
Expand All @@ -220,16 +177,15 @@ func (vc *validatorsConsAddrToValAddr) GetValAddrAndConsAddr(consOrValAddr strin
return
}

valAddr, consAddr, found = lookupUnexpiredData()
return
return vc.validators[:], nil
}

func (vc *validatorsConsAddrToValAddr) IsCacheExpired() (expired bool, err error) {
func (vc *stakingValidatorsCache) IsCacheExpired() (expired bool, err error) {
expired, _, err = vc.isCacheExpired(true)
return
}

func (vc *validatorsConsAddrToValAddr) isCacheExpired(lock bool) (expired bool, latestHeight int64, err error) {
func (vc *stakingValidatorsCache) isCacheExpired(lock bool) (expired bool, latestHeight int64, err error) {
resStatus, err := vc.tmClient.Status(context.Background())
if err != nil {
return false, 0, err
Expand All @@ -246,7 +202,7 @@ func (vc *validatorsConsAddrToValAddr) isCacheExpired(lock bool) (expired bool,
}

// reloadCacheWithoutLock performs reload cache. Lock acquire must be performed before calling this.
func (vc *validatorsConsAddrToValAddr) reloadCacheWithoutLock(height int64) error {
func (vc *stakingValidatorsCache) reloadCacheWithoutLock(height int64) error {
var perPage = 200

stakingVals, errStakingVals := vc.stakingQueryClient.Validators(context.Background(), &stakingtypes.QueryValidatorsRequest{
Expand All @@ -266,7 +222,10 @@ func (vc *validatorsConsAddrToValAddr) reloadCacheWithoutLock(height int64) erro
}

consAddrStr := consAddr.String()
vc.validatorsConsAddrToValAddr[consAddrStr] = val.OperatorAddress
vc.validators = append(vc.validators, cachedValidator{
consAddr: consAddrStr,
validator: val,
})
}

vc.cacheController.UpdateExpirationAnchor(height + validatorsCacheExpiration)
Expand Down
38 changes: 26 additions & 12 deletions be_rpc/backend/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,38 @@ func (m *Backend) GetStakingInfo(delegatorAddr string) (berpctypes.GenericBacken
}

func (m *Backend) GetValidators() (berpctypes.GenericBackendResponse, error) {
validators, err := m.tendermintValidatorsCache.GetValidators()
tmValidators, err := m.tendermintValidatorsCache.GetValidators()
if err != nil {
return nil, status.Error(codes.Internal, errors.Wrap(err, "failed to get validators").Error())
return nil, status.Error(codes.Internal, errors.Wrap(err, "failed to get tendermint validators").Error())
}

stakingValidators, err := m.stakingValidatorsCache.GetValidators()
if err != nil {
return nil, status.Error(codes.Internal, errors.Wrap(err, "failed to get staking validators").Error())
}

res := make(berpctypes.GenericBackendResponse)
for _, validator := range validators {
consAddr := sdk.ConsAddress(validator.Address).String()
valAddr, _, err := m.validatorsConsAddrToValAddr.GetValAddrFromConsAddr(consAddr)
if err != nil {
return nil, status.Error(codes.Internal, errors.Wrap(err, "failed to get valiator address from consensus address").Error())
}
res[consAddr] = map[string]any{

for _, stakingValidator := range stakingValidators {
consAddr := stakingValidator.consAddr
valInfo := map[string]any{
"consAddress": consAddr,
"valAddress": valAddr,
"pubKeyType": validator.PubKey.Type(),
"votingPower": validator.VotingPower,
"valAddress": stakingValidator.validator.OperatorAddress,
"pubKeyType": "",
"votingPower": -1,
}

for _, tmValidator := range tmValidators {
if sdk.ConsAddress(tmValidator.Address).String() != consAddr {
continue
}

valInfo["pubKeyType"] = tmValidator.PubKey.Type()
valInfo["votingPower"] = tmValidator.VotingPower
break
}

res[consAddr] = valInfo
}

return res, nil
Expand Down

0 comments on commit 5bc5cbc

Please sign in to comment.