docs: graduate Phase 0 into production documentation

Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
Claude 2026-02-20 15:24:38 +00:00
parent 4c0b7f290e
commit 37cc3d7342
No known key found for this signature in database
GPG key ID: AF404715446AEB41
5 changed files with 707 additions and 36 deletions

View file

@ -1,46 +1,27 @@
# go-blockchain
# CLAUDE.md
Go implementation of the Lethean blockchain protocol. Pure Go package providing
chain configuration, core data types, wire serialisation, and difficulty
calculation for the Lethean CryptoNote/Zano-fork chain.
Pure Go implementation of the Lethean blockchain protocol (config, types, wire, difficulty).
This package follows ADR-001: Go Shell + C++ Crypto Library. Protocol logic
lives in Go; only the mathematically complex cryptographic primitives (ring
signatures, bulletproofs, Zarcanum proofs) are delegated to a cleaned C++
library via CGo in later phases.
Module: `forge.lthn.ai/core/go-blockchain`
Lineage: CryptoNote -> IntenseCoin (2017) -> Lethean -> Zano rebase.
Licence: EUPL-1.2
## Build and Test
## Commands
```bash
go build ./...
go test -v -race ./...
go vet ./...
go test ./... # run all tests
go test -race ./... # race detector (required before commit)
go test -v -run Name ./... # single test
go vet ./... # vet check
```
## Package Layout
## Standards
```
config/ Chain parameters (mainnet/testnet), hardfork schedule
types/ Core data types: Hash, PublicKey, Address, Block, Transaction
wire/ Binary serialisation (CryptoNote varint encoding)
difficulty/ PoW + PoS difficulty adjustment (LWMA variant)
crypto/ (future) CGo bridge to libcryptonote
p2p/ (future) Levin TCP protocol
rpc/ (future) Daemon and wallet JSON-RPC
chain/ (future) Blockchain storage, validation, mempool
wallet/ (future) Key management, output scanning, tx construction
consensus/ (future) Hardfork rules, block reward, fee policy
```
- UK English
- `go test -race ./...` and `go vet ./...` must pass before commit
- Conventional commits: `type(scope): description`
- Co-Author: `Co-Authored-By: Charon <charon@lethean.io>`
## Coding Standards
## Docs
- **Language:** UK English in all comments and documentation (colour, organisation, centre)
- **Commits:** Conventional commits (`feat:`, `fix:`, `refactor:`, `test:`, `docs:`)
- **Co-Author:** All commits include `Co-Authored-By: Charon <charon@lethean.io>`
- **Test naming:** `_Good` (happy path), `_Bad` (expected errors), `_Ugly` (panics/edge cases)
- **Imports:** stdlib, then `golang.org/x`, then `forge.lthn.ai`, each separated by a blank line
- **No emojis** in code or comments
- `docs/architecture.md` -- package structure, key types, design decisions, ADR-001
- `docs/development.md` -- prerequisites, test patterns, coding standards
- `docs/history.md` -- completed phases with commit hashes, known limitations

55
README.md Normal file
View file

@ -0,0 +1,55 @@
# go-blockchain
Pure Go implementation of the Lethean blockchain protocol. Provides chain configuration, core cryptographic data types, CryptoNote wire serialisation, and LWMA difficulty adjustment for the Lethean CryptoNote/Zano-fork chain. Follows ADR-001: protocol logic in Go, cryptographic primitives deferred to a C++ bridge in later phases. Lineage: CryptoNote to IntenseCoin (2017) to Lethean to Zano rebase.
**Module**: `forge.lthn.ai/core/go-blockchain`
**Licence**: EUPL-1.2
**Language**: Go 1.25
## Quick Start
```go
import (
"forge.lthn.ai/core/go-blockchain/config"
"forge.lthn.ai/core/go-blockchain/types"
"forge.lthn.ai/core/go-blockchain/wire"
"forge.lthn.ai/core/go-blockchain/difficulty"
)
// Query the active hardfork version at a given block height
version := config.VersionAtHeight(config.MainnetForks, 10081) // returns HF2
// Check if a specific hardfork is active
active := config.IsHardForkActive(config.MainnetForks, config.HF4Zarcanum, 50000) // false
// Encode and decode a Lethean address
addr := &types.Address{SpendPublicKey: spendKey, ViewPublicKey: viewKey}
encoded := addr.Encode(config.AddressPrefix)
decoded, prefix, err := types.DecodeAddress(encoded)
// Varint encoding for the wire protocol
buf := wire.EncodeVarint(0x1eaf7)
val, n, err := wire.DecodeVarint(buf)
// Calculate next block difficulty
nextDiff := difficulty.NextDifficulty(timestamps, cumulativeDiffs, 120)
```
## Documentation
- [Architecture](docs/architecture.md) -- package structure, key types, design decisions, ADR-001
- [Development Guide](docs/development.md) -- prerequisites, test patterns, coding standards
- [Project History](docs/history.md) -- completed phases with commit hashes, known limitations
## Build & Test
```bash
go test ./...
go test -race ./...
go vet ./...
go build ./...
```
## Licence
European Union Public Licence 1.2 -- see [LICENCE](LICENCE) for details.

