BOLT9.hs (24124B)
1 {-# OPTIONS_HADDOCK prune #-} 2 {-# LANGUAGE BangPatterns #-} 3 {-# LANGUAGE DeriveGeneric #-} 4 5 -- | 6 -- Module: Lightning.Protocol.BOLT9 7 -- Copyright: (c) 2025 Jared Tobin 8 -- License: MIT 9 -- Maintainer: Jared Tobin <jared@ppad.tech> 10 -- 11 -- Feature flags for the Lightning Network, per 12 -- [BOLT #9](https://github.com/lightning/bolts/blob/master/09-features.md). 13 -- 14 -- A feature vector is a big-endian bit field. Features are assigned 15 -- pairs of bits: setting the even bit means the feature is required, 16 -- setting the odd bit means it is optional (/it's ok to be odd/). 17 -- 18 -- The examples below assume: 19 -- 20 -- >>> :set -XOverloadedStrings 21 -- >>> import Lightning.Protocol.BOLT9 22 -- 23 -- Build a vector, check it before sending it, and render it: 24 -- 25 -- >>> let fv = set_feature_with_deps OptionZeroconf Optional empty 26 -- >>> list_features fv 27 -- [(OptionScidAlias,Optional),(OptionZeroconf,Optional)] 28 -- >>> validate_local InitContext fv 29 -- Right () 30 -- >>> render fv 31 -- "\b\128\NUL\NUL\NUL\NUL\NUL" 32 -- 33 -- Check a vector received from a peer: 34 -- 35 -- >>> validate_remote InitContext (parse "\DLE\NUL\NUL") 36 -- Left (UnknownBit 20 :| []) 37 -- >>> validate_remote InitContext (parse "\STX\NUL\NUL") 38 -- Right () 39 40 module Lightning.Protocol.BOLT9 ( 41 -- * Feature vectors 42 FeatureVector 43 , parse 44 , render 45 , empty 46 , union 47 48 -- * Bits 49 , set_bit 50 , clear_bit 51 , test_bit 52 , set_bits 53 54 -- * Known features 55 , Feature(..) 56 , known_features 57 , feature_by_bit 58 , feature_bit 59 , feature_name 60 , feature_contexts 61 , feature_dependencies 62 , feature_assumed 63 64 -- * Feature operations 65 , FeatureLevel(..) 66 , set_feature 67 , set_feature_with_deps 68 , clear_feature 69 , test_feature 70 , list_features 71 72 -- * Validation 73 , Context(..) 74 , ValidationError(..) 75 , validate_local 76 , validate_remote 77 78 -- * Channel types 79 , ChannelType(..) 80 , BasicChannelType(..) 81 , channel_type 82 , channel_type_features 83 ) where 84 85 import Control.DeepSeq (NFData(..)) 86 import qualified Data.Bits as B 87 import Data.ByteString (ByteString) 88 import qualified Data.ByteString as BS 89 import Data.List (find) 90 import Data.List.NonEmpty (NonEmpty(..)) 91 import Data.Maybe (isNothing) 92 import Data.Word (Word8) 93 import GHC.Generics (Generic) 94 95 -- feature vectors ----------------------------------------------------------- 96 97 -- | A feature vector. 98 -- 99 -- Bit 0 is the least significant bit of the last byte. A vector 100 -- produced by 'parse' keeps its bytes exactly, so 'render' gives 101 -- them back unchanged (signatures over gossip messages cover them). 102 -- Every other operation produces a minimally-encoded vector, i.e. 103 -- one without leading zero bytes. 104 -- 105 -- Equality ignores leading zero bytes. 106 -- 107 -- >>> parse "\NUL\STX" == parse "\STX" 108 -- True 109 -- >>> set_bit 1 empty 110 -- parse "\STX" 111 newtype FeatureVector = FeatureVector ByteString 112 113 instance Eq FeatureVector where 114 FeatureVector a == FeatureVector b = strip a == strip b 115 116 instance Show FeatureVector where 117 showsPrec d (FeatureVector bs) = showParen (d > 10) $ 118 showString "parse " . showsPrec 11 bs 119 120 instance NFData FeatureVector where 121 rnf (FeatureVector bs) = rnf bs 122 123 -- | Parse a feature vector from its wire bytes. Every byte string is a 124 -- valid feature vector. 125 -- 126 -- >>> test_bit 9 (parse "\STX\NUL") 127 -- True 128 parse :: ByteString -> FeatureVector 129 parse = FeatureVector 130 {-# INLINE parse #-} 131 132 -- | The wire bytes of a feature vector: the original bytes of a vector 133 -- produced by 'parse', and the minimal encoding of any other. 134 -- 135 -- >>> render (parse "\NUL\STX") 136 -- "\NUL\STX" 137 -- >>> render (union (parse "\NUL\STX") empty) 138 -- "\STX" 139 render :: FeatureVector -> ByteString 140 render (FeatureVector bs) = bs 141 {-# INLINE render #-} 142 143 -- | The empty feature vector. 144 -- 145 -- >>> render empty 146 -- "" 147 empty :: FeatureVector 148 empty = FeatureVector BS.empty 149 150 -- | The bitwise OR of two feature vectors. 151 -- 152 -- BOLT #1 requires the receiver of an @init@ message to combine its 153 -- @globalfeatures@ and @features@ fields this way. 154 -- 155 -- >>> set_bits (union (parse "\STX") (parse "\SOH\NUL")) 156 -- [1,8] 157 union :: FeatureVector -> FeatureVector -> FeatureVector 158 union (FeatureVector a) (FeatureVector b) = 159 FeatureVector (combine (B..|.) a b) 160 161 -- bits ---------------------------------------------------------------------- 162 163 -- | Set the bit at the given index. Negative indices are ignored. 164 -- 165 -- >>> render (set_bit 9 empty) 166 -- "\STX\NUL" 167 set_bit :: Int -> FeatureVector -> FeatureVector 168 set_bit !i (FeatureVector bs) 169 | i < 0 = FeatureVector (strip bs) 170 | otherwise = FeatureVector (combine (B..|.) bs (single i)) 171 172 -- | Clear the bit at the given index. Negative indices are ignored. 173 -- 174 -- >>> render (clear_bit 9 (parse "\STX\SOH")) 175 -- "\SOH" 176 clear_bit :: Int -> FeatureVector -> FeatureVector 177 clear_bit !i (FeatureVector bs) 178 | i < 0 || i `quot` 8 >= BS.length s = FeatureVector s 179 | otherwise = FeatureVector (combine clr s (single i)) 180 where 181 s = strip bs 182 clr x y = x B..&. B.complement y 183 184 -- | Test the bit at the given index. Negative indices are never set. 185 -- 186 -- >>> test_bit 9 (parse "\STX\NUL") 187 -- True 188 -- >>> test_bit 8 (parse "\STX\NUL") 189 -- False 190 test_bit :: Int -> FeatureVector -> Bool 191 test_bit !i (FeatureVector bs) 192 | i < 0 || q >= len = False 193 | otherwise = B.testBit (BS.index bs (len - 1 - q)) r 194 where 195 len = BS.length bs 196 (q, r) = i `quotRem` 8 197 198 -- | The indices of all set bits, in ascending order. 199 -- 200 -- >>> set_bits (parse "\STX\NUL\SOH") 201 -- [0,17] 202 set_bits :: FeatureVector -> [Int] 203 set_bits (FeatureVector bs) = go 0 204 where 205 !len = BS.length bs 206 go !q 207 | q >= len = [] 208 | otherwise = 209 let !w = BS.index bs (len - 1 - q) 210 in [q * 8 + r | r <- [0 .. 7], B.testBit w r] ++ go (q + 1) 211 212 -- Drop leading zero bytes. 213 strip :: ByteString -> ByteString 214 strip = BS.dropWhile (== 0) 215 {-# INLINE strip #-} 216 217 -- The minimal encoding of a vector with only bit i set (i >= 0). 218 single :: Int -> ByteString 219 single i = BS.cons (B.bit r) (BS.replicate q 0) 220 where 221 (q, r) = i `quotRem` 8 222 223 -- Combine two encodings bytewise, aligned at their last bytes (the 224 -- shorter one padded with leading zeros), and strip the result. 225 combine 226 :: (Word8 -> Word8 -> Word8) -> ByteString -> ByteString -> ByteString 227 combine f a b = strip (fst (BS.unfoldrN n step 0)) 228 where 229 !la = BS.length a 230 !lb = BS.length b 231 !n = max la lb 232 byte s ls k 233 | k < n - ls = 0 234 | otherwise = BS.index s (k - n + ls) 235 step !k = Just (f (byte a la k) (byte b lb k), k + 1) 236 237 -- known features ------------------------------------------------------------ 238 239 -- | The features assigned in the BOLT #9 table. 240 data Feature 241 = OptionDataLossProtect -- ^ 0/1 @option_data_loss_protect@ 242 | OptionUpfrontShutdownScript -- ^ 4/5 @option_upfront_shutdown_script@ 243 | GossipQueries -- ^ 6/7 @gossip_queries@ 244 | VarOnionOptin -- ^ 8/9 @var_onion_optin@ 245 | GossipQueriesEx -- ^ 10/11 @gossip_queries_ex@ 246 | OptionStaticRemotekey -- ^ 12/13 @option_static_remotekey@ 247 | PaymentSecret -- ^ 14/15 @payment_secret@ 248 | BasicMpp -- ^ 16/17 @basic_mpp@ 249 | OptionSupportLargeChannel -- ^ 18/19 @option_support_large_channel@ 250 | OptionAnchors -- ^ 22/23 @option_anchors@ 251 | OptionRouteBlinding -- ^ 24/25 @option_route_blinding@ 252 | OptionShutdownAnysegwit -- ^ 26/27 @option_shutdown_anysegwit@ 253 | OptionDualFund -- ^ 28/29 @option_dual_fund@ 254 | OptionQuiesce -- ^ 34/35 @option_quiesce@ 255 | OptionAttributionData -- ^ 36/37 @option_attribution_data@ 256 | OptionOnionMessages -- ^ 38/39 @option_onion_messages@ 257 | ZeroFeeCommitments -- ^ 40/41 @zero_fee_commitments@ 258 | OptionProvideStorage -- ^ 42/43 @option_provide_storage@ 259 | OptionChannelType -- ^ 44/45 @option_channel_type@ 260 | OptionScidAlias -- ^ 46/47 @option_scid_alias@ 261 | OptionPaymentMetadata -- ^ 48/49 @option_payment_metadata@ 262 | OptionZeroconf -- ^ 50/51 @option_zeroconf@ 263 | OptionSimpleClose -- ^ 60/61 @option_simple_close@ 264 | OptionSplice -- ^ 62/63 @option_splice@ 265 | OptionOnionMessagesOnlyChannels 266 -- ^ 66/67 @option_onion_messages_only_channels@ 267 deriving (Eq, Ord, Show, Generic) 268 269 instance NFData Feature 270 271 -- | All known features, in bit order. 272 -- 273 -- >>> length known_features 274 -- 25 275 known_features :: [Feature] 276 known_features = [ 277 OptionDataLossProtect 278 , OptionUpfrontShutdownScript 279 , GossipQueries 280 , VarOnionOptin 281 , GossipQueriesEx 282 , OptionStaticRemotekey 283 , PaymentSecret 284 , BasicMpp 285 , OptionSupportLargeChannel 286 , OptionAnchors 287 , OptionRouteBlinding 288 , OptionShutdownAnysegwit 289 , OptionDualFund 290 , OptionQuiesce 291 , OptionAttributionData 292 , OptionOnionMessages 293 , ZeroFeeCommitments 294 , OptionProvideStorage 295 , OptionChannelType 296 , OptionScidAlias 297 , OptionPaymentMetadata 298 , OptionZeroconf 299 , OptionSimpleClose 300 , OptionSplice 301 , OptionOnionMessagesOnlyChannels 302 ] 303 304 -- A row of the BOLT #9 table. 305 data Entry = Entry { 306 e_bit :: !Int 307 , e_name :: !String 308 , e_contexts :: ![Context] 309 , e_deps :: ![Feature] 310 , e_assumed :: !Bool 311 } 312 313 entry :: Feature -> Entry 314 entry f = case f of 315 OptionDataLossProtect -> 316 Entry 0 "option_data_loss_protect" [] [] True 317 OptionUpfrontShutdownScript -> 318 Entry 4 "option_upfront_shutdown_script" _IN [] False 319 GossipQueries -> 320 Entry 6 "gossip_queries" [] [] False 321 VarOnionOptin -> 322 Entry 8 "var_onion_optin" [] [] True 323 GossipQueriesEx -> 324 Entry 10 "gossip_queries_ex" _IN [] False 325 OptionStaticRemotekey -> 326 Entry 12 "option_static_remotekey" [] [] True 327 PaymentSecret -> 328 Entry 14 "payment_secret" [] [] True 329 BasicMpp -> 330 Entry 16 "basic_mpp" _IN9 [PaymentSecret] False 331 OptionSupportLargeChannel -> 332 Entry 18 "option_support_large_channel" _IN [] False 333 OptionAnchors -> 334 Entry 22 "option_anchors" _INT [] False 335 OptionRouteBlinding -> 336 Entry 24 "option_route_blinding" _IN9 [] False 337 OptionShutdownAnysegwit -> 338 Entry 26 "option_shutdown_anysegwit" _IN [] False 339 OptionDualFund -> 340 Entry 28 "option_dual_fund" _IN [] False 341 OptionQuiesce -> 342 Entry 34 "option_quiesce" _IN [] False 343 OptionAttributionData -> 344 Entry 36 "option_attribution_data" _IN9 [] False 345 OptionOnionMessages -> 346 Entry 38 "option_onion_messages" _IN [] False 347 ZeroFeeCommitments -> 348 Entry 40 "zero_fee_commitments" _IN [OptionChannelType] False 349 OptionProvideStorage -> 350 Entry 42 "option_provide_storage" _IN [] False 351 OptionChannelType -> 352 Entry 44 "option_channel_type" [] [] True 353 OptionScidAlias -> 354 Entry 46 "option_scid_alias" _INT [] False 355 OptionPaymentMetadata -> 356 Entry 48 "option_payment_metadata" [InvoiceContext] [] False 357 OptionZeroconf -> 358 Entry 50 "option_zeroconf" _INT [OptionScidAlias] False 359 OptionSimpleClose -> 360 Entry 60 "option_simple_close" _IN [OptionShutdownAnysegwit] False 361 OptionSplice -> 362 Entry 62 "option_splice" _IN [] False 363 OptionOnionMessagesOnlyChannels -> 364 Entry 66 "option_onion_messages_only_channels" _IN 365 [OptionOnionMessages] False 366 where 367 _IN = [InitContext, NodeContext] 368 _IN9 = [InitContext, NodeContext, InvoiceContext] 369 _INT = [InitContext, NodeContext, ChannelTypeContext] 370 371 -- | The feature that a bit (even or odd) belongs to, if any. 372 -- 373 -- >>> feature_by_bit 16 374 -- Just BasicMpp 375 -- >>> feature_by_bit 17 376 -- Just BasicMpp 377 -- >>> feature_by_bit 20 378 -- Nothing 379 feature_by_bit :: Int -> Maybe Feature 380 feature_by_bit !i 381 | i < 0 || i > max_known_bit = Nothing 382 | otherwise = find ((== base) . feature_bit) known_features 383 where 384 base = i - i `rem` 2 385 386 -- The highest bit assigned to any known feature. 387 max_known_bit :: Int 388 max_known_bit = foldr (max . (+ 1) . feature_bit) 0 known_features 389 390 -- | A feature's even (required) bit. Its odd (optional) bit is the 391 -- next one up. 392 -- 393 -- >>> feature_bit BasicMpp 394 -- 16 395 feature_bit :: Feature -> Int 396 feature_bit = e_bit . entry 397 398 -- | A feature's name in the BOLT #9 table. 399 -- 400 -- >>> feature_name BasicMpp 401 -- "basic_mpp" 402 feature_name :: Feature -> String 403 feature_name = e_name . entry 404 405 -- | The contexts the BOLT #9 table lists for a feature, in table order. 406 -- The list is empty for ASSUMED features and for 'GossipQueries'. 407 -- 408 -- >>> feature_contexts BasicMpp 409 -- [InitContext,NodeContext,InvoiceContext] 410 -- >>> feature_contexts PaymentSecret 411 -- [] 412 feature_contexts :: Feature -> [Context] 413 feature_contexts = e_contexts . entry 414 415 -- | A feature's direct dependencies. 416 -- 417 -- >>> feature_dependencies OptionZeroconf 418 -- [OptionScidAlias] 419 feature_dependencies :: Feature -> [Feature] 420 feature_dependencies = e_deps . entry 421 422 -- | Whether BOLT #9 marks a feature ASSUMED, i.e. supported by all 423 -- nodes. 424 -- 425 -- >>> feature_assumed PaymentSecret 426 -- True 427 feature_assumed :: Feature -> Bool 428 feature_assumed = e_assumed . entry 429 430 -- feature operations -------------------------------------------------------- 431 432 -- | The level at which a feature is set. 433 data FeatureLevel 434 = Required -- ^ the even bit is set 435 | Optional -- ^ the odd bit is set 436 deriving (Eq, Ord, Show, Generic) 437 438 instance NFData FeatureLevel 439 440 level_bit :: Feature -> FeatureLevel -> Int 441 level_bit f Required = feature_bit f 442 level_bit f Optional = feature_bit f + 1 443 {-# INLINE level_bit #-} 444 445 -- | Set a feature at the given level, clearing the other bit of its 446 -- pair. 447 -- 448 -- >>> set_bits (set_feature BasicMpp Optional empty) 449 -- [17] 450 -- >>> set_bits (set_feature BasicMpp Required (set_bit 17 empty)) 451 -- [16] 452 set_feature :: Feature -> FeatureLevel -> FeatureVector -> FeatureVector 453 set_feature f l = set_bit (level_bit f l) . clear_bit (level_bit f other) 454 where 455 other = case l of 456 Required -> Optional 457 Optional -> Required 458 459 -- | Set a feature at the given level, together with its transitive 460 -- dependencies (ASSUMED ones included). Dependencies that are not 461 -- yet set are set at the same level; those already set keep theirs. 462 -- 463 -- >>> list_features (set_feature_with_deps BasicMpp Optional empty) 464 -- [(PaymentSecret,Optional),(BasicMpp,Optional)] 465 set_feature_with_deps 466 :: Feature -> FeatureLevel -> FeatureVector -> FeatureVector 467 set_feature_with_deps f l fv = 468 foldr ensure (set_feature f l fv) (feature_dependencies f) 469 where 470 ensure d acc = 471 let acc' = case test_feature d acc of 472 Just _ -> acc 473 Nothing -> set_feature d l acc 474 in foldr ensure acc' (feature_dependencies d) 475 476 -- | Clear both bits of a feature. 477 -- 478 -- >>> clear_feature BasicMpp (set_feature BasicMpp Optional empty) 479 -- parse "" 480 clear_feature :: Feature -> FeatureVector -> FeatureVector 481 clear_feature f = 482 clear_bit (level_bit f Required) . clear_bit (level_bit f Optional) 483 484 -- | The level at which a feature is set, if it is. 485 -- 486 -- A feature with both bits set is 'Required', as BOLT #9 directs the 487 -- receiver to treat it. 488 -- 489 -- >>> test_feature BasicMpp (set_bit 17 empty) 490 -- Just Optional 491 -- >>> test_feature BasicMpp (set_bit 16 (set_bit 17 empty)) 492 -- Just Required 493 -- >>> test_feature BasicMpp empty 494 -- Nothing 495 test_feature :: Feature -> FeatureVector -> Maybe FeatureLevel 496 test_feature f fv 497 | test_bit (level_bit f Required) fv = Just Required 498 | test_bit (level_bit f Optional) fv = Just Optional 499 | otherwise = Nothing 500 501 -- | The known features set in a vector, in bit order. 502 -- 503 -- >>> list_features (parse "\SOH\128\NUL") 504 -- [(PaymentSecret,Optional),(BasicMpp,Required)] 505 list_features :: FeatureVector -> [(Feature, FeatureLevel)] 506 list_features fv = 507 [(f, l) | f <- known_features, Just l <- [test_feature f fv]] 508 509 -- validation ---------------------------------------------------------------- 510 511 -- | A field in which feature bits are presented: the values of the 512 -- Context column of the BOLT #9 table. 513 -- 514 -- The table's @C-@ and @C+@ are not further contexts. They mark a 515 -- feature presented in @channel_announcement@ as always optional or 516 -- always required. No feature at the implemented spec revision is 517 -- presented in @channel_announcement@ in any form. 518 data Context 519 = InitContext -- ^ @I@: the @init@ message 520 | NodeContext -- ^ @N@: @node_announcement@ 521 | ChannelContext -- ^ @C@: @channel_announcement@ 522 | InvoiceContext -- ^ @9@: BOLT #11 invoices 523 | BlindedContext -- ^ @B@: @allowed_features@ of a blinded path 524 | ChannelTypeContext -- ^ @T@: the @channel_type@ field 525 deriving (Eq, Ord, Show, Generic) 526 527 instance NFData Context 528 529 -- | A rule a feature vector breaks. 530 data ValidationError 531 = UnknownBit {-# UNPACK #-} !Int 532 -- ^ a bit belonging to no known feature is set 533 | BothBitsSet !Feature 534 -- ^ both bits of a feature are set 535 | ContextNotAllowed !Feature !Context 536 -- ^ a feature is set in a context that doesn't present it 537 | MissingDependency !Feature !Feature 538 -- ^ a set feature (first) lacks a dependency (second) 539 | InvalidChannelType 540 -- ^ a @channel_type@ is not a type that BOLT #2 defines 541 deriving (Eq, Show, Generic) 542 543 instance NFData ValidationError 544 545 -- | Validate a feature vector that we're about to send in the given 546 -- context, per the origin requirements of BOLT #9 and BOLT #1. 547 -- 548 -- For 'ChannelTypeContext', the vector must be a channel type that 549 -- BOLT #2 defines (see 'channel_type'). For every other context, 550 -- checks that: 551 -- 552 -- * no bit outside the known features is set; 553 -- * no feature has both bits set; 554 -- * each set feature is presented in the context. A feature with an 555 -- empty Context column (the ASSUMED features and 'GossipQueries') 556 -- is accepted in 'InitContext', 'NodeContext' and 557 -- 'InvoiceContext', where deployed nodes still present it; 558 -- * each set feature's dependencies are set. A dependency on an 559 -- ASSUMED feature counts as met even when its bits are clear. 560 -- 561 -- Errors are reported in that order. No known feature is presented 562 -- in 'ChannelContext' or 'BlindedContext', so only the empty vector 563 -- passes there (as BOLT #4 requires of @allowed_features@). 564 -- 565 -- >>> validate_local InitContext (set_feature OptionZeroconf Optional empty) 566 -- Left (MissingDependency OptionZeroconf OptionScidAlias :| []) 567 -- >>> validate_local InitContext (set_feature BasicMpp Optional empty) 568 -- Right () 569 -- >>> validate_local InitContext (set_bit 101 empty) 570 -- Left (UnknownBit 101 :| []) 571 validate_local 572 :: Context -> FeatureVector -> Either (NonEmpty ValidationError) () 573 validate_local ctx fv = to_either $ case ctx of 574 ChannelTypeContext -> channel_type_errors fv 575 _ -> unknown_bits (const True) fv 576 ++ both_bits_errors fv 577 ++ context_errors ctx fv 578 ++ dependency_errors fv 579 580 -- | Validate a feature vector received in the given context, per the 581 -- receiver requirements for that context: 582 -- 583 -- * 'InitContext' (BOLT #1) and 'InvoiceContext' (BOLT #11): no 584 -- unknown even bit is set, and each set feature's dependencies are 585 -- set (ASSUMED dependencies count as met). 586 -- * 'NodeContext' and 'ChannelContext' (BOLT #7): no unknown even 587 -- bit is set. A failure here means the node or channel must not be 588 -- routed through; the announcement itself is still valid. 589 -- * 'BlindedContext' (BOLT #4): no unknown bit is set, odd or even. 590 -- * 'ChannelTypeContext' (BOLT #2): the vector is a defined channel 591 -- type (see 'channel_type'). 592 -- 593 -- Unknown odd bits are otherwise ignored. A feature with both bits 594 -- set is not an error; it counts as 'Required' (see 'test_feature'). 595 -- Nor is a known feature outside its listed contexts, since that 596 -- rule binds only the sender. 597 -- 598 -- >>> validate_remote InitContext (set_bit 101 empty) 599 -- Right () 600 -- >>> validate_remote InitContext (set_bit 100 empty) 601 -- Left (UnknownBit 100 :| []) 602 -- >>> validate_remote BlindedContext (set_bit 101 empty) 603 -- Left (UnknownBit 101 :| []) 604 validate_remote 605 :: Context -> FeatureVector -> Either (NonEmpty ValidationError) () 606 validate_remote ctx fv = to_either $ case ctx of 607 InitContext -> unknown_even ++ dependency_errors fv 608 NodeContext -> unknown_even 609 ChannelContext -> unknown_even 610 InvoiceContext -> unknown_even ++ dependency_errors fv 611 BlindedContext -> unknown_bits (const True) fv 612 ChannelTypeContext -> channel_type_errors fv 613 where 614 unknown_even = unknown_bits even fv 615 616 to_either :: [e] -> Either (NonEmpty e) () 617 to_either [] = Right () 618 to_either (e : es) = Left (e :| es) 619 620 -- Unknown set bits satisfying the predicate. 621 unknown_bits :: (Int -> Bool) -> FeatureVector -> [ValidationError] 622 unknown_bits p fv = 623 [ UnknownBit i 624 | i <- set_bits fv, p i, isNothing (feature_by_bit i) ] 625 626 both_bits_errors :: FeatureVector -> [ValidationError] 627 both_bits_errors fv = 628 [ BothBitsSet f 629 | f <- known_features 630 , test_bit (level_bit f Required) fv 631 , test_bit (level_bit f Optional) fv ] 632 633 context_errors :: Context -> FeatureVector -> [ValidationError] 634 context_errors ctx fv = 635 [ ContextNotAllowed f ctx 636 | (f, _) <- list_features fv, not (presented f) ] 637 where 638 presented f = case feature_contexts f of 639 [] -> ctx `elem` [InitContext, NodeContext, InvoiceContext] 640 cs -> ctx `elem` cs 641 642 dependency_errors :: FeatureVector -> [ValidationError] 643 dependency_errors fv = 644 [ MissingDependency f d 645 | (f, _) <- list_features fv 646 , d <- feature_dependencies f 647 , not (feature_assumed d) 648 , isNothing (test_feature d fv) ] 649 650 channel_type_errors :: FeatureVector -> [ValidationError] 651 channel_type_errors fv = case channel_type fv of 652 Nothing -> [InvalidChannelType] 653 Just _ -> [] 654 655 -- channel types ------------------------------------------------------------- 656 657 -- | The basic channel types of BOLT #2. 658 data BasicChannelType 659 = BasicStaticRemotekey 660 -- ^ 'OptionStaticRemotekey' (bit 12) 661 | BasicAnchors 662 -- ^ 'OptionAnchors' and 'OptionStaticRemotekey' (bits 22 and 12) 663 | BasicZeroFeeCommitments 664 -- ^ 'ZeroFeeCommitments' (bit 40) 665 deriving (Eq, Ord, Show, Generic) 666 667 instance NFData BasicChannelType 668 669 -- | A channel type, per BOLT #2: a basic type plus any of the 670 -- 'OptionScidAlias' and 'OptionZeroconf' variations. 671 -- 672 -- Channel types are an enumeration that reuses even feature bits; 673 -- they aren't subject to the dependency or context rules for 674 -- feature vectors. BOLT #2 also forbids 'OptionScidAlias' in the 675 -- channel type of a channel to be announced, which needs the 676 -- @announce_channel@ flag to check. 677 data ChannelType = ChannelType { 678 ct_basic :: !BasicChannelType 679 , ct_scid_alias :: !Bool 680 , ct_zeroconf :: !Bool 681 } 682 deriving (Eq, Show, Generic) 683 684 instance NFData ChannelType 685 686 -- | The channel type that a @channel_type@ vector encodes, if it is a 687 -- defined one. Leading zero bytes are ignored. 688 -- 689 -- >>> let zeroconf = ChannelType BasicStaticRemotekey False True 690 -- >>> channel_type (parse "\EOT\NUL\NUL\NUL\NUL\DLE\NUL") == Just zeroconf 691 -- True 692 -- >>> channel_type (set_bit 13 empty) 693 -- Nothing 694 channel_type :: FeatureVector -> Maybe ChannelType 695 channel_type fv = find ((== fv) . channel_type_features) channel_types 696 697 -- All defined channel types. 698 channel_types :: [ChannelType] 699 channel_types = 700 [ ChannelType b s z 701 | b <- [BasicStaticRemotekey, BasicAnchors, BasicZeroFeeCommitments] 702 , s <- [False, True] 703 , z <- [False, True] ] 704 705 -- | The @channel_type@ vector for a channel type. 706 -- 707 -- >>> let anchors = ChannelType BasicAnchors False False 708 -- >>> render (channel_type_features anchors) 709 -- "@\DLE\NUL" 710 channel_type_features :: ChannelType -> FeatureVector 711 channel_type_features (ChannelType b s z) = 712 foldr (\f -> set_feature f Required) empty 713 (basic b ++ [OptionScidAlias | s] ++ [OptionZeroconf | z]) 714 where 715 basic BasicStaticRemotekey = [OptionStaticRemotekey] 716 basic BasicAnchors = [OptionAnchors, OptionStaticRemotekey] 717 basic BasicZeroFeeCommitments = [ZeroFeeCommitments]