diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 9c7ce727f..f4f213279 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -324,14 +324,19 @@ func (app *BaseApp) FilterPeerByPubKey(info string) abci.ResponseQuery { return abci.ResponseQuery{} } -// Implements ABCI. -// Delegates to CommitMultiStore if it implements Queryable -func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { - path := strings.Split(req.Path, "/") +func splitPath(requestPath string) (path []string) { + path = strings.Split(requestPath, "/") // first element is empty string if len(path) > 0 && path[0] == "" { path = path[1:] } + return path +} + +// Implements ABCI. +// Delegates to CommitMultiStore if it implements Queryable +func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) { + path := splitPath(req.Path) // "/app" prefix for special application queries if len(path) >= 2 && path[0] == "app" { var result sdk.Result diff --git a/store/iavlstore.go b/store/iavlstore.go index e5d509572..d05c867c2 100644 --- a/store/iavlstore.go +++ b/store/iavlstore.go @@ -153,6 +153,20 @@ func (st *iavlStore) ReverseIterator(start, end []byte) Iterator { return newIAVLIterator(st.tree.Tree(), start, end, false) } +// Handle gatest the latest height, if height is 0 +func getHeight(tree *iavl.VersionedTree, req abci.RequestQuery) int64 { + height := req.Height + if height == 0 { + latest := tree.Version64() + if tree.VersionExists(latest - 1) { + height = latest - 1 + } else { + height = latest + } + } + return height +} + // Query implements ABCI interface, allows queries // // by default we will return from (latest height -1), @@ -167,24 +181,17 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) { } tree := st.tree - height := req.Height - if height == 0 { - latest := tree.Version64() - if tree.VersionExists(latest - 1) { - height = latest - 1 - } else { - height = latest - } - } - // store the height we chose in the response - res.Height = height + + // store the height we chose in the response, with 0 being changed to the + // latest height + res.Height = getHeight(tree, req) switch req.Path { case "/store", "/key": // Get by key key := req.Data // Data holds the key bytes res.Key = key if req.Prove { - value, proof, err := tree.GetVersionedWithProof(key, height) + value, proof, err := tree.GetVersionedWithProof(key, res.Height) if err != nil { res.Log = err.Error() break @@ -198,7 +205,7 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) { } res.Proof = p } else { - _, res.Value = tree.GetVersioned(key, height) + _, res.Value = tree.GetVersioned(key, res.Height) } case "/subspace": subspace := req.Data diff --git a/tools/gometalinter.json b/tools/gometalinter.json index 32ae434c4..124e28c14 100644 --- a/tools/gometalinter.json +++ b/tools/gometalinter.json @@ -5,5 +5,5 @@ "Enable": ["golint", "vet", "ineffassign", "unparam", "unconvert", "misspell", "gocyclo"], "Deadline": "500s", "Vendor": true, - "Cyclo": 10 + "Cyclo": 11 } \ No newline at end of file diff --git a/types/int.go b/types/int.go index d04c6a80c..0227203cd 100644 --- a/types/int.go +++ b/types/int.go @@ -37,6 +37,13 @@ func mod(i *big.Int, i2 *big.Int) *big.Int { return new(big.Int).Mod(i, i2) } func neg(i *big.Int) *big.Int { return new(big.Int).Neg(i) } +func min(i *big.Int, i2 *big.Int) *big.Int { + if i.Cmp(i2) == 1 { + return new(big.Int).Set(i2) + } + return new(big.Int).Set(i) +} + // MarshalAmino for custom encoding scheme func marshalAmino(i *big.Int) (string, error) { bz, err := i.MarshalText() @@ -227,6 +234,11 @@ func (i Int) Neg() (res Int) { return Int{neg(i.i)} } +// Return the minimum of the ints +func MinInt(i1, i2 Int) Int { + return Int{min(i1.BigInt(), i2.BigInt())} +} + func (i Int) String() string { return i.i.String() } @@ -419,6 +431,11 @@ func (i Uint) DivRaw(i2 uint64) Uint { return i.Div(NewUint(i2)) } +// Return the minimum of the Uints +func MinUint(i1, i2 Uint) Uint { + return Uint{min(i1.BigInt(), i2.BigInt())} +} + // MarshalAmino defines custom encoding scheme func (i Uint) MarshalAmino() (string, error) { if i.i == nil { // Necessary since default Uint initialization has i.i as nil diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index f194d656c..a2080eab9 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -81,10 +81,7 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in } // Cannot decrease balance below zero - sharesToRemove := remainingSlashAmount - if sharesToRemove.GT(validator.PoolShares.Amount.RoundInt()) { - sharesToRemove = validator.PoolShares.Amount.RoundInt() - } + sharesToRemove := sdk.MinInt(remainingSlashAmount, validator.PoolShares.Amount.RoundInt()) // Get the current pool pool := k.GetPool(ctx) @@ -163,10 +160,7 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty // Possible since the unbonding delegation may already // have been slashed, and slash amounts are calculated // according to stake held at time of infraction - unbondingSlashAmount := slashAmount - if unbondingSlashAmount.GT(unbondingDelegation.Balance.Amount) { - unbondingSlashAmount = unbondingDelegation.Balance.Amount - } + unbondingSlashAmount := sdk.MinInt(slashAmount, unbondingDelegation.Balance.Amount) // Update unbonding delegation if necessary if !unbondingSlashAmount.IsZero() {