257
docs/architecture.md Normal file
View file

@ -0,0 +1,257 @@
# Architecture
go-blockchain is a pure Go implementation of the Lethean blockchain protocol. It
provides chain configuration, core cryptographic data types, consensus-critical
wire serialisation, and difficulty adjustment for the Lethean CryptoNote/Zano-fork
chain.
Module path: `forge.lthn.ai/core/go-blockchain`
---
## Package Structure
```
config/ Chain parameters (mainnet/testnet), hardfork schedule
types/ Core data types: Hash, PublicKey, Address, Block, Transaction
wire/ Binary serialisation (CryptoNote varint encoding)
difficulty/ PoW + PoS difficulty adjustment (LWMA variant)
```
### config/
Defines every consensus-critical constant for the Lethean chain, derived directly
from the canonical C++ source files `currency_config.h.in` and `default.cmake`.
Constants cover tokenomics, address prefixes, network ports, difficulty parameters,
block and transaction limits, version numbers, PoS parameters, P2P constants,
network identity, currency identity, and alias rules.
The `ChainConfig` struct aggregates all parameters into a single value.
Pre-populated `Mainnet` and `Testnet` variables are provided as package-level
globals. The hardfork schedule is defined in `hardfork.go` with lookup functions
for querying active versions at any block height.
### types/
Fixed-size byte array types matching the CryptoNote specification:
- `Hash` (32 bytes) -- Keccak-256 hash values
- `PublicKey` (32 bytes) -- Ed25519 public keys
- `SecretKey` (32 bytes) -- Ed25519 secret keys
- `KeyImage` (32 bytes) -- double-spend detection images
- `Signature` (64 bytes) -- cryptographic signatures
Also contains the full address encoding/decoding implementation (CryptoNote
base58 with Keccak-256 checksums), block header and block structures, and all
transaction types across versions 0 through 3.
### wire/
Consensus-critical binary serialisation primitives. Currently implements
CryptoNote varint encoding (7-bit LEB128 with MSB continuation). All encoding
must be bit-identical to the C++ reference implementation.
### difficulty/
LWMA (Linear Weighted Moving Average) difficulty adjustment algorithm for both
PoW and PoS blocks. Examines a window of recent block timestamps and cumulative
difficulties to calculate the next target difficulty.
---
## Key Types
### ChainConfig
```go
type ChainConfig struct {
Name string
Abbreviation string
IsTestnet bool
CurrencyFormationVersion uint64
Coin uint64
DisplayDecimalPoint uint8
BlockReward uint64
DefaultFee uint64
MinimumFee uint64
Premine uint64
AddressPrefix uint64
IntegratedAddressPrefix uint64
AuditableAddressPrefix uint64
AuditableIntegratedAddressPrefix uint64
P2PPort uint16
RPCPort uint16
StratumPort uint16
DifficultyPowTarget uint64
DifficultyPosTarget uint64
DifficultyWindow uint64
DifficultyLag uint64
DifficultyCut uint64
DifficultyPowStarter uint64
DifficultyPosStarter uint64
MaxBlockNumber uint64
TxMaxAllowedInputs uint64
TxMaxAllowedOutputs uint64
DefaultDecoySetSize uint64
HF4MandatoryDecoySetSize uint64
MinedMoneyUnlockWindow uint64
P2PMaintainersPubKey string
}
```
Pre-populated globals `Mainnet` and `Testnet` contain the complete parameter
sets for each network. Mainnet uses ports 36940-36942; testnet uses 46940-46942.
### HardFork
```go
type HardFork struct {
Version uint8
Height uint64
Mandatory bool
Description string
}
```
Seven hardfork versions are defined (HF0 through HF6). On mainnet, HF0 is
active from genesis, HF1 and HF2 activate after block 10,080, and HF3 through
HF6 are scheduled at height 999,999,999 (effectively future). On testnet, most
forks activate early for testing.
### Address
```go
type Address struct {
SpendPublicKey PublicKey
ViewPublicKey PublicKey
Flags uint8
}
```
Four address types are supported via distinct prefixes:
| Type | Prefix | Leading chars |
|------|--------|---------------|
| Standard | `0x1eaf7` | `iTHN` |
| Integrated | `0xdeaf7` | `iTHn` |
| Auditable | `0x3ceff7` | `iThN` |
| Auditable integrated | `0x8b077` | `iThn` |
### Block and Transaction
```go
type BlockHeader struct {
MajorVersion uint8
MinorVersion uint8
Timestamp uint64
PrevID Hash
Nonce uint64
}
type Block struct {
BlockHeader
MinerTx Transaction
TxHashes []Hash
}
type Transaction struct {
Version uint8
UnlockTime uint64
Vin []TxInput
Vout []TxOutput
Extra []byte
}
```
Transaction versions progress through the hardfork schedule:
| Version | Era | Description |
|---------|-----|-------------|
| 0 | Genesis | Coinbase transactions |
| 1 | Pre-HF4 | Standard transparent transactions |
| 2 | Post-HF4 | Zarcanum confidential transactions (CLSAG) |
| 3 | Post-HF5 | Confidential assets with surjection proofs |
Input types: `TxInputGenesis` (coinbase, tag `0xFF`) and `TxInputToKey` (standard
spend with ring signature, tag `0x02`).
Output types: `TxOutputBare` (transparent, tag `0x02`) and `TxOutputZarcanum`
(confidential with Pedersen commitments, tag `0x03`).
---
## Design Decisions
### Why CryptoNote Base58
CryptoNote uses its own base58 variant (not Bitcoin's base58check). The alphabet
omits `0`, `O`, `I`, and `l` to avoid visual ambiguity. Data is split into 8-byte
blocks, each encoded independently into 11 base58 characters. The final partial
block produces fewer characters according to a fixed mapping table
(`base58BlockSizes`). This block-based approach differs from Bitcoin's
whole-number division and produces different output for the same input bytes.
The implementation uses `math/big` for block conversion rather than a lookup
table. This is correct for all uint64 ranges but is not optimised for
high-throughput address generation. Performance optimisation is deferred to a
later phase if profiling identifies it as a bottleneck.
### Why Keccak-256 (Not SHA3-256)
CryptoNote predates the NIST SHA-3 standard. It uses the original Keccak-256
submission (`sha3.NewLegacyKeccak256()`), which differs from the finalised
SHA3-256 in padding. This is consensus-critical -- using SHA3-256 would produce
different checksums and break address compatibility with the C++ node.
### Address Encoding Algorithm
1. Encode the address prefix as a CryptoNote varint
2. Append the 32-byte spend public key
3. Append the 32-byte view public key
4. Append the 1-byte flags field
5. Compute Keccak-256 over bytes 1-4, take the first 4 bytes as checksum
6. Append the 4-byte checksum
7. Encode the entire blob using CryptoNote base58
Decoding reverses this process: base58 decode, extract and validate the varint
prefix, verify the Keccak-256 checksum, then extract the two keys and flags.
### Varint Encoding
The wire format uses 7-bit variable-length integers identical to protobuf
varints. Each byte carries 7 data bits in the low bits with the MSB set to 1
if more bytes follow. A uint64 requires at most 10 bytes. The implementation
provides sentinel errors (`ErrVarintOverflow`, `ErrVarintEmpty`) for malformed
input.
### Hardfork System (Reverse-Scan VersionAtHeight)
`VersionAtHeight()` iterates all hardforks and returns the highest version whose
activation height has been passed. A fork with `Height=0` is active from genesis.
A fork with `Height=N` is active at heights strictly greater than N.
This scan approach (rather than a sorted binary search) is deliberate: the fork
list is small (7 entries) and correctness is trivially verifiable. The same list
drives both `VersionAtHeight()` and `IsHardForkActive()`.
### LWMA Difficulty Adjustment
The difficulty algorithm uses the LWMA (Linear Weighted Moving Average) approach:
```
nextDiff = difficultyDelta * targetInterval / timeSpan
```
The window examines up to 735 blocks (720 window + 15 lag). When fewer blocks
are available (early chain), the algorithm uses whatever data exists. Division
by zero is prevented by clamping the time span to a minimum of 1 second.
`StarterDifficulty` (value 1) is returned when insufficient data is available.
### ADR-001: Go Shell + C++ Crypto Library
This package follows ADR-001. All protocol logic, data types, serialisation,
and configuration live in pure Go. Only the mathematically complex cryptographic
primitives (ring signatures, bulletproofs, Zarcanum proofs) will be delegated to
a cleaned C++ library via CGo in later phases. This boundary keeps the Go code
testable without a C toolchain while preserving access to battle-tested
cryptographic implementations.

202
docs/development.md Normal file
View file

@ -0,0 +1,202 @@
# Development Guide
## Prerequisites
- Go 1.25 or later (the module declares `go 1.25`)
- `golang.org/x/crypto` for Keccak-256 (legacy, pre-NIST)
- No CGO required
No C toolchain, no system libraries, no external build tools. A plain
`go build ./...` is sufficient.
---
## Build and Test
```bash
# Run all tests
go test ./...
# Run all tests with the race detector (required before every commit)
go test -race ./...
# Run a single test by name
go test -v -run TestVersionAtHeight ./config/
# Run a single subtest
go test -v -run "TestVersionAtHeight_Good/genesis" ./config/
# Check for vet issues
go vet ./...
# Tidy dependencies
go mod tidy
```
All three commands (`go test -race ./...`, `go vet ./...`, and `go mod tidy`)
must produce no errors or warnings before a commit is pushed.
---
## Test Patterns
### File Organisation
Each package has a corresponding `_test.go` file in the same package (white-box
tests):
- `config/config_test.go` -- constant validation against C++ source values
- `config/hardfork_test.go` -- hardfork schedule and version lookup
- `types/address_test.go` -- address encode/decode round-trips, base58, checksums
- `difficulty/difficulty_test.go` -- LWMA algorithm behaviour
- `wire/varint_test.go` -- varint encode/decode round-trips, boundary values
### Naming Convention
All tests follow the `_Good`, `_Bad`, `_Ugly` suffix pattern:
- `_Good` -- happy path (correct inputs produce correct outputs)
- `_Bad` -- expected error conditions (invalid input, checksum corruption)
- `_Ugly` -- edge cases (empty slices, nil inputs, overflow, zero time spans)
Examples:
```
TestAddressEncodeDecodeRoundTrip_Good
TestDecodeAddress_Bad
TestBase58Empty_Ugly
TestIsHardForkActive_Bad
TestVersionAtHeight_Ugly
TestNextDifficulty_Ugly
TestDecodeVarint_Ugly
```
### Table-Driven Subtests
Most test functions use table-driven subtests with `t.Run()`:
```go
tests := []struct {
name string
height uint64
want uint8
}{
{"genesis", 0, HF0Initial},
{"before_hf1", 10080, HF0Initial},
{"at_hf1_hf2", 10081, HF2},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := VersionAtHeight(MainnetForks, tt.height)
if got != tt.want {
t.Errorf("got %d, want %d", got, tt.want)
}
})
}
```
### Test Helpers
`makeTestAddress(flags uint8)` creates an address with deterministic byte
patterns (sequential values 0-31 for the spend key, 32-63 for the view key).
This produces reproducible base58 output for round-trip testing.
### Assertion Style
Tests use the standard library `testing` package directly with `t.Error`,
`t.Errorf`, and `t.Fatal`. Testify is not used in this package. Error messages
include both the got and want values with descriptive context.
---
## Coverage
Current coverage by package:
| Package | Coverage |
|---------|----------|
| config | 100.0% |
| difficulty | 81.0% |
| types | 73.4% |
| wire | 95.2% |
Total test functions: 75 (across 5 test files).
The lower coverage in `types/` reflects unexported helper functions
(`encodeBlock`, `decodeBlock`, `base58CharIndex`) that are exercised indirectly
through the public API but have branches not fully reached by the current test
vectors. The lower coverage in `difficulty/` reflects the window-capping branch
that only triggers with more than 735 block entries.
`go test -race ./...` passes clean across all packages.
---
## Coding Standards
### Language
UK English throughout: colour, organisation, serialise, initialise, behaviour.
Do not use American spellings in identifiers, comments, or documentation.
### Go Style
- All exported types, functions, and fields must have doc comments
- Error strings use the `package: description` format (e.g. `types: invalid hex
for hash`)
- Error wrapping uses `fmt.Errorf("types: description: %w", err)`
- Every source file carries the EUPL-1.2 copyright header
- No emojis in code or comments
- Imports are ordered: stdlib, then `golang.org/x`, then `forge.lthn.ai`, each
separated by a blank line
### Dependencies
Direct dependencies are intentionally minimal:
| Dependency | Purpose |
|------------|---------|
| `golang.org/x/crypto` | Keccak-256 (legacy, pre-NIST) for address checksums |
| `golang.org/x/sys` | Indirect, required by `golang.org/x/crypto` |
No test-only dependencies beyond the standard library `testing` package.
---
## Licence
EUPL-1.2. Every source file carries the standard copyright header:
```
// Copyright (c) 2017-2026 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// SPDX-License-Identifier: EUPL-1.2
```
---
## Commit Convention
Format: `type(scope): description`
Common types: `feat`, `fix`, `test`, `refactor`, `docs`, `perf`, `chore`
Common scopes: `config`, `types`, `wire`, `difficulty`, `address`, `hardfork`
Every commit must include:
```
Co-Authored-By: Charon <charon@lethean.io>
```
Example:
```
feat(types): add Zarcanum confidential output type
Co-Authored-By: Charon <charon@lethean.io>
```
Commits must not be pushed unless `go test -race ./...` and `go vet ./...` both
pass. `go mod tidy` must produce no changes.

176
docs/history.md Normal file
View file

@ -0,0 +1,176 @@
# Project History
## Origin
go-blockchain implements the Lethean blockchain protocol in pure Go, following
ADR-001 (Go Shell + C++ Crypto Library). The chain lineage is CryptoNote (2014)
to IntenseCoin (2017) to Lethean to a Zano rebase. All consensus parameters are
derived from the canonical C++ source files `currency_config.h.in` and
`default.cmake`.
The package was created as part of the broader effort to rewrite the Lethean
node tooling in Go, keeping protocol logic in Go while deferring only the
mathematically complex cryptographic primitives (ring signatures, bulletproofs,
Zarcanum proofs) to a cleaned C++ library via CGo in later phases.
---
## Phase 0 -- Scaffold
Commit: `4c0b7f2` -- `feat: Phase 0 scaffold -- config, types, wire, difficulty`
Phase 0 established the foundational four packages with complete test suites
and full coverage of the consensus-critical configuration surface.
### Packages implemented
- **config/** -- All chain constants from `currency_config.h.in` and
`default.cmake`: tokenomics (Coin, BlockReward, fees, premine), address
prefixes (standard, integrated, auditable, auditable integrated), network
ports (mainnet 36940-36942, testnet 46940-46942), difficulty parameters
(window 720, lag 15, cut 60, targets 120s), block and transaction limits,
version constants, PoS parameters, P2P constants, network identity, currency
identity, and alias rules. `ChainConfig` struct with pre-populated `Mainnet`
and `Testnet` globals. Hardfork schedule (HF0-HF6) with `VersionAtHeight()`
and `IsHardForkActive()` lookup functions.
- **types/** -- Fixed-size cryptographic types: `Hash` (32 bytes), `PublicKey`
(32 bytes), `SecretKey` (32 bytes), `KeyImage` (32 bytes), `Signature`
(64 bytes). Hex encode/decode for `Hash` and `PublicKey`. CryptoNote base58
address encoding with Keccak-256 checksums. `Address` struct with
`Encode()`/`DecodeAddress()` round-trip. `BlockHeader`, `Block`,
`Transaction` structs. Input types (`TxInputGenesis`, `TxInputToKey`) and
output types (`TxOutputBare`, `TxOutputZarcanum`) with wire type tags.
`TxInput` and `TxOutput` interfaces.
- **wire/** -- CryptoNote varint encoding (7-bit LEB128 with MSB continuation).
`EncodeVarint()` and `DecodeVarint()` with sentinel errors for overflow and
empty input. Maximum 10 bytes per uint64.
- **difficulty/** -- LWMA difficulty adjustment algorithm. `NextDifficulty()`
examines a window of timestamps and cumulative difficulties to compute the
next target. Handles insufficient data (returns `StarterDifficulty`), zero
time spans, and negative difficulty deltas.
### Tests added
75 test cases across 5 test files, all passing with the race detector:
- `config/config_test.go` -- 7 test functions validating every constant group
against C++ source values: tokenomics, address prefixes, ports (mainnet and
testnet), difficulty parameters, network identity, `ChainConfig` struct fields,
transaction limits, and transaction version constants.
- `config/hardfork_test.go` -- 7 test functions covering `VersionAtHeight()`
on both mainnet and testnet fork schedules, `IsHardForkActive()` for boundary
conditions, unknown version queries, empty fork lists, single-element fork
lists, and full fork schedule validation for both networks.
- `types/address_test.go` -- 8 test functions covering encode/decode round-trips
for all four address types, deterministic encoding, auditable flag detection,
integrated prefix detection, invalid input rejection (empty, invalid base58
characters, too short), checksum corruption detection, base58 round-trip, and
base58 edge cases (empty encode/decode).
- `difficulty/difficulty_test.go` -- 7 test functions covering stable difficulty
with constant intervals, empty input, single entry, fast blocks (difficulty
increases), slow blocks (difficulty decreases), zero time span handling, and
algorithm constants.
- `wire/varint_test.go` -- 5 test functions covering encoding known values,
decoding known values, round-trip across all bit boundaries (0 through
`MaxUint64`), empty input errors, and overflow detection.
### Coverage
| Package | Coverage |
|---------|----------|
| config | 100.0% |
| difficulty | 81.0% |
| types | 73.4% |
| wire | 95.2% |
`go test -race ./...` passed clean. `go vet ./...` produced no warnings.
---
## Phase 1 -- Wire Serialisation (Planned)
Extend `wire/` with full block and transaction binary serialisation matching the
C++ `binary_archive` format. Add `Serialise()` and `Deserialise()` methods to
`Block`, `Transaction`, and all input/output types. Validate against real
mainnet block blobs.
## Phase 2 -- Crypto Bridge (Planned)
Create `crypto/` package with CGo bridge to the cleaned C++ `libcryptonote`
library. Implement key derivation (`generate_key_derivation`,
`derive_public_key`), one-time address generation, and key image computation.
Follow the same CGo pattern used by the MLX backend in `go-ai`.
## Phase 3 -- P2P Levin Protocol (Planned)
Implement the Levin binary protocol in `p2p/` for peer-to-peer communication.
Handshake, ping, timed sync, and block/transaction relay. Integrate with
`go-p2p` for connection management.
## Phase 4 -- RPC Layer (Planned)
Implement `rpc/` with daemon JSON-RPC (get_block, get_transaction, submit_block)
and wallet JSON-RPC (transfer, get_balance, get_address). Provide both client
and server implementations.
## Phase 5 -- Chain Storage and Validation (Planned)
Implement `chain/` with blockchain storage (using `go-store` for persistence),
block validation, transaction verification, and mempool management. UTXO set
tracking with output index.
## Phase 6 -- Wallet Core (Planned)
Implement `wallet/` with key management, output scanning, transaction
construction, and balance calculation. Deterministic key derivation from seed
phrases. Support for all address types.
## Phase 7 -- Consensus Rules (Planned)
Implement `consensus/` with hardfork-aware block reward calculation, fee
policy enforcement, and full block/transaction validation rules per hardfork
version.
## Phase 8 -- Mining (Planned)
PoW mining support with stratum protocol client. PoS staking with kernel
hash computation and coinstake transaction construction.
---
## Known Limitations
**No wire serialisation.** Block and transaction types are defined as Go structs
but cannot yet be serialised to or deserialised from the CryptoNote binary
format. This means the types cannot be used to parse real chain data until
Phase 1 is complete.
**No cryptographic operations.** Key derivation, ring signatures, bulletproofs,
and all other cryptographic primitives are deferred to Phase 2. Address
encoding/decoding works but key generation and output scanning are not possible.
**Base58 uses math/big.** The CryptoNote base58 implementation converts each
8-byte block via `big.Int` arithmetic. This is correct but not optimised for
high-throughput scenarios. A future phase may replace this with a lookup-table
approach if profiling identifies it as a bottleneck.
**Difficulty coverage at 81%.** The window-capping branch in `NextDifficulty()`
that limits the window to `BlocksCount` (735) entries is not fully exercised by
the current test suite. Adding test vectors with 1,000+ block entries would
cover this path.
**Types coverage at 73.4%.** Unexported base58 helper functions have branches
that are exercised indirectly through the public API but are not fully reached
by the current test vectors. Additional edge-case address strings would improve
coverage.
**Future forks are placeholders.** HF3 through HF6 are defined with activation
height 999,999,999 on mainnet. These heights will be updated when each fork is
scheduled for activation on the live network.