Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module github.com/ava-labs/libevm

go 1.20

retract v1.13.14-0.1.0-rc.1 // bad semver format ("0-rc" grouping) considered > .rc-2

require (
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
github.com/Microsoft/go-winio v0.6.1
Expand Down
93 changes: 93 additions & 0 deletions params/version.libevm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2024 the libevm authors.
//
// The libevm additions to go-ethereum are free software: you can redistribute
// them and/or modify them under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The libevm additions are distributed in the hope that they will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see
// <http://www.gnu.org/licenses/>.

package params

import "fmt"

const (
LibEVMVersionMajor = 0
LibEVMVersionMinor = 1
LibEVMVersionPatch = 0

libEVMReleaseType releaseType = betaRelease
libEVMReleaseCandidate uint = 0 // ignored unless [libEVMReleaseType] == [releaseCandidate]
)

// LibEVMVersion holds the textual version string of `libevm` modifications.
//
// Although compliant with [semver v2], it follows additional rules:
//
// 1. Major, minor, and patch MUST be the respective `geth` values;
// 2. The first three pre-release identifiers MUST be a semver-compliant
// triplet denoting the `libevm` "version";
// 3. On the `main` (development) branch, the final identifier MUST be "alpha"
// or "beta";
// 3. If a production version, the final identifier MUST be "release"; and
// 4. If a release candidate, the final two identifiers MUST be "rc" and an
// incrementing numeric value.
//
// The benefits of this pattern are that (a) it captures all relevant
// information; and (b) it follows an intuitive ordering under semver rules.
// Precedence is determined first by the `geth` version then the `libevm`
// version, with release candidates being lower than actual releases.
//
// The primary drawbacks is that it requires an explicit "release" identifier
// because of the use of pre-release identifiers to capture the `libevm`
// triplet.
//
// [semver v2]: https://semver.org/
var LibEVMVersion = func() string {
v := libEVMSemver{
geth: semverTriplet{VersionMajor, VersionMinor, VersionPatch},
libEVM: semverTriplet{LibEVMVersionMajor, LibEVMVersionMinor, LibEVMVersionPatch},
typ: libEVMReleaseType,
rc: libEVMReleaseCandidate,
}
return v.String()
}()

type semverTriplet struct {
major, minor, patch uint
}

func (t semverTriplet) String() string {
return fmt.Sprintf("%d.%d.%d", t.major, t.minor, t.patch)
}

type releaseType string

const (
// betaRelease MUST be used on `main` branch
betaRelease = releaseType("beta")
// Reserved for `release/*` branches
releaseCandidate = releaseType("rc")
productionRelease = releaseType("release")
)

type libEVMSemver struct {
geth, libEVM semverTriplet
typ releaseType
rc uint
}

func (v libEVMSemver) String() string {
suffix := v.typ
if suffix == releaseCandidate {
suffix = releaseType(fmt.Sprintf("%s.%d", suffix, v.rc))
}
return fmt.Sprintf("%s-%s.%s", v.geth, v.libEVM, suffix)
}
86 changes: 86 additions & 0 deletions params/version.libevm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2024 the libevm authors.
//
// The libevm additions to go-ethereum are free software: you can redistribute
// them and/or modify them under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The libevm additions are distributed in the hope that they will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see
// <http://www.gnu.org/licenses/>.

package params

import (
"testing"

"golang.org/x/mod/semver"
)

func TestLibEVMVersioning(t *testing.T) {
// We have an unusual version structure as defined by [LibEVMVersion] that
// is easy to mess up, so it's easier to just automate it and test the
// ordering assumptions.

// This is a deliberate change-detector test to provide us with a copyable
// string of the current version, useful for git tagging.
const curr = "1.13.14-0.1.0.beta"
if got, want := LibEVMVersion, curr; got != want {
t.Errorf("got LibEVMVersion %q; want %q", got, want)
}

ordered := []libEVMSemver{
{
semverTriplet{1, 13, 14},
semverTriplet{0, 1, 0},
betaRelease,
0, // ignored
},
{
semverTriplet{1, 13, 14},
semverTriplet{0, 1, 0},
releaseCandidate, 1,
},
{
semverTriplet{1, 13, 14},
semverTriplet{0, 1, 0},
releaseCandidate, 2,
},
{
semverTriplet{1, 13, 14},
semverTriplet{0, 1, 0},
productionRelease,
0, // ignored,
},
{
semverTriplet{1, 13, 14},
semverTriplet{0, 1, 1}, // bump takes precedence
betaRelease, 0,
},
{
semverTriplet{1, 13, 14},
semverTriplet{0, 1, 1},
productionRelease, 0,
},
{
semverTriplet{1, 13, 15}, // bump takes precedence
semverTriplet{0, 1, 1},
betaRelease, 0,
},
}

for i, low := range ordered[:len(ordered)-1] {
// The `go mod` semver package requires the "v" prefix, which
// technically isn't valid semver.
lo := "v" + low.String()
hi := "v" + ordered[i+1].String()
if got := semver.Compare(lo, hi); got != -1 {
t.Errorf("Version pattern is not strictly ordered; semver.Compare(%q, %q) = %d", lo, hi, got)
}
}
}
Loading