ARCH1.md (3515B)
1 # ARCH1: High-level architecture for ppad-bolt9 2 3 ## Goals 4 5 - Represent BOLT 9 feature bits with strong types and safe invariants. 6 - Provide total parsing, validation, and construction of feature vectors. 7 - Enforce dependencies, context restrictions, and optional/required pairing. 8 - Keep the core API small and stable; push policy to explicit validators. 9 10 ## Core concepts 11 12 - Feature bit: numbered bit (0-based) with optional/required pairing 13 (odd/optional, even/required). 14 - Feature pair: optional bit N and required bit N-1 (for odd N). 15 - Context: where a feature vector appears (init, node_announcement, 16 channel_announcement, invoice, blinded path, channel_type). 17 - Feature vector: packed bitset with context-specific restrictions. 18 19 ## Module layout (proposed) 20 21 - `Lightning.Protocol.BOLT9` 22 - Public API: feature types, parsing, rendering, validation helpers. 23 - Re-export safe constructors and lookup functions. 24 25 - `Lightning.Protocol.BOLT9.Feature` 26 - Enumerates known features from 09-features.md. 27 - Tables: bit number, name, contexts, dependencies, assumed. 28 - Total lookup: bit -> known feature info (Maybe). 29 30 - `Lightning.Protocol.BOLT9.Context` 31 - ADT for contexts: Init, NodeAnn, ChanAnn, Invoice, Blinded, ChanType. 32 - Helpers for context-specific rules (C-, C+ handling). 33 34 - `Lightning.Protocol.BOLT9.Vector` 35 - Packed representation of feature bits (ByteString). 36 - Functions: empty, set, clear, member, union, normalize. 37 - Safe constructors for optional vs required bits. 38 39 - `Lightning.Protocol.BOLT9.Validate` 40 - Validation of a vector against: 41 - context restrictions 42 - optional/required conflict 43 - dependency closure 44 - must-not-set unknown bits (if required by caller) 45 - Validation of remote vectors for unknown bits handling. 46 47 ## Data model notes 48 49 - Use newtypes for bit indices and for optional vs required bits. 50 - Encode odd/even constraints in constructors (smart constructors). 51 - Store dependencies as feature pairs (logical dependencies) rather than 52 raw bit numbers, then expand to actual bits for validation. 53 54 ## Invariants to enforce 55 56 - No vector may contain both optional and required bits for a feature. 57 - Context restrictions are respected: 58 - Some bits only in Init/Node/Chan/Invoice/Blinded/ChanType. 59 - C-: only optional (odd bit) allowed in channel_announcement. 60 - C+: only required (even bit) allowed in channel_announcement. 61 - Known dependencies are transitively satisfied. 62 - Unknown bits may be allowed but must be treated as mandatory if 63 both optional and required are set (receiver rule). 64 65 ## API shape 66 67 - Parsing and rendering: 68 - parseFeatureVector :: ByteString -> Either Error FeatureVector 69 - renderFeatureVector :: FeatureVector -> ByteString 70 71 - Construction: 72 - emptyVector 73 - setOptional :: Feature -> FeatureVector -> FeatureVector 74 - setRequired :: Feature -> FeatureVector -> FeatureVector 75 76 - Validation: 77 - validateLocal :: Context -> FeatureVector -> Either Error Validated 78 - validateRemote :: Context -> FeatureVector -> Either Error Validated 79 80 ## Validation policy 81 82 - Local validation is strict: unknown bits are rejected by default. 83 - Remote validation is configurable: 84 - accept unknown optional bits 85 - reject unknown required bits 86 - configurable fallback for unknown pairs 87 88 ## Testing strategy 89 90 - Unit tests for all known features (bit numbers, contexts, deps). 91 - Property tests: 92 - dependencies are closed under set operations 93 - no constructor can produce invalid parity 94 - render/parse roundtrip 95