-
Notifications
You must be signed in to change notification settings - Fork 179
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
Expose minimum required version to cadence interface #6560
Changes from 8 commits
a79c9b8
f82f503
f36aafe
59269e0
fe18d5a
4166e0a
b2fa1c3
2109f64
a72cd52
2ccf370
d9d5ef4
9c47667
456e8a6
58e84cd
b2ee0e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -62,6 +62,8 @@ type Environment interface { | |||||||||||||||||||||
error, | ||||||||||||||||||||||
) | ||||||||||||||||||||||
|
||||||||||||||||||||||
GetCurrentVersionBoundary() (cadence.Value, error) | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a comment, but this is a different function. This one just exposes the one on |
||||||||||||||||||||||
|
||||||||||||||||||||||
// AccountInfo | ||||||||||||||||||||||
GetAccount(address flow.Address) (*flow.Account, error) | ||||||||||||||||||||||
GetAccountKeys(address flow.Address) ([]flow.AccountPublicKey, error) | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,76 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
package environment | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/coreos/go-semver/semver" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"github.com/onflow/flow-go/fvm/storage/state" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// MinimumRequiredVersion returns the minimum required cadence version for the current environment | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// in semver format. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type MinimumRequiredVersion interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MinimumRequiredVersion() (string, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we be more specific?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this one is a bit tricky. This method satisfies the cadence runtime interface (defined by cadence) and from a cadence perspective it does not make sense to name it a I'll add a comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Maybe we keep the method name as |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type minimumRequiredVersion struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
txnPreparer state.NestedTransactionPreparer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func NewMinimumRequiredVersion( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
txnPreparer state.NestedTransactionPreparer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) MinimumRequiredVersion { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return minimumRequiredVersion{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
txnPreparer: txnPreparer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func (c minimumRequiredVersion) MinimumRequiredVersion() (string, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
executionParameters := c.txnPreparer.ExecutionParameters() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cadenceVersion := mapToCadenceVersion(executionParameters.ExecutionVersion) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return cadenceVersion.String(), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
func mapToCadenceVersion(version semver.Version) semver.Version { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Too vague, it's better to be more explicit.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add lots of test cases to this function to describe the behavior? I would suggest to let it take the fvmToCadenceVersionMapping as input, so that it's easy to write unittests.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are quite a few cases:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added tests |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// return 0.0.0 if there is no mapping for the version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var cadenceVersion = semver.Version{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
greaterThanOrEqualTo := func(version semver.Version, versionToCompare semver.Version) bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can move this pure function outside |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return version.Compare(versionToCompare) >= 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for _, entry := range fvmToCadenceVersionMapping { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if greaterThanOrEqualTo(version, entry.FlowGoVersion) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cadenceVersion = entry.CadenceVersion | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
break | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why It seems we always just look at the very first version entry only, in that case, why not just having one version entry instead of a mapping? If we are going to hardcode a version map entry, I would say we just hard code the default one:
then we can simplify this function into:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return cadenceVersion | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type VersionMapEntry struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FlowGoVersion semver.Version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CadenceVersion semver.Version | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically the version map doesn't need to know that this is a mapping between minimums. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// 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. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
janezpodhostnik marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var fvmToCadenceVersionMapping = []VersionMapEntry{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// 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) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fvmToCadenceVersionMapping = mapping | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
var _ MinimumRequiredVersion = (*minimumRequiredVersion)(nil) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional:
This introduce unnecessary complexity to the GetMinimumExecutionVersion function.
And create a shortcut for tests. Can we mock the the smart contract call in tests instead?
I saw there are also other WithXXX functions having the same pattern which is to use some flag variables only for testing. IMO, this is a bad practice. We shouldn't have production code skipping some logic (shortcuts) only for tests.
I'm ok for now, but better address this altogether in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For most test this was not used. I only used it for tests that are testing the programs cache loading and resetting. The reason I did that is that an extra contract is loading now, and those tests were off by 1. I think its cleaner for those tests to focus on what they were testing without this interference.
I agree its not the bast pattern, and I will try mocking in a separate PR.
However I am thinking of also using this setting for bootstrapping...