Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert to using defers in addrbook. #3025

Merged
merged 2 commits into from
Dec 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ Special thanks to external contributors on this release:
### IMPROVEMENTS:

### BUG FIXES:

- [\#3025](https://github.com/tendermint/tendermint/pull/3025) - Revert to using defers in addrbook. Fixes deadlocks in pex and consensus upon invalid ExternalAddr/ListenAddr configuration.
5 changes: 5 additions & 0 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,11 @@ func makeNodeInfo(

nodeInfo.ListenAddr = lAddr

err := nodeInfo.Validate()
if err != nil {
panic(err)
}

return nodeInfo
}

Expand Down
6 changes: 6 additions & 0 deletions p2p/netaddress.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ func (na *NetAddress) Same(other interface{}) bool {

// String representation: <ID>@<IP>:<PORT>
func (na *NetAddress) String() string {
if na == nil {
return "<nil-NetAddress>"
}
if na.str == "" {
addrStr := na.DialString()
if na.ID != "" {
Expand All @@ -186,6 +189,9 @@ func (na *NetAddress) String() string {
}

func (na *NetAddress) DialString() string {
if na == nil {
return "<nil-NetAddress>"
}
return net.JoinHostPort(
na.IP.String(),
strconv.FormatUint(uint64(na.Port), 10),
Expand Down
6 changes: 3 additions & 3 deletions p2p/node_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type nodeInfoAddress interface {
// nodeInfoTransport validates a nodeInfo and checks
// our compatibility with it. It's for use in the handshake.
type nodeInfoTransport interface {
ValidateBasic() error
Validate() error
CompatibleWith(other NodeInfo) error
}

Expand Down Expand Up @@ -103,7 +103,7 @@ func (info DefaultNodeInfo) ID() ID {
return info.ID_
}

// ValidateBasic checks the self-reported DefaultNodeInfo is safe.
// Validate checks the self-reported DefaultNodeInfo is safe.
// It returns an error if there
// are too many Channels, if there are any duplicate Channels,
// if the ListenAddr is malformed, or if the ListenAddr is a host name
Expand All @@ -116,7 +116,7 @@ func (info DefaultNodeInfo) ID() ID {
// International clients could then use punycode (or we could use
// url-encoding), and we just need to be careful with how we handle that in our
// clients. (e.g. off by default).
func (info DefaultNodeInfo) ValidateBasic() error {
func (info DefaultNodeInfo) Validate() error {

// ID is already validated.

Expand Down
6 changes: 3 additions & 3 deletions p2p/node_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestNodeInfoValidate(t *testing.T) {

// empty fails
ni := DefaultNodeInfo{}
assert.Error(t, ni.ValidateBasic())
assert.Error(t, ni.Validate())

channels := make([]byte, maxNumChannels)
for i := 0; i < maxNumChannels; i++ {
Expand Down Expand Up @@ -68,13 +68,13 @@ func TestNodeInfoValidate(t *testing.T) {
// test case passes
ni = testNodeInfo(nodeKey.ID(), name).(DefaultNodeInfo)
ni.Channels = channels
assert.NoError(t, ni.ValidateBasic())
assert.NoError(t, ni.Validate())

for _, tc := range testCases {
ni := testNodeInfo(nodeKey.ID(), name).(DefaultNodeInfo)
ni.Channels = channels
tc.malleateNodeInfo(&ni)
err := ni.ValidateBasic()
err := ni.Validate()
if tc.expectErr {
assert.Error(t, err, tc.testName)
} else {
Expand Down
25 changes: 18 additions & 7 deletions p2p/pex/addrbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,29 @@ func (a *addrBook) FilePath() string {

// AddOurAddress one of our addresses.
func (a *addrBook) AddOurAddress(addr *p2p.NetAddress) {
a.Logger.Info("Add our address to book", "addr", addr)
a.mtx.Lock()
defer a.mtx.Unlock()

a.Logger.Info("Add our address to book", "addr", addr)
a.ourAddrs[addr.String()] = struct{}{}
a.mtx.Unlock()
}

// OurAddress returns true if it is our address.
func (a *addrBook) OurAddress(addr *p2p.NetAddress) bool {
a.mtx.Lock()
defer a.mtx.Unlock()

_, ok := a.ourAddrs[addr.String()]
a.mtx.Unlock()
return ok
}

func (a *addrBook) AddPrivateIDs(IDs []string) {
a.mtx.Lock()
defer a.mtx.Unlock()

for _, id := range IDs {
a.privateIDs[p2p.ID(id)] = struct{}{}
}
a.mtx.Unlock()
}

// AddAddress implements AddrBook
Expand All @@ -191,13 +194,15 @@ func (a *addrBook) AddPrivateIDs(IDs []string) {
func (a *addrBook) AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error {
a.mtx.Lock()
defer a.mtx.Unlock()

return a.addAddress(addr, src)
}

// RemoveAddress implements AddrBook - removes the address from the book.
func (a *addrBook) RemoveAddress(addr *p2p.NetAddress) {
a.mtx.Lock()
defer a.mtx.Unlock()

ka := a.addrLookup[addr.ID]
if ka == nil {
return
Expand All @@ -211,14 +216,16 @@ func (a *addrBook) RemoveAddress(addr *p2p.NetAddress) {
func (a *addrBook) IsGood(addr *p2p.NetAddress) bool {
a.mtx.Lock()
defer a.mtx.Unlock()

return a.addrLookup[addr.ID].isOld()
}

// HasAddress returns true if the address is in the book.
func (a *addrBook) HasAddress(addr *p2p.NetAddress) bool {
a.mtx.Lock()
defer a.mtx.Unlock()

ka := a.addrLookup[addr.ID]
a.mtx.Unlock()
return ka != nil
}

Expand Down Expand Up @@ -292,6 +299,7 @@ func (a *addrBook) PickAddress(biasTowardsNewAddrs int) *p2p.NetAddress {
func (a *addrBook) MarkGood(addr *p2p.NetAddress) {
a.mtx.Lock()
defer a.mtx.Unlock()

ka := a.addrLookup[addr.ID]
if ka == nil {
return
Expand All @@ -306,6 +314,7 @@ func (a *addrBook) MarkGood(addr *p2p.NetAddress) {
func (a *addrBook) MarkAttempt(addr *p2p.NetAddress) {
a.mtx.Lock()
defer a.mtx.Unlock()

ka := a.addrLookup[addr.ID]
if ka == nil {
return
Expand Down Expand Up @@ -461,12 +470,13 @@ ADDRS_LOOP:

// ListOfKnownAddresses returns the new and old addresses.
func (a *addrBook) ListOfKnownAddresses() []*knownAddress {
addrs := []*knownAddress{}
a.mtx.Lock()
defer a.mtx.Unlock()

addrs := []*knownAddress{}
for _, addr := range a.addrLookup {
addrs = append(addrs, addr.copy())
}
a.mtx.Unlock()
return addrs
}

Expand All @@ -476,6 +486,7 @@ func (a *addrBook) ListOfKnownAddresses() []*knownAddress {
func (a *addrBook) Size() int {
a.mtx.Lock()
defer a.mtx.Unlock()

return a.size()
}

Expand Down
2 changes: 1 addition & 1 deletion p2p/test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type mockNodeInfo struct {

func (ni mockNodeInfo) ID() ID { return ni.addr.ID }
func (ni mockNodeInfo) NetAddress() *NetAddress { return ni.addr }
func (ni mockNodeInfo) ValidateBasic() error { return nil }
func (ni mockNodeInfo) Validate() error { return nil }
func (ni mockNodeInfo) CompatibleWith(other NodeInfo) error { return nil }

func AddPeerToSwitch(sw *Switch, peer Peer) {
Expand Down
2 changes: 1 addition & 1 deletion p2p/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ func (mt *MultiplexTransport) upgrade(
}
}

if err := nodeInfo.ValidateBasic(); err != nil {
if err := nodeInfo.Validate(); err != nil {
return nil, nil, ErrRejected{
conn: c,
err: err,
Expand Down