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
3 changes: 3 additions & 0 deletions codegen/astgen/v3/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ func (c *codeGenAst) getTemplates(
RawType: field.String(),
IsOptional: isOptional,
IsEnum: c.isEnumType(typeExtracted, pkg),
IsBytes: model.BytesFieldNames[fieldExtracted],
IsBytesHex: model.BytesHexFieldNames[fieldExtracted],
IsUint32: model.Uint32FieldNames[fieldExtracted],
IsUint32List: model.Uint32ListFieldNames[fieldExtracted],
Expand Down Expand Up @@ -438,6 +439,7 @@ func (c *codeGenAst) getDataTypes(pkg *daml.Package, module *daml.Module, module
Type: typeExtracted,
RawType: field.String(),
IsOptional: isOptional,
IsBytes: model.BytesFieldNames[fieldExtracted],
IsBytesHex: model.BytesHexFieldNames[fieldExtracted],
IsUint32: model.Uint32FieldNames[fieldExtracted],
IsUint32List: model.Uint32ListFieldNames[fieldExtracted],
Expand All @@ -455,6 +457,7 @@ func (c *codeGenAst) getDataTypes(pkg *daml.Package, module *daml.Module, module
Type: typeExtracted,
RawType: field.String(),
IsOptional: true,
IsBytes: model.BytesFieldNames[fieldExtracted],
IsBytesHex: model.BytesHexFieldNames[fieldExtracted],
IsUint32: model.Uint32FieldNames[fieldExtracted],
IsUint32List: model.Uint32ListFieldNames[fieldExtracted],
Expand Down
1 change: 1 addition & 0 deletions codegen/model/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type TmplField struct {
RawType string
IsOptional bool
IsEnum bool
IsBytes bool // True if field should use uint8 length prefix (hex:"bytes" tag)
IsBytesHex bool // True if field should use uint16 length prefix (hex:"bytes16" tag)
IsUint32 bool // True if INT64 field should encode as 4-byte uint32 (hex:"uint32" tag)
IsUint32List bool // True if []INT64 field should encode with 4-byte uint32 elements (hex:"[]uint32" tag)
Expand Down
27 changes: 27 additions & 0 deletions codegen/model/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ func (t BytesHex) IsBytesHex() bool {
return true
}

// ** Custom Bytes Length Mapping **

// The Daml compiler erases type synonyms. When you define a field as BytesHex in Daml,
// the compiler expands it to its underlying type (Text) in the compiled Daml-LF output.
// By the time go-daml parses the .dalf files, all it sees is
// signerAddress: Text
// operationData: Text
// root: Text
// There's no way to distinguish which Text fields were originally BytesHex and require special encoding.
// The hardcoded maps (BytesFieldNames, BytesHexFieldNames) work around this limitation by explicitly listing
// field names that need hex encoding tags.

// BytesHexFieldNames contains field names that should use uint16 length prefix
// encoding (hex:"bytes16" tag) instead of the default uint8 length prefix.
//
Expand All @@ -87,6 +99,21 @@ var BytesHexFieldNames = map[string]bool{
"salt": true,
}

// BytesFieldNames contains field names that should use uint8 length prefix
// encoding (hex:"bytes" tag). These are fixed-size hex fields ≤255 bytes.
//
// From MCMS/CCIP contracts:
// - signerAddress: EVM signer address (20 bytes)
// - chainFamilySelector: Chain family selector (4 bytes)
// - root: Merkle root hash (32 bytes)
// - newRoot: New merkle root hash (32 bytes)
var BytesFieldNames = map[string]bool{
"signerAddress": true,
"chainFamilySelector": true,
"root": true,
"newRoot": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this very domain (CCIP/MCMS) specific? I see we also have another specific type Uint32ListFieldNames. I feel this shouldn't belong to this lib

}

// Uint32FieldNames contains field names where INT64 should encode as 4-byte uint32.
// This matches the Daml MCMS/Codec.daml encoding which uses encodeUint32 for these fields.
//
Expand Down
4 changes: 2 additions & 2 deletions codegen/source.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ var _ types.ENUM = {{capitalise .Name}}("")
// {{capitalise .Name}} is a {{.RawType}} type
type {{capitalise .Name}} struct {
{{- range $field := .Fields}}
{{capitalise $field.Name}} {{$field.Type.GoType}} `json:"{{$field.Name}}"{{if $field.IsOptional}} hex:"optional"{{else if $field.IsBytesHex}} hex:"bytes16"{{else if $field.IsUint32}} hex:"uint32"{{else if $field.IsUint32List}} hex:"[]uint32"{{end}}`
{{capitalise $field.Name}} {{$field.Type.GoType}} `json:"{{$field.Name}}"{{if $field.IsOptional}} hex:"optional"{{else if $field.IsBytes}} hex:"bytes"{{else if $field.IsBytesHex}} hex:"bytes16"{{else if $field.IsUint32}} hex:"uint32"{{else if $field.IsUint32List}} hex:"[]uint32"{{end}}`
{{- end}}
}

Expand Down Expand Up @@ -359,7 +359,7 @@ func (t *{{capitalise .Name}}) UnmarshalHex(data string) error {
type {{capitalise .Name}}MCMSParams struct {
{{- range .Fields}}
{{- if not (isCallerField .Name)}}
{{capitalise .Name}} {{.Type.GoType}} `json:"{{.Name}}"{{if .IsOptional}} hex:"optional"{{else if .IsBytesHex}} hex:"bytes16"{{else if .IsUint32}} hex:"uint32"{{else if .IsUint32List}} hex:"[]uint32"{{end}}`
{{capitalise .Name}} {{.Type.GoType}} `json:"{{.Name}}"{{if .IsOptional}} hex:"optional"{{else if .IsBytes}} hex:"bytes"{{else if .IsBytesHex}} hex:"bytes16"{{else if .IsUint32}} hex:"uint32"{{else if .IsUint32List}} hex:"[]uint32"{{end}}`
{{- end}}
{{- end}}
}
Expand Down