Skip to content

Commit b05b510

Browse files
authored
Merge pull request #4 from blockblaz/feature
fix: refactored code to use native u256
2 parents 3ae78cf + f94c8de commit b05b510

File tree

11 files changed

+159
-268
lines changed

11 files changed

+159
-268
lines changed

README.md

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ The Native Sequencer is a high-performance transaction sequencer designed for La
2929
- **State Management**: Track nonces, balances, and receipts
3030
- **Observability**: Metrics endpoint for monitoring
3131
- **Operator Controls**: Emergency halt, rate limiting, configuration management
32+
- **ExecuteTx Support**: Stateless transaction type (0x05) with automatic forwarding to L1 geth
3233

3334
## Architecture
3435

@@ -336,7 +337,7 @@ The sequencer exposes standard Ethereum JSON-RPC endpoints:
336337

337338
#### `eth_sendRawTransaction`
338339

339-
Submit a raw transaction to the sequencer.
340+
Submit a raw transaction to the sequencer. Supports both legacy transactions and ExecuteTx transactions (type 0x05).
340341

341342
**Request**:
342343
```json
@@ -357,6 +358,21 @@ Submit a raw transaction to the sequencer.
357358
}
358359
```
359360

361+
**Transaction Types Supported**:
362+
- **Legacy Transactions**: Standard Ethereum transactions that are validated, stored in mempool, and sequenced into blocks
363+
- **ExecuteTx Transactions (Type 0x05)**: Stateless transactions that are forwarded directly to L1 geth for execution. These transactions include:
364+
- Pre-state hash and witness data for stateless execution
365+
- Withdrawals data
366+
- Blob versioned hashes
367+
- Standard EIP-1559 fields (chainId, nonce, gas, value, etc.)
368+
369+
**ExecuteTx Handling**:
370+
- ExecuteTx transactions are stateless and designed to be executed by L1 geth
371+
- The sequencer performs minimal validation (signature check for deduplication)
372+
- ExecuteTx transactions are automatically forwarded to L1 geth via `eth_sendRawTransaction`
373+
- Full validation and execution is handled by L1 geth
374+
- ExecuteTx transactions are not stored in the sequencer's mempool
375+
360376
#### `eth_getTransactionReceipt`
361377

362378
Get transaction receipt by transaction hash.
@@ -432,6 +448,9 @@ This is an experimental implementation. The following features are implemented o
432448
- ✅ HTTP server implementation (Zig 0.14.1 networking APIs)
433449
- ✅ HTTP client for L1 communication (JSON-RPC support)
434450
- ✅ Conditional transaction submission (EIP-7796 support)
451+
- ✅ ExecuteTx transaction type support (type 0x05)
452+
- ✅ ExecuteTx JSON serialization/deserialization
453+
- ✅ ExecuteTx forwarding to L1 geth
435454
- ⏳ Complete ECDSA signature verification and recovery (basic implementation)
436455
- ⏳ Full transaction execution engine
437456
- ⏳ RocksDB/LMDB integration for persistence
@@ -484,7 +503,7 @@ The CI pipeline includes:
484503
- **Windows (x86_64)**: Builds and verifies binary for Windows
485504

486505
#### Docker Build Validation
487-
- **Multi-architecture Docker builds**: Tests Docker image builds for both `linux/amd64` and `linux/arm64`
506+
- **Multi-architecture Docker builds**: Tests Docker image builds for `linux/amd64` (ARM64 builds are currently disabled in CI)
488507
- **Image verification**: Validates Docker image structure and metadata
489508
- **Runtime testing**: Verifies that the Docker image can start and contains the expected binary
490509

@@ -506,15 +525,23 @@ The sequencer uses Zig 0.14.1's standard library networking APIs:
506525
- **Connection Handling**: Thread-based concurrent request handling with proper resource cleanup
507526
- **RLP Transaction Parsing**: Full RLP decoding support for transaction deserialization
508527

