mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-14 13:51:21 +00:00
Revert to using defers in addrbook. (#3025)
* Revert to using defers in addrbook. ValidateBasic->Validate since it requires DNS * Update CHANGELOG_PENDING
This commit is contained in:
@ -21,3 +21,5 @@ Special thanks to external contributors on this release:
|
|||||||
### IMPROVEMENTS:
|
### IMPROVEMENTS:
|
||||||
|
|
||||||
### BUG FIXES:
|
### 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.
|
||||||
|
@ -817,6 +817,11 @@ func makeNodeInfo(
|
|||||||
|
|
||||||
nodeInfo.ListenAddr = lAddr
|
nodeInfo.ListenAddr = lAddr
|
||||||
|
|
||||||
|
err := nodeInfo.Validate()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
return nodeInfo
|
return nodeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +175,9 @@ func (na *NetAddress) Same(other interface{}) bool {
|
|||||||
|
|
||||||
// String representation: <ID>@<IP>:<PORT>
|
// String representation: <ID>@<IP>:<PORT>
|
||||||
func (na *NetAddress) String() string {
|
func (na *NetAddress) String() string {
|
||||||
|
if na == nil {
|
||||||
|
return "<nil-NetAddress>"
|
||||||
|
}
|
||||||
if na.str == "" {
|
if na.str == "" {
|
||||||
addrStr := na.DialString()
|
addrStr := na.DialString()
|
||||||
if na.ID != "" {
|
if na.ID != "" {
|
||||||
@ -186,6 +189,9 @@ func (na *NetAddress) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (na *NetAddress) DialString() string {
|
func (na *NetAddress) DialString() string {
|
||||||
|
if na == nil {
|
||||||
|
return "<nil-NetAddress>"
|
||||||
|
}
|
||||||
return net.JoinHostPort(
|
return net.JoinHostPort(
|
||||||
na.IP.String(),
|
na.IP.String(),
|
||||||
strconv.FormatUint(uint64(na.Port), 10),
|
strconv.FormatUint(uint64(na.Port), 10),
|
||||||
|
@ -36,7 +36,7 @@ type nodeInfoAddress interface {
|
|||||||
// nodeInfoTransport validates a nodeInfo and checks
|
// nodeInfoTransport validates a nodeInfo and checks
|
||||||
// our compatibility with it. It's for use in the handshake.
|
// our compatibility with it. It's for use in the handshake.
|
||||||
type nodeInfoTransport interface {
|
type nodeInfoTransport interface {
|
||||||
ValidateBasic() error
|
Validate() error
|
||||||
CompatibleWith(other NodeInfo) error
|
CompatibleWith(other NodeInfo) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ func (info DefaultNodeInfo) ID() ID {
|
|||||||
return info.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
|
// It returns an error if there
|
||||||
// are too many Channels, if there are any duplicate Channels,
|
// are too many Channels, if there are any duplicate Channels,
|
||||||
// if the ListenAddr is malformed, or if the ListenAddr is a host name
|
// if the ListenAddr is malformed, or if the ListenAddr is a host name
|
||||||
@ -116,7 +116,7 @@ func (info DefaultNodeInfo) ID() ID {
|
|||||||
// International clients could then use punycode (or we could use
|
// 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
|
// url-encoding), and we just need to be careful with how we handle that in our
|
||||||
// clients. (e.g. off by default).
|
// clients. (e.g. off by default).
|
||||||
func (info DefaultNodeInfo) ValidateBasic() error {
|
func (info DefaultNodeInfo) Validate() error {
|
||||||
|
|
||||||
// ID is already validated.
|
// ID is already validated.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ func TestNodeInfoValidate(t *testing.T) {
|
|||||||
|
|
||||||
// empty fails
|
// empty fails
|
||||||
ni := DefaultNodeInfo{}
|
ni := DefaultNodeInfo{}
|
||||||
assert.Error(t, ni.ValidateBasic())
|
assert.Error(t, ni.Validate())
|
||||||
|
|
||||||
channels := make([]byte, maxNumChannels)
|
channels := make([]byte, maxNumChannels)
|
||||||
for i := 0; i < maxNumChannels; i++ {
|
for i := 0; i < maxNumChannels; i++ {
|
||||||
@ -68,13 +68,13 @@ func TestNodeInfoValidate(t *testing.T) {
|
|||||||
// test case passes
|
// test case passes
|
||||||
ni = testNodeInfo(nodeKey.ID(), name).(DefaultNodeInfo)
|
ni = testNodeInfo(nodeKey.ID(), name).(DefaultNodeInfo)
|
||||||
ni.Channels = channels
|
ni.Channels = channels
|
||||||
assert.NoError(t, ni.ValidateBasic())
|
assert.NoError(t, ni.Validate())
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
ni := testNodeInfo(nodeKey.ID(), name).(DefaultNodeInfo)
|
ni := testNodeInfo(nodeKey.ID(), name).(DefaultNodeInfo)
|
||||||
ni.Channels = channels
|
ni.Channels = channels
|
||||||
tc.malleateNodeInfo(&ni)
|
tc.malleateNodeInfo(&ni)
|
||||||
err := ni.ValidateBasic()
|
err := ni.Validate()
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
assert.Error(t, err, tc.testName)
|
assert.Error(t, err, tc.testName)
|
||||||
} else {
|
} else {
|
||||||
|
@ -162,26 +162,29 @@ func (a *addrBook) FilePath() string {
|
|||||||
|
|
||||||
// AddOurAddress one of our addresses.
|
// AddOurAddress one of our addresses.
|
||||||
func (a *addrBook) AddOurAddress(addr *p2p.NetAddress) {
|
func (a *addrBook) AddOurAddress(addr *p2p.NetAddress) {
|
||||||
a.Logger.Info("Add our address to book", "addr", addr)
|
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
|
a.Logger.Info("Add our address to book", "addr", addr)
|
||||||
a.ourAddrs[addr.String()] = struct{}{}
|
a.ourAddrs[addr.String()] = struct{}{}
|
||||||
a.mtx.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OurAddress returns true if it is our address.
|
// OurAddress returns true if it is our address.
|
||||||
func (a *addrBook) OurAddress(addr *p2p.NetAddress) bool {
|
func (a *addrBook) OurAddress(addr *p2p.NetAddress) bool {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
_, ok := a.ourAddrs[addr.String()]
|
_, ok := a.ourAddrs[addr.String()]
|
||||||
a.mtx.Unlock()
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *addrBook) AddPrivateIDs(IDs []string) {
|
func (a *addrBook) AddPrivateIDs(IDs []string) {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
for _, id := range IDs {
|
for _, id := range IDs {
|
||||||
a.privateIDs[p2p.ID(id)] = struct{}{}
|
a.privateIDs[p2p.ID(id)] = struct{}{}
|
||||||
}
|
}
|
||||||
a.mtx.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddAddress implements AddrBook
|
// AddAddress implements AddrBook
|
||||||
@ -191,6 +194,7 @@ func (a *addrBook) AddPrivateIDs(IDs []string) {
|
|||||||
func (a *addrBook) AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error {
|
func (a *addrBook) AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
return a.addAddress(addr, src)
|
return a.addAddress(addr, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +202,7 @@ func (a *addrBook) AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error {
|
|||||||
func (a *addrBook) RemoveAddress(addr *p2p.NetAddress) {
|
func (a *addrBook) RemoveAddress(addr *p2p.NetAddress) {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
ka := a.addrLookup[addr.ID]
|
ka := a.addrLookup[addr.ID]
|
||||||
if ka == nil {
|
if ka == nil {
|
||||||
return
|
return
|
||||||
@ -211,14 +216,16 @@ func (a *addrBook) RemoveAddress(addr *p2p.NetAddress) {
|
|||||||
func (a *addrBook) IsGood(addr *p2p.NetAddress) bool {
|
func (a *addrBook) IsGood(addr *p2p.NetAddress) bool {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
return a.addrLookup[addr.ID].isOld()
|
return a.addrLookup[addr.ID].isOld()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasAddress returns true if the address is in the book.
|
// HasAddress returns true if the address is in the book.
|
||||||
func (a *addrBook) HasAddress(addr *p2p.NetAddress) bool {
|
func (a *addrBook) HasAddress(addr *p2p.NetAddress) bool {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
ka := a.addrLookup[addr.ID]
|
ka := a.addrLookup[addr.ID]
|
||||||
a.mtx.Unlock()
|
|
||||||
return ka != nil
|
return ka != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,6 +299,7 @@ func (a *addrBook) PickAddress(biasTowardsNewAddrs int) *p2p.NetAddress {
|
|||||||
func (a *addrBook) MarkGood(addr *p2p.NetAddress) {
|
func (a *addrBook) MarkGood(addr *p2p.NetAddress) {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
ka := a.addrLookup[addr.ID]
|
ka := a.addrLookup[addr.ID]
|
||||||
if ka == nil {
|
if ka == nil {
|
||||||
return
|
return
|
||||||
@ -306,6 +314,7 @@ func (a *addrBook) MarkGood(addr *p2p.NetAddress) {
|
|||||||
func (a *addrBook) MarkAttempt(addr *p2p.NetAddress) {
|
func (a *addrBook) MarkAttempt(addr *p2p.NetAddress) {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
ka := a.addrLookup[addr.ID]
|
ka := a.addrLookup[addr.ID]
|
||||||
if ka == nil {
|
if ka == nil {
|
||||||
return
|
return
|
||||||
@ -461,12 +470,13 @@ ADDRS_LOOP:
|
|||||||
|
|
||||||
// ListOfKnownAddresses returns the new and old addresses.
|
// ListOfKnownAddresses returns the new and old addresses.
|
||||||
func (a *addrBook) ListOfKnownAddresses() []*knownAddress {
|
func (a *addrBook) ListOfKnownAddresses() []*knownAddress {
|
||||||
addrs := []*knownAddress{}
|
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
|
addrs := []*knownAddress{}
|
||||||
for _, addr := range a.addrLookup {
|
for _, addr := range a.addrLookup {
|
||||||
addrs = append(addrs, addr.copy())
|
addrs = append(addrs, addr.copy())
|
||||||
}
|
}
|
||||||
a.mtx.Unlock()
|
|
||||||
return addrs
|
return addrs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,6 +486,7 @@ func (a *addrBook) ListOfKnownAddresses() []*knownAddress {
|
|||||||
func (a *addrBook) Size() int {
|
func (a *addrBook) Size() int {
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
|
||||||
return a.size()
|
return a.size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ type mockNodeInfo struct {
|
|||||||
|
|
||||||
func (ni mockNodeInfo) ID() ID { return ni.addr.ID }
|
func (ni mockNodeInfo) ID() ID { return ni.addr.ID }
|
||||||
func (ni mockNodeInfo) NetAddress() *NetAddress { return ni.addr }
|
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 (ni mockNodeInfo) CompatibleWith(other NodeInfo) error { return nil }
|
||||||
|
|
||||||
func AddPeerToSwitch(sw *Switch, peer Peer) {
|
func AddPeerToSwitch(sw *Switch, peer Peer) {
|
||||||
|
@ -350,7 +350,7 @@ func (mt *MultiplexTransport) upgrade(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := nodeInfo.ValidateBasic(); err != nil {
|
if err := nodeInfo.Validate(); err != nil {
|
||||||
return nil, nil, ErrRejected{
|
return nil, nil, ErrRejected{
|
||||||
conn: c,
|
conn: c,
|
||||||
err: err,
|
err: err,
|
||||||
|
Reference in New Issue
Block a user