0xMiden / 0xMiden/protocol

Transaction events: Rust types and commitment specification

Đang mở
#3,830 0 bình luận 0 reaction 1 người được giao Được @partylikeits1983 nhận Xem trên GitHub
Ngôn ngữ chính
Rust
Star
132
Fork
167
Merge trung bình
1 ngày 23 giờ
Pull request đã merge (30 ngày)
110

Mô tả

Part of #3803. This issue adds the Rust types, serialization, and commitment specification for transaction events. Kernel and transaction integration will follow in #3831.

### Rust Types

Add two types in `miden_protocol::transaction`:
- `TransactionEvent` contains `emitter: AccountId`, `topic: Word`, and `payload: Vec`.
- `TransactionEvents` holds the ordered events and their computed commitment.

Constructors will validate the size limits. Fields remain private, with no direct mutable access or unchecked constructors. Empty lists, empty payloads, and duplicate events are allowed. Events retain their insertion order, and the collection commitment is cached but not serialized.

`TransactionEvents::try_push(event)` will check the event count and total payload size, append the event, and update the commitment. Validation errors will leave the collection unchanged. Construction from a vector will use the same append logic.

### Commitment

Use the existing Poseidon2 hasher to extend the commitment as each event is added. For events numbered `1..=n`:

```text
P_i = Hasher::hash_elements(flatten(payload_i))
M_i = [emitter_suffix, emitter_prefix, payload_word_count, i]
C_0 = EMPTY_WORD
C_i = Hasher::hash_elements_in_domain(
C_(i-1) || M_i || topic_i || P_i,
TX_EVENTS_DOMAIN,
)
events_commitment = C_n
```

Each step hashes four words, binding the emitter, topic, payload, count, and order. The event position is derived from the list rather than serialized. Empty payloads hash to `EMPTY_WORD`. This PR will allocate and document the event hash domain.

The kernel can then maintain the commitment and counters between calls without retaining the full list or building a Merkle tree.

### Serialization and Limits

Use the existing serialization traits and encodings for `AccountId` and `Word`, with little endian `u16` lengths:

```text
TransactionEvent = emitter || topic || payload_word_count || payload_words
TransactionEvents = event_count || events
```

The initial limits are 64 events per transaction, 256 words per payload, and 2,048 total payload words. Deserialization will check counts before allocation and the remaining transaction budget before reading each payload, then compute the commitment from the decoded events.

### Topics

Document `topic = Hasher::hash(signature.as_bytes())` for canonical signatures such as `example::Transfer(account_id,u64)`, without whitespace or parameter names. The protocol treats topics as opaque words; application schemas and SDK tooling remain outside this issue.

### Tests and Scope

Tests will cover fixed serialization and commitment vectors, empty and duplicate events, field changes, ordering, size limits, invalid encodings, and truncated data. Include intermediate commitment vectors for each append so #3831 can verify the same results in MASM. Also verify that validation errors leave the collection unchanged and excessive lengths are rejected before payload reads.

This is Rust only. Transaction output layouts, IDs, summaries, protobuf, MASM, and finalization are covered by #3831.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.