509-
### Custom U256 Implementation
528+
### ExecuteTx Transaction Support
529+
530+
The sequencer supports ExecuteTx transactions (type 0x05), a stateless transaction type designed for execution by L1 geth nodes. Key features:
510531

511-
Due to a compiler bug in Zig 0.14.x's HashMap implementation with native `u256` types, we use a custom `U256` struct implementation. This struct:
512-
- Uses two `u128` fields to represent 256-bit values
513-
- Provides conversion functions to/from native `u256` and byte arrays
514-
- Includes custom hash and equality functions for HashMap compatibility
515-
- Maintains full compatibility with Ethereum's 32-byte hashes and 20-byte addresses
532+
- **Transaction Type**: EIP-2718 typed transaction with type prefix `0x05`
533+
- **RLP Encoding/Decoding**: Full RLP serialization support matching go-ethereum's ExecuteTx format
534+
- **JSON Serialization**: Complete JSON-RPC serialization/deserialization for ExecuteTx fields
535+
- **Signature Recovery**: ECDSA signature verification and sender address recovery
536+
- **L1 Forwarding**: Automatic forwarding to L1 geth via `eth_sendRawTransaction`
537+
- **Minimal Validation**: Only signature check for deduplication (full validation done by L1 geth)
516538

517-
See `src/core/types.zig` for implementation details and rationale.
539+
ExecuteTx transactions include:
540+
- Standard EIP-1559 fields (chainId, nonce, gas, gasTipCap, gasFeeCap, value, to, data)
541+
- ExecuteTx-specific fields (preStateHash, witness, withdrawals, coinbase, blockNumber, timestamp, blobHashes)
542+
- Signature components (v, r, s)
543+
544+
See `src/core/transaction_execute.zig` for the complete implementation.
518545

519546
## Known Issues & Workarounds
520547

@@ -532,36 +559,6 @@ zig build -Dtarget=x86_64-linux-gnu.2.38
532559
2. Build in a container with glibc 2.38+
533560
3. Use the Docker build which includes the correct glibc version
534561

535-
### Zig 0.14.x HashMap Allocator Bug (RESOLVED)
536-
537-
**Status**: ✅ **RESOLVED** - Custom U256 implementation workaround implemented
538-
539-
This project encountered a compiler bug in Zig 0.14.x related to HashMap initialization with native `u256` types as keys. The error manifests as:
540-
```
541-
error: access of union field 'pointer' while field 'int' is active
542-
at std/mem/Allocator.zig:425:45
543-
```
544-
545-
**Root Cause**: The bug is in HashMap's `AutoContext` type introspection code when handling large integer types (`u256`). This is a compiler bug, not an issue with our code.
546-
547-
**Solution**: We implemented a custom `U256` struct using two `u128` fields with explicit `hash()` and `eql()` methods, along with custom HashMap contexts (`HashContext`, `AddressContext`). This bypasses the problematic `AutoContext` code path entirely.
548-
549-
**Implementation Details**:
550-
- Custom `U256` struct in `src/core/types.zig` with two `u128` fields (`low`, `high`)
551-
- Custom hash function combining both halves via XOR
552-
- Custom equality comparison
553-
- Custom HashMap contexts for `Hash` and `Address` types
554-
- Full compatibility with 32-byte hashes and 20-byte addresses
555-
556-
**Performance**: No performance penalty - the struct is stack-allocated and operations are efficient.
557-
558-
See `src/core/types.zig` for detailed comments explaining the implementation.
559-
560-
### Zig 0.14.x Allocator Bug (Historical)
561-
562-
This project previously encountered allocator bugs in Zig 0.14.0 and 0.14.1 related to allocating arrays of structs containing slices. **Verified through testing**: The bug exists in both versions (at different line numbers: 400 vs 412). The issue was resolved by using a custom `U256` implementation instead of native `u256` types.
563-
564-
565562
## License
566563

567564
See LICENSE file.

0 commit comments

Comments
 (0)