Skip to content

Account Vec<defined type> fields are decoded with from_json() instead of from_decoded() #7

@kristinaNikolaevaa

Description

@kristinaNikolaevaa

The Python generator produces incorrect account decoding code for fields with this IDL shape with arrayTypeNode
where

count.kind == "prefixedCountNode" (Vec<T>)
item.kind == "definedTypeLinkNode"

This affects:

- Vec<defined struct>
- Vec<defined enum>

The most visible failure happens when a Vec contains an enum field.
Generated account decode() uses from_json(...) for vector items, but Borsh account parsing returns decoded objects, not JSON objects. It should use from_decoded(...).
Minimal IDL to reproduse

`{
   ...
    "accounts": [
      {
        "kind": "accountNode",
        "name": "bag",
        "data": {
          "kind": "structTypeNode",
          "fields": [
            {
              "kind": "structFieldTypeNode",
              "name": "items",
              "type": {
                "kind": "arrayTypeNode",
                "item": {
                  "kind": "definedTypeLinkNode",
                  "name": "item"
                },
                "count": {
                  "kind": "prefixedCountNode",
                  "prefix": {
                    "kind": "numberTypeNode",
                    "format": "u32",
                    "endian": "le"
                  }
                }
              }
            }
          ]
        }
      }
    ],
    "definedTypes": [
      {
        "kind": "definedTypeNode",
        "name": "kind",
        "type": {
          "kind": "enumTypeNode",
          "variants": [
            { "kind": "enumEmptyVariantTypeNode", "name": "A" },
            { "kind": "enumEmptyVariantTypeNode", "name": "B" }
          ]
        }
      },
      {
        "kind": "definedTypeNode",
        "name": "item",
        "type": {
          "kind": "structTypeNode",
          "fields": [
            {
              "kind": "structFieldTypeNode",
              "name": "kind",
              "type": {
                "kind": "definedTypeLinkNode",
                "name": "kind"
              }
  }`

Actual Generated code looks like:
items=list(map(lambda item: types.item.Item.from_json(item), dec.items))
Expected It should be:
items=list(map(lambda item: types.item.Item.from_decoded(item), dec.items))

Nested enums expect JSON like:
{"kind": "Buy"}
But account decoding receives decoded Borsh objects like:
{"Buy": Container()}
That leads to runtime errors such as:
KeyError: 'kind'

Diff file how to fix it is attached

fix.diff.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions