Merge pull request #2200 from cosmos/dev/GetValidator_speed_improvement
Improve GetValidator speed
This commit is contained in:
commit
a4f36aa874
@ -80,7 +80,7 @@ IMPROVEMENTS
|
||||
* [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check.
|
||||
* [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046)
|
||||
* [x/stake] [x/slashing] Ensure delegation invariants to jailed validators [#1883](https://github.com/cosmos/cosmos-sdk/issues/1883).
|
||||
|
||||
* [x/stake] Improve speed of GetValidator, which was shown to be a performance bottleneck. [#2046](https://github.com/tendermint/tendermint/pull/2200)
|
||||
* SDK
|
||||
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
|
||||
* [cli] \#1632 Add integration tests to ensure `basecoind init && basecoind` start sequences run successfully for both `democoin` and `basecoin` examples.
|
||||
|
||||
@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
@ -11,6 +12,19 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
// Cache the amino decoding of validators, as it can be the case that repeated slashing calls
|
||||
// cause many calls to GetValidator, which were shown to throttle the state machine in our
|
||||
// simulation. Note this is quite biased though, as the simulator does more slashes than a
|
||||
// live chain should, however we require the slashing to be fast as noone pays gas for it.
|
||||
type cachedValidator struct {
|
||||
val types.Validator
|
||||
marshalled string // marshalled amino bytes for the validator object (not operator address)
|
||||
}
|
||||
|
||||
// validatorCache-key: validator amino bytes
|
||||
var validatorCache = make(map[string]cachedValidator, 500)
|
||||
var validatorCacheList = list.New()
|
||||
|
||||
// get a single validator
|
||||
func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator types.Validator, found bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
@ -18,6 +32,28 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator ty
|
||||
if value == nil {
|
||||
return validator, false
|
||||
}
|
||||
|
||||
// If these amino encoded bytes are in the cache, return the cached validator
|
||||
strValue := string(value)
|
||||
if val, ok := validatorCache[strValue]; ok {
|
||||
valToReturn := val.val
|
||||
// Doesn't mutate the cache's value
|
||||
valToReturn.Operator = addr
|
||||
return valToReturn, true
|
||||
}
|
||||
|
||||
// amino bytes weren't found in cache, so amino unmarshal and add it to the cache
|
||||
validator = types.MustUnmarshalValidator(k.cdc, addr, value)
|
||||
cachedVal := cachedValidator{validator, strValue}
|
||||
validatorCache[strValue] = cachedValidator{validator, strValue}
|
||||
validatorCacheList.PushBack(cachedVal)
|
||||
|
||||
// if the cache is too big, pop off the last element from it
|
||||
if validatorCacheList.Len() > 500 {
|
||||
valToRemove := validatorCacheList.Remove(validatorCacheList.Front()).(cachedValidator)
|
||||
delete(validatorCache, valToRemove.marshalled)
|
||||
}
|
||||
|
||||
validator = types.MustUnmarshalValidator(k.cdc, addr, value)
|
||||
return validator, true
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user