Skip to content

Commit

Permalink
swith to single mapped version
Browse files Browse the repository at this point in the history
  • Loading branch information
janezpodhostnik committed Oct 25, 2024
1 parent d9d5ef4 commit 9c47667
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 122 deletions.
49 changes: 12 additions & 37 deletions fvm/environment/minimum_required_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,59 +33,34 @@ func (c minimumRequiredVersion) MinimumRequiredVersion() (string, error) {
return cadenceVersion.String(), nil
}

// mapToCadenceVersion finds the entry in the versionMapping with the flow version that is closest to,
// but not higher the given flowGoVersion than returns the cadence version for that entry.
// the versionMapping is assumed to be sorted by flowGoVersion.
func mapToCadenceVersion(flowGoVersion semver.Version, versionMapping []VersionMapEntry) semver.Version {
// return 0.0.0 if there is no mapping for the version
var closestEntry = VersionMapEntry{}

// example setup: flowGoVersion = 2.1
// versionMapping = [
// {FlowGoVersion: 1.0, CadenceVersion: 1.1},
// {FlowGoVersion: 2.0, CadenceVersion: 2.1},
// {FlowGoVersion: 2.1, CadenceVersion: 2.2},
// {FlowGoVersion: 3.0, CadenceVersion: 3.1},
// {FlowGoVersion: 4.0, CadenceVersion: 4.1},
// ]
for _, entry := range versionMapping {
// loop 1: 2.1 >= 1.0 closest entry is 0
// loop 2: 2.1 >= 2.0 closest entry is 1
// loop 3: 2.1 >= 2.1 closest entry is 2
// loop 4: 2.1 < 3.0 we went too high: closest entry is 2 break
if versionGreaterThanOrEqualTo(flowGoVersion, entry.FlowGoVersion) {
closestEntry = entry
} else {
break
}
func mapToCadenceVersion(flowGoVersion semver.Version, versionMapping FlowGoToCadenceVersionMapping) semver.Version {
if versionGreaterThanOrEqualTo(flowGoVersion, versionMapping.FlowGoVersion) {
return versionMapping.CadenceVersion
} else {
return semver.Version{}
}

// return the cadence version for the closest entry (2): 2.2
return closestEntry.CadenceVersion
}

func versionGreaterThanOrEqualTo(version semver.Version, other semver.Version) bool {
return version.Compare(other) >= 0
}

type VersionMapEntry struct {
type FlowGoToCadenceVersionMapping struct {
FlowGoVersion semver.Version
CadenceVersion semver.Version
}

// FVMToCadenceVersionMapping is a hardcoded mapping between FVM versions and Cadence versions.
// Entries are only needed for cadence versions where cadence intends to switch behaviour
// based on the version.
// This should be ordered in ascending order by FlowGoVersion.
var minimumFvmToMinimumCadenceVersionMapping = []VersionMapEntry{
// This could also be a map, but ist not needed because we only expect one entry at a give time
// we won't be fixing 2 separate issues at 2 separate version with one deploy.
var minimumFvmToMinimumCadenceVersionMapping = FlowGoToCadenceVersionMapping{
// Leaving this example in, so it's easier to understand
//{
//
// FlowGoVersion: *semver.New("0.37.0"),
// CadenceVersion: *semver.New("1.0.0"),
//},
//
}

func SetFVMToCadenceVersionMappingForTestingOnly(mapping []VersionMapEntry) {
func SetFVMToCadenceVersionMappingForTestingOnly(mapping FlowGoToCadenceVersionMapping) {
minimumFvmToMinimumCadenceVersionMapping = mapping
}

Expand Down
63 changes: 11 additions & 52 deletions fvm/environment/minimum_required_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,19 @@ func Test_MapToCadenceVersion(t *testing.T) {
Patch: 0,
}

mapping := []VersionMapEntry{
{
FlowGoVersion: flowV1,
CadenceVersion: cadenceV1,
},
{
FlowGoVersion: flowV2,
CadenceVersion: cadenceV2,
},
}

mappingWith2Versions := []VersionMapEntry{
{
FlowGoVersion: flowV1,
CadenceVersion: cadenceV1,
},
{
FlowGoVersion: flowV2,
CadenceVersion: cadenceV2,
},
mapping := FlowGoToCadenceVersionMapping{
FlowGoVersion: flowV1,
CadenceVersion: cadenceV1,
}

t.Run("no mapping, v0", func(t *testing.T) {
version := mapToCadenceVersion(flowV0, nil)
version := mapToCadenceVersion(flowV0, FlowGoToCadenceVersionMapping{})

require.Equal(t, cadenceV0, version)
})

t.Run("v0", func(t *testing.T) {
version := mapToCadenceVersion(flowV0, mappingWith2Versions)
version := mapToCadenceVersion(flowV0, mapping)

require.Equal(t, semver.Version{}, version)
})
Expand All @@ -69,12 +52,12 @@ func Test_MapToCadenceVersion(t *testing.T) {
v := flowV1
v.Patch -= 1

version := mapToCadenceVersion(v, mappingWith2Versions)
version := mapToCadenceVersion(v, mapping)

require.Equal(t, cadenceV0, version)
})
t.Run("v1", func(t *testing.T) {
version := mapToCadenceVersion(flowV1, mappingWith2Versions)
version := mapToCadenceVersion(flowV1, mapping)

require.Equal(t, cadenceV1, version)
})
Expand All @@ -83,7 +66,7 @@ func Test_MapToCadenceVersion(t *testing.T) {
v := flowV1
v.BumpPatch()

version := mapToCadenceVersion(v, mappingWith2Versions)
version := mapToCadenceVersion(v, mapping)

require.Equal(t, cadenceV1, version)
})
Expand All @@ -92,12 +75,12 @@ func Test_MapToCadenceVersion(t *testing.T) {
v := flowV2
v.Patch -= 1

version := mapToCadenceVersion(v, mappingWith2Versions)
version := mapToCadenceVersion(v, mapping)

require.Equal(t, cadenceV1, version)
})
t.Run("v2", func(t *testing.T) {
version := mapToCadenceVersion(flowV2, mappingWith2Versions)
version := mapToCadenceVersion(flowV2, mapping)

require.Equal(t, cadenceV2, version)
})
Expand All @@ -106,32 +89,8 @@ func Test_MapToCadenceVersion(t *testing.T) {
v := flowV2
v.BumpPatch()

version := mapToCadenceVersion(v, mappingWith2Versions)

require.Equal(t, cadenceV2, version)
})

t.Run("v1 - delta, single version in mapping", func(t *testing.T) {

v := flowV1
v.Patch -= 1

version := mapToCadenceVersion(v, mapping)

require.Equal(t, cadenceV0, version)
})
t.Run("v1, single version in mapping", func(t *testing.T) {
version := mapToCadenceVersion(flowV1, mapping)

require.Equal(t, cadenceV1, version)
})
t.Run("v1 + delta, single version in mapping", func(t *testing.T) {

v := flowV1
v.BumpPatch()

version := mapToCadenceVersion(v, mapping)

require.Equal(t, cadenceV1, version)
require.Equal(t, cadenceV2, version)
})
}
36 changes: 3 additions & 33 deletions fvm/fvm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3564,33 +3564,14 @@ func Test_MinimumRequiredVersion(t *testing.T) {
Patch: 3,
PreRelease: "rc.2",
}
flowVersion2 := semver.Version{
Major: 2,
Minor: 2,
Patch: 3,
PreRelease: "rc.1",
}
cadenceVersion2 := semver.Version{
Major: 12,
Minor: 0,
Patch: 0,
PreRelease: "",
}
environment.SetFVMToCadenceVersionMappingForTestingOnly(
[]environment.VersionMapEntry{
{
FlowGoVersion: flowVersion1,
CadenceVersion: cadenceVersion1,
},
{
FlowGoVersion: flowVersion2,
CadenceVersion: cadenceVersion2,
},
environment.FlowGoToCadenceVersionMapping{
FlowGoVersion: flowVersion1,
CadenceVersion: cadenceVersion1,
})

h0 := uint64(100) // starting height
hv1 := uint64(2000) // version boundary height
hv2 := uint64(4000) // version boundary height

txIndex := uint32(0)

Expand All @@ -3617,19 +3598,8 @@ func Test_MinimumRequiredVersion(t *testing.T) {

// system transaction needs to run to update the flowVersion on chain
snapshotTree = runSystemTxToUpdateNodeVersionBeaconContract(hv1+1, ctx, snapshotTree, vm, txIndex)
txIndex += 1

// still cadence version 1
require.Equal(t, cadenceVersion1.String(), getVersion(ctx, snapshotTree))

// insert version boundary 2
snapshotTree = insertVersionBoundary(flowVersion2, hv1+1, hv2, ctx, snapshotTree, vm, txIndex)
txIndex += 1

// system transaction needs to run to update the flowVersion on chain
snapshotTree = runSystemTxToUpdateNodeVersionBeaconContract(hv2, ctx, snapshotTree, vm, txIndex)

// switch cadence version 2
require.Equal(t, cadenceVersion2.String(), getVersion(ctx, snapshotTree))
}))
}

0 comments on commit 9c47667

Please sign in to comment.