codegen: support array types everywhere (struct/record fields, mapping values, function I/O), recursively
还没有人认领这个 Issue。
评估
调研方向
Start in codegen/_emit.py at resolve_ty and _check_struct_refs, then inspect tests/test_codegen_emit.py and the existing tests/fixtures/shield_swap_v3.abi.json fixture. Add coverage for recursive arrays in struct, record, mapping, and function I/O positions, including nested structs and arrays; done means emission and plaintext round-trips pass while unsupported ABI shapes still raise clearly.
由索引模型根据 Issue 内容生成。
描述
Summary
aleo.codegen does not support array types. codegen/_emit.py::resolve_ty maps only {"Primitive": …} and {"Struct": …}; every other shape falls through to raise ValueError("Unsupported ABI type: …"). Arrays are represented in the ABI as {"Array": {"element": <ty>, "length": N}}, which has no branch — so any struct/record field (or mapping value) that is an array breaks emit_module.
Structs (nested structs, cross-program ref checks) work; this is specific to arrays.
What "support arrays" means here
An Aleo array is just a fixed-length collection of a single element type, and that element can itself be any type:
- a primitive —
[u8; 32],[field; 4],[bool; 8],[address; 3] - a struct —
[Foo; 2] - another array (arbitrary nesting) —
[[u8; 4]; 3],[[Foo; 2]; 5]
So the fix must be recursive: resolve_ty should resolve the element type (which may recurse into a primitive, a struct, or a nested array) and build the Python representation from it. There is no fixed depth.
Scope — arrays must work in EVERY type position
Array support should be complete wherever the codegen resolves a type:
- Struct fields —
struct Foo: xs as [u8; 4u32]; - Record fields —
record R: data as [field; 8u32].private; - Mapping values —
mapping m: key as ...; value as [u8; 32u32]; - Function input / output positions —
input r0 as [u8; 4u32].private;/output r0 as [Foo; 2u32].private;
Note on (4): emit_module currently emits struct/record dataclasses, mapping-value decoders, and the raw ABI dict, but does not emit typed function signatures at all — so today array function I/O neither works nor errors, it's simply unbound. Completing this item therefore also means the codegen must resolve function input/output types (arrays included), not just struct/record/mapping types.
Reproduction
from aleo.abi import generate_abi
from aleo.mainnet import Program
from aleo.codegen._emit import emit_module
src = """program arr3.aleo;
struct Foo:
xs as [u8; 4u32];
function usefoo:
input r0 as Foo.private;
output r0 as Foo.private;
"""
abi = generate_abi(Program.from_source(src), "mainnet")
emit_module(abi)
# ValueError: Unsupported ABI type:
# {'Array': {'element': {'Primitive': {'UInt': 'U8'}}, 'length': 4}}
Runtime decoding is unaffected — codegen/runtime.py::_parse_array already turns array plaintext into Python lists (see the passing test_parse_nested_struct_and_array). The gap is purely on the emission/type-mapping side.
Suggested fix
resolve_ty— add a recursive"Array"case. Resolve the element typeet = resolve_ty(ty["Array"]["element"]), then:- annotation:
list[<et.annotation>] - encode:
"[ " + ", ".join(<et.encode(x)> for x in e) + " ]"(Aleo array literal). The element encoder is applied per element, so[Foo; 2]callsFoo.to_plaintext()per element and[[u8;4];3]recurses. - decode: map the element decoder over the list — pass-through for primitive elements,
Elem.from_decodedfor struct elements, and recurse for nested arrays. (runtime.parse_plaintextalready yields nested lists, so decode just re-wraps struct elements.)
- annotation:
_check_struct_refs— descend into array elements so a[SomeStruct; N]field/value still resolves its struct reference (currently only top-level{"Struct"}is checked; a struct nested in an array is skipped).- Function I/O typing — if/when function signatures are emitted, route their input/output types through the same
resolve_tyso arrays are covered there too.
Robust array test fixture (required)
Add a dedicated ABI fixture (sibling to tests/fixtures/shield_swap_v3.abi.json) that exercises arrays in every position and nesting, and drive emit + round-trip (to_plaintext → from_plaintext) tests off it:
- array of each primitive family:
[u8; N]/int,[bool; N],[address; N],[field; N](field/group/scalar) - array of struct:
[Foo; N] - nested array:
[[u8; 4]; 3], and array-of-array-of-struct[[Foo; 2]; 3] - an array field inside a struct, inside a record, as a mapping value, and in a function input and output
- struct containing an array containing a struct (mixed recursion)
Round-trip assertions should confirm: emitted annotations (list[...], nested), to_plaintext produces valid Aleo array literals for each case, and from_plaintext/from_decoded reconstructs the exact Python value (including struct elements and nesting). Also keep a negative test asserting a clear error for genuinely unsupported shapes.
Why it wasn't caught
The only real ABI fixture (tests/fixtures/shield_swap_v3.abi.json) is 258 Primitive + 16 Struct with zero arrays, and test_codegen_emit.py only exercises resolve_ty on primitives + structs.
- 主要语言
- Python
- 星标
- 45
- 派生
- 51
- 平均合并
- 3 天 18 小时
- 30 天内合并 PR
- 2
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
ProvableHQ/python-sdk 的其他 Issue
-
难度 3/5 1-2 天 新手友好度 35/100
ProvableHQ/python-sdk#43 ·
-
ProvableHQ/python-sdk#10 · 3 条评论 · 已指派 1 人 ·
-
难度 5/5 一周以上 新手友好度 25/100
ProvableHQ/python-sdk#7 ·
查看 ProvableHQ/python-sdk 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 86/100
zostera/django-bootstrap4#894 ·
-
难度 2/5 1-3 小时 新手友好度 78/100
use-agent-os/agent-os#3276 ·
-
难度 2/5 1-3 小时 新手友好度 88/100
zephyrproject-rtos/zephyr#119726 ·
-
area/auth bug comp/agent P3 platform/discord type/security
难度 2/5 1-3 小时 新手友好度 88/100
NousResearch/hermes-agent#117848 ·
-
难度 2/5 1-3 小时 新手友好度 82/100
zilliztech/memsearch#759 ·