Skip to content

Commit 6a56c6f

Browse files
fix: memory leak from policy registration (#1660)
1 parent 643b5dc commit 6a56c6f

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

consensus/istanbul/config.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/ethereum/go-ethereum/accounts/abi/bind"
2525
"github.com/ethereum/go-ethereum/common"
2626
"github.com/ethereum/go-ethereum/common/math"
27+
"github.com/ethereum/go-ethereum/log"
2728
"github.com/ethereum/go-ethereum/params"
2829
"github.com/naoina/toml"
2930
)
@@ -35,6 +36,8 @@ const (
3536
Sticky
3637
)
3738

39+
const MaxValidatorSetInRegistry = 100 // Max number of ValidatorSet in the registry
40+
3841
// ProposerPolicy represents the Validator Proposer Policy
3942
type ProposerPolicy struct {
4043
Id ProposerPolicyId // Could be RoundRobin or Sticky
@@ -111,17 +114,26 @@ func (p *ProposerPolicy) RegisterValidatorSet(valSet ValidatorSet) {
111114
p.registry = []ValidatorSet{valSet}
112115
} else {
113116
p.registry = append(p.registry, valSet)
117+
// Non-validators don't ever call ClearRegistry
118+
// Validators cap the registry to MaxValidatorSetInRegistry length to prevent unexpected leaks
119+
if len(p.registry) > MaxValidatorSetInRegistry {
120+
p.registry = p.registry[1:]
121+
}
114122
}
123+
log.Debug("Validator Policy Registry", "length", p.GetRegistrySize())
115124
}
116125

117126
// ClearRegistry removes any ValidatorSet from the ProposerPolicy registry
118127
func (p *ProposerPolicy) ClearRegistry() {
119128
p.registryMU.Lock()
120129
defer p.registryMU.Unlock()
121-
122130
p.registry = nil
123131
}
124132

133+
func (p *ProposerPolicy) GetRegistrySize() int {
134+
return len(p.registry)
135+
}
136+
125137
type Config struct {
126138
RequestTimeout uint64 `toml:",omitempty"` // The timeout for each Istanbul round in milliseconds.
127139
BlockPeriod uint64 `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second

consensus/istanbul/validator/proposerpolicy_test.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,20 @@ import (
2424
"github.com/stretchr/testify/assert"
2525
)
2626

27+
var (
28+
addr1 = common.HexToAddress("0xc53f2189bf6d7bf56722731787127f90d319e112")
29+
addr2 = common.HexToAddress("0xed2d479591fe2c5626ce09bca4ed2a62e00e5bc2")
30+
addr3 = common.HexToAddress("0xc8417f834995aaeb35f342a67a4961e19cd4735c")
31+
addr4 = common.HexToAddress("0x784ae51f5013b51c8360afdf91c6bc5a16f586ea")
32+
addr5 = common.HexToAddress("0xecf0974e6f0630fd91ea4da8399cdb3f59e5220f")
33+
addr6 = common.HexToAddress("0x411c4d11acd714b82a5242667e36de14b9e1d10b")
34+
addr7 = common.HexToAddress("0x681381b3D0DaaC179d95aCc9e22E23da2DA670f6")
35+
addrSet = []common.Address{addr1, addr2, addr3, addr4, addr5, addr6}
36+
addrSet2 = []common.Address{addr7, addr1, addr2, addr3, addr4, addr5}
37+
)
38+
2739
func TestProposerPolicy(t *testing.T) {
28-
addr1 := common.HexToAddress("0xc53f2189bf6d7bf56722731787127f90d319e112")
29-
addr2 := common.HexToAddress("0xed2d479591fe2c5626ce09bca4ed2a62e00e5bc2")
30-
addr3 := common.HexToAddress("0xc8417f834995aaeb35f342a67a4961e19cd4735c")
31-
addr4 := common.HexToAddress("0x784ae51f5013b51c8360afdf91c6bc5a16f586ea")
32-
addr5 := common.HexToAddress("0xecf0974e6f0630fd91ea4da8399cdb3f59e5220f")
33-
addr6 := common.HexToAddress("0x411c4d11acd714b82a5242667e36de14b9e1d10b")
34-
35-
addrSet := []common.Address{addr1, addr2, addr3, addr4, addr5, addr6}
40+
3641
addressSortedByByte := []common.Address{addr6, addr4, addr1, addr3, addr5, addr2}
3742
addressSortedByString := []common.Address{addr6, addr4, addr1, addr2, addr5, addr3}
3843

@@ -51,3 +56,17 @@ func TestProposerPolicy(t *testing.T) {
5156
assert.Equal(t, addressSortedByString[i].Hex(), valList[i].String(), "validatorSet not string sorted")
5257
}
5358
}
59+
60+
func TestProposerPolicyRegistration(t *testing.T) {
61+
// test that registration can't go beyond MaxValidatorSetInRegistry limit
62+
pp := istanbul.NewRoundRobinProposerPolicy()
63+
pp2 := istanbul.NewRoundRobinProposerPolicy()
64+
valSet := NewSet(addrSet, pp)
65+
valSet2 := NewSet(addrSet2, pp2)
66+
67+
for i := 0; i < istanbul.MaxValidatorSetInRegistry+100; i++ {
68+
pp.RegisterValidatorSet(valSet)
69+
}
70+
pp.RegisterValidatorSet(valSet2)
71+
assert.Equal(t, istanbul.MaxValidatorSetInRegistry, pp.GetRegistrySize(), "validator set not dropped")
72+
}

0 commit comments

Comments
 (0)