0xMiden / 0xMiden/compiler

Felt::new(0) / zero-valued felt in storage generates unsupported f32.const 0.0 WASM instruction

Aberta
#1,240 3 comentários 0 reações 1 responsável Reivindicada por @mooori Ver no GitHub
Linguagem predominante
Rust
Estrelas
115
Forks
84
Merge médio
1d 8h
PRs com merge (30d)
15

Descrição

### Packages versions

miden-client: 0.15.2
miden-protocol: 0.14.4
miden-vm: 0.25.x (via miden-stateful-hasher 0.25.1)
0xMiden/compiler: commit 6d01a0a (next branch)

### Bug description

### Environment
- Compiler: `0xMiden/compiler`, commit `6d01a0a105f2fd7643236ea1b846b9add6b9611f` (`next` branch ancestor)
- miden-client: v0.15.2
- Contract: weather prediction market ([pplmaverick/miden-weather-market](https://github.com/pplmaverick/miden-weather-market))

### Bug description

When a storage field can hold a zero-valued felt — either as a default/unset
state or as an explicit `Felt::new(0)` — the Miden compiler backend emits an
`f32.const 0.0` WASM instruction, which the Miden VM does not support. There
is no compile-time error; the failure surfaces only at runtime.

The root cause appears to be a type-inference path where the integer literal
`0` (or any expression reducing to zero) is lowered through the WASM codegen
as a float `f32.const 0.0` rather than a felt/u64 constant.

### Affected code pattern

```rust
// #![no_std] contract using miden SDK

const STATUS_OPEN: u64 = 1; // ← must be non-zero
const STATUS_SETTLED: u64 = 2; // ← must be non-zero
// Starting from 0 (STATUS_UNSET: u64 = 0) would trigger f32.const 0.0

#[component_storage]
struct WeatherMarketStorage {
// Fields that may naturally hold zero-felt as "unset" are affected:
#[storage(description = "non-zero once initialize() has been called")]
initialized: StorageValue, // zero-as-false pattern broken

#[storage(description = "bet_commitment => non-zero if winnings claimed")]
claimed: StorageMap, // zero-as-absent pattern broken
}

// Helper used throughout to construct felts:
fn felt(v: u64) -> Felt {
Felt::new(v).expect("value is a valid field element")
}
// Calling felt(0) anywhere in storage logic reproduces the issue.
```

### Workaround

Avoid zero entirely in storage-facing code. Use non-zero sentinel values for
all flags, enums, and map presence markers:

```rust
const STATUS_OPEN: u64 = 1; // not 0
const STATUS_SETTLED: u64 = 2; // not 1/0
// For claimed map: write felt(1) to mark "claimed"; treat absence-of-key as unclaimed.
```

Reference in our project:
[`README.md` lines 228–229](https://github.com/pplmaverick/miden-weather-market/blob/main/README.md#L228) |
[`ARCHITECTURE.md` line 50](https://github.com/pplmaverick/miden-weather-market/blob/main/ARCHITECTURE.md#L50)

### Why this matters

Zero-as-default is idiomatic in both Rust and EVM/Solidity. Contract developers
migrating patterns from other ecosystems will naturally reach for zero as an
unset/false sentinel, hit this at runtime with no actionable error message, and
have no path to diagnose it without knowing the WASM codegen detail. A
compile-time warning or error when a zero felt is used in storage context would
eliminate this class of bug entirely.

### How can this be reproduced?

1. Create a Miden account component contract with a storage field that may hold a zero-valued felt (e.g. a boolean flag or a map presence marker):

```rust
#[component_storage]
struct Storage {
#[storage(description = "non-zero once initialized")]
initialized: StorageValue, // zero as "unset" state
}
```

2. In any component method, write or read a zero felt value using `Felt::new(0)` or the equivalent zero literal.

3. Compile the contract with the Miden compiler (`next` branch).

4. Deploy and invoke the method via miden-client.

**Expected:** Normal execution.
**Actual:** Runtime failure — the compiler emits an `f32.const 0.0` WASM instruction for the zero felt value, which the Miden VM does not support.

### Relevant log output

```shell
No terminal log captured at the time — the issue was identified through
runtime failure and documented in project README/ARCHITECTURE as a workaround
pattern. See linked references in Bug description above.
```

Guia de contribuição

Abrir o guia de contribuição

Direção de pesquisa

O problema está na geração de código WASM do compilador, onde o literal inteiro 0 é reduzido para f32.const 0.0. Comece examinando a lógica de inferência de tipo e redução para constantes felt/u64, particularmente em torno de campos de armazenamento. Procure o código que lida com Felt::new(0) ou literais zero. A correção provavelmente envolve garantir que felts de valor zero sejam emitidos como constantes u64/i64, não como floats. Teste compilando um contrato com um campo de armazenamento felt zero e verificando as instruções WASM geradas.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
rust, wasm
Domínio
compilers
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Pouca atividade
Clareza
Claramente especificada
Facilidade para iniciantes
45/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.