Skip to content

v1.0.0-preview.24

Pre-release
Pre-release
Compare
Choose a tag to compare
@turbolent turbolent released this 30 Apr 19:19
· 1034 commits to master since this release

What's Changed

💥 Go API Breaking Chance

The API of the Go package cadence improved. These changes only impact users of the Go API of Cadence. These changes had no impact on the language itself or programs written in Cadence.

  • It is no longer possible to access composite fields (cadence.Composite types, like cadence.Struct, cadence.Resource, etc) by index. The Fields field got unexported.

    Details:
    • Accessing fields by index makes code dependent on the order of fields in the Cadence type definition, which may change (order is insignificant)
    • The order of fields of composite values returned from the chain (e.g. from a script) is planned to be made deterministic in the future. The Go API change prepares for this upcoming encoding change. For more details see #2952
    • Accessing fields by name improves code, as it removes possibilities for extracting field values incorrectly (by wrong index)
    • There are two ways to get the value of a composite field:
      • If multiple field values are needed from the composite value,
        use cadence.FieldsMappedByName, which returns a map[string]cadence.Value.

        For example:

        const fooTypeSomeIntFieldName = "someInt"
        const fooTypeSomeStringFieldName = "someString"
        
        // decodeFooEvent decodes the Cadence event:
        //
        //	event Foo(someInt: Int, someString: String)
        //
        // It returns an error if the event does not have the expected fields.
        func decodeFooEvent(event cadence.Event) (someInt cadence.Int, someString cadence.String, err error) {
        	fields := cadence.FieldsMappedByName(event)
        
        	var ok bool
        
        	someIntField := fields[fooTypeSomeIntFieldName]
        	someInt, ok = someIntField.(cadence.Int)
        	if !ok {
        		return cadence.Int{}, "", fmt.Errorf("wrong field type: expected Int, got %T", someInt)
        	}
        	
        	someStringField := fields[fooTypeSomeStringFieldName]
        	someString, ok = someStringField.(cadence.String)
        	if !ok {
        		return cadence.Int{}, "", fmt.Errorf("wrong field type: expected String, got %T", someString)
        	}
        	
        	return someInt, someString, nil
        }
      • If only a single field value is needed from the composite,
        use cadence.SearchFieldByName. As the name indicates, the function performs a linear search over all fields of the composite. Prefer FieldsMappedByName over repeated calls to SearchFieldByName.
        For example:

        const fooTypeSomeIntFieldName = "someInt"
        
        // fooEventSomeIntField gets the value of the someInt field of the Cadence event:
        //
        //	event Foo(someInt: Int)
        //
        // It returns an error if the event does not have the expected field.
        func fooEventSomeIntField(event cadence.Event) (cadence.Int, error) {
        	someIntField := cadence.SearchFieldByName(event, fooTypeSomeIntFieldName)
        	someInt, ok := someIntField.(cadence.Int)
        	if !ok {
        		return cadence.Int{}, fmt.Errorf("wrong field type: expected Int, got %T", someInt)
        	}
        	return someInt, nil
        }
  • cadence.GetFieldByName got renamed to cadence.SearchFieldByName to make it clear that the function performs a linear search

  • cadence.GetFieldsMappedByName got renamed to cadence.FieldsMappedByName, to better follow common Go style / naming guides, e.g. https://google.github.io/styleguide/go/decisions#getters

  • The convenience method ToGoValue of cadence.Value, which converts a cadence.Value into a Go value (if possible), got removed. Likewise, the convenience function cadence.NewValue, which constructs a new cadence.Value from the given Go value (if possible), got removed.

    Details:
    • There are many different use cases and needs for methods that convert between Cadence and Go values. When attempting to convert an arbitrary Cadence value into a Go value, there is no "correct" Go type to return in all cases. Likewise, when attempting to convert an arbitrary Go value to Cadence, there might not be a “correct” result type.
    • Developers might expect a certain Go type to be returned. For example, ToGoValue of cadence.Struct returned a Go slice, but some developers might assume and want a Go map; and ToGoValue of cadence.Dictionary returned a Go map, but did not account for the case where dictionary keys in Cadence might be types that are invalid in Go maps.
    • As the return type of ToGoValue is any, developers using the method need to cast to some expected Go type, and hope the returned value is what they expect.
    • Improvements in the implementation of ToGoValue, like in #2531, would have silently broken programs using the function, as the different return value would have no longer matched the developer’s expected type.
    • Even though these methods and functions got removed from the cadence package, developers can still perform the conversion that the ToGoValue methods performed. A future version of Cadence might re-introduce well-defined and strongly-typed conversion functions, that are also consistent with similar conversion functions in other languages (e.g. JavaScript SDK / FCL).
    • To see what the removed functions and methods did, have a look at the PR that removed them: https://github.com/onflow/cadence/pull/3291/files.
    • If you feel like Cadence should re-gain this functionality, please open a feature request, or even consider contributing them through pull requests

🛠 Improvements

  • Add runtime check for transaction value moves by @SupunS in #3298
  • Add predicate function and test for atree's PersistentSlabStorage.FixLoadedBrokenReferences by @turbolent in #3300

Other Changes

  • Merge release/v1.0.0-preview.23 to master by @github-actions in #3289
  • Update update tool config by @turbolent in #3292
  • Bump atree version in master branch by @fxamacker in #3293

Full Changelog: v1.0.0-preview.23...v1.0.0-preview.24