diff --git a/network/peer.go b/network/peer.go index 08a10e37bc02..9e880814329d 100644 --- a/network/peer.go +++ b/network/peer.go @@ -469,8 +469,13 @@ func (p *peer) version(msg Msg) { if err := p.net.version.Compatible(peerVersion); err != nil { p.net.log.Debug("peer version not compatible due to %s", err) - p.discardIP() - return + if !p.net.beacons.Contains(p.id) { + p.discardIP() + return + } + p.net.log.Info("allowing beacon %s to connect with a lower version %s", + p.id, + peerVersion) } if p.ip.IsZero() { diff --git a/version/version.go b/version/version.go index 1bf2d639cf3f..7c9d62e86cc0 100644 --- a/version/version.go +++ b/version/version.go @@ -93,9 +93,9 @@ func (v *version) Compatible(o Version) error { switch { case v.App() != o.App(): return errDifferentApps - case v.Major() != o.Major(): + case v.Major() > o.Major(): return errDifferentMajor - case v.Minor() != o.Minor(): + case v.Major() == o.Major() && v.Minor() > o.Minor(): return errDifferentMinor default: return nil diff --git a/version/version_test.go b/version/version_test.go index 7ffbba4bc72f..7fa9a892ae96 100644 --- a/version/version_test.go +++ b/version/version_test.go @@ -4,6 +4,7 @@ package version import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -35,54 +36,83 @@ func TestNewVersion(t *testing.T) { assert.False(t, v.Before(v)) } -func TestIncompatibleApps(t *testing.T) { - v0 := NewDefaultVersion("avalanche", 1, 2, 3) - v1 := NewDefaultVersion("notavalanche", 1, 2, 3) - - assert.NotNil(t, v0) - assert.NotNil(t, v1) - assert.Error(t, v0.Compatible(v1)) - assert.Error(t, v1.Compatible(v0)) - - assert.False(t, v0.Before(v1)) - assert.False(t, v1.Before(v0)) -} - -func TestIncompatibleMajor(t *testing.T) { - v0 := NewDefaultVersion("avalanche", 1, 2, 3) - v1 := NewDefaultVersion("avalanche", 2, 2, 3) - - assert.NotNil(t, v0) - assert.NotNil(t, v1) - assert.Error(t, v0.Compatible(v1)) - assert.Error(t, v1.Compatible(v0)) - - assert.True(t, v0.Before(v1)) - assert.False(t, v1.Before(v0)) -} - -func TestIncompatibleMinor(t *testing.T) { - v0 := NewDefaultVersion("avalanche", 1, 2, 3) - v1 := NewDefaultVersion("avalanche", 1, 3, 3) - - assert.NotNil(t, v0) - assert.NotNil(t, v1) - assert.Error(t, v0.Compatible(v1)) - assert.Error(t, v1.Compatible(v0)) - - assert.True(t, v0.Before(v1)) - assert.False(t, v1.Before(v0)) -} - -func TestCompatiblePatch(t *testing.T) { - v0 := NewDefaultVersion("avalanche", 1, 2, 3) - v1 := NewDefaultVersion("avalanche", 1, 2, 4) - - assert.NotNil(t, v0) - assert.NotNil(t, v1) - assert.NoError(t, v0.Compatible(v1)) - assert.NoError(t, v1.Compatible(v0)) - - assert.True(t, v0.Before(v1)) - assert.False(t, v1.Before(v0)) +func TestComparingVersions(t *testing.T) { + tests := []struct { + myVersion Version + peerVersion Version + compatible bool + before bool + }{ + { + myVersion: NewDefaultVersion("avalanche", 1, 2, 3), + peerVersion: NewDefaultVersion("avalanche", 1, 2, 3), + compatible: true, + before: false, + }, + { + myVersion: NewDefaultVersion("avalanche", 1, 2, 4), + peerVersion: NewDefaultVersion("avalanche", 1, 2, 3), + compatible: true, + before: false, + }, + { + myVersion: NewDefaultVersion("avalanche", 1, 2, 3), + peerVersion: NewDefaultVersion("avalanche", 1, 2, 4), + compatible: true, + before: true, + }, + { + myVersion: NewDefaultVersion("avalanche", 1, 3, 3), + peerVersion: NewDefaultVersion("avalanche", 1, 2, 3), + compatible: false, + before: false, + }, + { + myVersion: NewDefaultVersion("avalanche", 1, 2, 3), + peerVersion: NewDefaultVersion("avalanche", 1, 3, 3), + compatible: true, + before: true, + }, + { + myVersion: NewDefaultVersion("avalanche", 2, 2, 3), + peerVersion: NewDefaultVersion("avalanche", 1, 2, 3), + compatible: false, + before: false, + }, + { + myVersion: NewDefaultVersion("avalanche", 1, 2, 3), + peerVersion: NewDefaultVersion("avalanche", 2, 2, 3), + compatible: true, + before: true, + }, + { + myVersion: NewDefaultVersion("avax", 1, 2, 4), + peerVersion: NewDefaultVersion("avalanche", 1, 2, 3), + compatible: false, + before: false, + }, + { + myVersion: NewDefaultVersion("avalanche", 1, 2, 3), + peerVersion: NewDefaultVersion("avax", 1, 2, 3), + compatible: false, + before: false, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%s %s", test.myVersion, test.peerVersion), func(t *testing.T) { + err := test.myVersion.Compatible(test.peerVersion) + if test.compatible && err != nil { + t.Fatalf("Expected version to be compatible but returned: %s", + err) + } else if !test.compatible && err == nil { + t.Fatalf("Expected version to be incompatible but returned no error") + } + before := test.myVersion.Before(test.peerVersion) + if test.before && !before { + t.Fatalf("Expected version to be before the peer version but wasn't") + } else if !test.before && before { + t.Fatalf("Expected version not to be before the peer version but was") + } + }) + } }