From 517682f17ccf43d11848cd83f369d81ca0ea74f4 Mon Sep 17 00:00:00 2001 From: youjing Date: Tue, 21 Aug 2018 14:54:12 +0800 Subject: [PATCH 1/2] fix Iterator leak, ref to https://github.com/cosmos/cosmos-sdk/issues/2105 --- examples/democoin/x/assoc/validator_set.go | 1 + examples/democoin/x/oracle/handler.go | 1 + store/iavlstore_test.go | 3 +++ x/auth/mapper.go | 1 + x/gov/keeper_test.go | 2 ++ x/gov/tally.go | 2 +- 6 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/democoin/x/assoc/validator_set.go b/examples/democoin/x/assoc/validator_set.go index 03ce506ea0f1..ad89aab19281 100644 --- a/examples/democoin/x/assoc/validator_set.go +++ b/examples/democoin/x/assoc/validator_set.go @@ -93,6 +93,7 @@ func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.AccAddress, asso func (valset ValidatorSet) Associations(ctx sdk.Context, base sdk.AccAddress) (res []sdk.AccAddress) { res = make([]sdk.AccAddress, valset.maxAssoc) iter := sdk.KVStorePrefixIterator(valset.store, GetAssocPrefix(base)) + defer iter.Close() i := 0 for ; iter.Valid(); iter.Next() { key := iter.Key() diff --git a/examples/democoin/x/oracle/handler.go b/examples/democoin/x/oracle/handler.go index 3c78fc566be6..1aaefc7e1621 100644 --- a/examples/democoin/x/oracle/handler.go +++ b/examples/democoin/x/oracle/handler.go @@ -28,6 +28,7 @@ func (keeper Keeper) update(ctx sdk.Context, val sdk.Validator, valset sdk.Valid prefix := GetSignPrefix(p, keeper.cdc) store := ctx.KVStore(keeper.key) iter := sdk.KVStorePrefixIterator(store, prefix) + defer iter.Close() for ; iter.Valid(); iter.Next() { if valset.Validator(ctx, iter.Value()) != nil { store.Delete(iter.Key()) diff --git a/store/iavlstore_test.go b/store/iavlstore_test.go index d081b4576fde..38d85c65816c 100644 --- a/store/iavlstore_test.go +++ b/store/iavlstore_test.go @@ -168,6 +168,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { require.EqualValues(t, value, expectedKey) i++ } + iter.Close() require.Equal(t, len(expected), i) iter = sdk.KVStorePrefixIterator(iavlStore, []byte{byte(55), byte(255), byte(255)}) @@ -183,6 +184,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { require.EqualValues(t, value, []byte("test4")) i++ } + iter.Close() require.Equal(t, len(expected), i) iter = sdk.KVStorePrefixIterator(iavlStore, []byte{byte(255), byte(255)}) @@ -198,6 +200,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { require.EqualValues(t, value, []byte("test4")) i++ } + iter.Close() require.Equal(t, len(expected), i) } diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 244527af3f22..c8bf94a21f29 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -87,6 +87,7 @@ func (am AccountMapper) SetAccount(ctx sdk.Context, acc Account) { func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) { store := ctx.KVStore(am.key) iter := sdk.KVStorePrefixIterator(store, []byte("account:")) + defer iter.Close() for { if !iter.Valid() { return diff --git a/x/gov/keeper_test.go b/x/gov/keeper_test.go index 442caee901b8..a61292b93e05 100644 --- a/x/gov/keeper_test.go +++ b/x/gov/keeper_test.go @@ -130,6 +130,7 @@ func TestDeposits(t *testing.T) { require.Equal(t, fourSteak, deposit.Amount) depositsIterator.Next() require.False(t, depositsIterator.Valid()) + depositsIterator.Close() // Test Refund Deposits deposit, found = keeper.GetDeposit(ctx, proposalID, addrs[1]) @@ -196,6 +197,7 @@ func TestVotes(t *testing.T) { require.Equal(t, OptionNoWithVeto, vote.Option) votesIterator.Next() require.False(t, votesIterator.Valid()) + votesIterator.Close() } func TestProposalQueues(t *testing.T) { diff --git a/x/gov/tally.go b/x/gov/tally.go index d8d4c78703c1..cfb113ae3356 100644 --- a/x/gov/tally.go +++ b/x/gov/tally.go @@ -36,6 +36,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall // iterate over all the votes votesIterator := keeper.GetVotes(ctx, proposal.GetProposalID()) + defer votesIterator.Close() for ; votesIterator.Valid(); votesIterator.Next() { vote := &Vote{} keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), vote) @@ -64,7 +65,6 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall keeper.deleteVote(ctx, vote.ProposalID, vote.Voter) } - votesIterator.Close() // Iterate over the validators again to tally their voting power and see who didn't vote nonVoting = []sdk.AccAddress{} From e04e52451bffd85f81e02686985c371946a37332 Mon Sep 17 00:00:00 2001 From: youjing Date: Tue, 21 Aug 2018 20:23:53 +0800 Subject: [PATCH 2/2] Modify PENDING.md for #2105 --- PENDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PENDING.md b/PENDING.md index dafd653fe4a3..f36d613202f4 100644 --- a/PENDING.md +++ b/PENDING.md @@ -105,3 +105,4 @@ BUG FIXES * \#1787 Fixed bug where Tally fails due to revoked/unbonding validator * [basecoin] Fixes coin transaction failure and account query [discussion](https://forum.cosmos.network/t/unmarshalbinarybare-expected-to-read-prefix-bytes-75fbfab8-since-it-is-registered-concrete-but-got-0a141dfa/664/6) * [cli] \#1997 Handle panics gracefully when `gaiacli stake {delegation,unbond}` fail to unmarshal delegation. +* \#2105 Fix DB Iterator leak, which may leak a go routine.