From 89a95b3b58dda394c50969bef6bf6bb01bf20716 Mon Sep 17 00:00:00 2001 From: Jimmy Debe <91767824+jimstir@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:10:11 -0500 Subject: [PATCH 1/4] Update rln-relay.md --- waku/standards/core/17/rln-relay.md | 68 ++++++++--------------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/waku/standards/core/17/rln-relay.md b/waku/standards/core/17/rln-relay.md index 8645fffe6..78e0cd8cd 100644 --- a/waku/standards/core/17/rln-relay.md +++ b/waku/standards/core/17/rln-relay.md @@ -1,16 +1,15 @@ --- slug: 17 -title: 17/WAKU2-RLN-RELAY +title: 17/WAKU-RLN-RELAY name: Waku v2 RLN Relay status: draft tags: waku-core editor: Sanaz Taheri contributors: - - Oskar Thorén - - Aaryamann Challani + - Oskar Thorén --- -The `17/WAKU2-RLN-RELAY` protocol is an extension of `11/WAKU2-RELAY` which additionally provides spam protection using [Rate Limiting Nullifiers (RLN)](../../../../vac/32/rln-v1.md). +The `17/WAKU-RLN-RELAY` protocol is an extension of `11/WAKU-RELAY` which additionally provides spam protection using [Rate Limiting Nullifiers (RLN)](/spec/32). The security objective is to contain spam activity in a GossipSub network by enforcing a global messaging rate to all the peers. Peers that violate the messaging rate are considered spammers and their message is considered spam. @@ -32,11 +31,11 @@ We augment the [`11/WAKU2-RELAY`](/spec/11) protocol with a novel construct of [ The messaging rate is defined by the `period` which indicates how many messages can be sent in a given period. -We define an `epoch` as $\lceil$ `unix_time` / `period` $\rceil$. For example, if `unix_time` is `1644810116` and we set `period` to `30`, then `epoch` is $\lceil$`(unix_time/period)`$\rceil$ `= 54827003`. +We define an `epoch` as $$\lceil unix\\_time/period \rceil$$. For example, if `unix_time` is `1644810116` and we set `period` to `30`, then `epoch` is $$\lceil(unix\\_time/period)\rceil = 54827003$$. Note that `epoch` refers to epoch in RLN and not Unix epoch. This means a message can only be sent every period, where period is up to the application. See see section [Recommended System Parameters](#recommended-system-parameters) for some recommended ways to set a sensible `period` value depending on the application. Peers subscribed to a spam-protected `pubsubTopic` are only allowed to send one message per `epoch`. -The higher-level layers adopting `17/WAKU2-RLN-RELAY` MAY choose to enforce the messaging rate for `WakuMessages` with a specific `contentTopic` published on a `pubsubTopic`. +The higher-level layers adopting `17/WAKU-RLN-RELAY` MAY choose to enforce the messaging rate for `WakuMessages` with a specific `contentTopic` published on a `pubsubTopic`. @@ -57,7 +56,7 @@ The peer who has the secret key `sk` associated with a registered `pk` would be Note that `sk` is initially only known to its owning peer however, it may get exposed to other peers in case the owner attempts spamming the system i.e., sending more than one message per `epoch`. An overview of registration is illustrated in Figure 1. -![Figure 1: Registration.](./images/rln-relay.png) +![Figure 1: Registration.](../../../../rfcs/17/rln-relay.png) ## Publishing @@ -86,7 +85,7 @@ For more details about the proof generation check [RLN](/spec/32) The proof generation relies on the knowledge of two pieces of private information i.e., `sk` and `authPath`. The `authPath` is a subset of Merkle tree nodes by which a peer can prove the inclusion of its `pk` in the group. The proof generation also requires a set of public inputs which are: the Merkle tree root `merkle_root`, the current `epoch`, and the message for which the proof is going to be generated. -In `17/WAKU2-RLN-RELAY`, the message is the concatenation of `WakuMessage`'s `payload` filed and its `contentTopic` i.e., `payload||contentTopic`. +In `17/WAKU-RLN-RELAY`, the message is the concatenation of `WakuMessage`'s `payload` filed and its `contentTopic` i.e., `payload||contentTopic`. ## Group Synchronization @@ -94,9 +93,6 @@ Proof generation relies on the knowledge of Merkle tree root `merkle_root` and ` Getting access to the Merkle tree can be done in various ways. One way is that all the peers construct the tree locally. This can be done by listening to the registration and deletion events emitted by the membership contract. -Peers MUST update the local Merkle tree on a per-block basis. -This is discussed further in the [Merkle Root Validation](#merkle-root-validation) section. - Another approach for synchronizing the state of slashed `pk`s is to disseminate such information through a p2p GossipSub network to which all peers are subscribed. This is in addition to sending the deletion transaction to the membership contract. The benefit of an off-chain slashing is that it allows real-time removal of spammers as opposed to on-chain slashing in which peers get informed with a delay, @@ -109,31 +105,17 @@ The reason is that using an old root can allow inference about the index of the Upon the receipt of a PubSub message via [`11/WAKU2-RELAY`](/spec/11) protocol, the routing peer parses the `data` field as a `WakuMessage` and gets access to the `RateLimitProof` field. The peer then validates the `RateLimitProof` as explained next. -### Epoch Validation +**Epoch Validation** If the `epoch` attached to the message is more than `max_epoch_gap` apart from the routing peer's current `epoch` then the message is discarded and considered invalid. This is to prevent a newly registered peer from spamming the system by messaging for all the past epochs. `max_epoch_gap` is a system parameter for which we provide some recommendations in section [Recommended System Parameters](#recommended-system-parameters). -### Merkle Root Validation -The routing peers MUST check whether the provided Merkle root in the `RateLimitProof` is valid. -It can do so by maintaining a local set of valid Merkle roots, which consist of `acceptable_root_window_size` past roots. -These roots refer to the final state of the Merkle tree after a whole block consisting of group changes is processed. -The Merkle roots are updated on a per-block basis instead of a per-event basis. -This is done because if Merkle roots are updated on a per-event basis, some peers could send messages with a root that refers to a Merkle tree state that might get invalidated while the message is still propagating in the network, due to many registrations happening during this time frame. -By updating roots on a per-block basis instead, we will have only one root update per-block processed, regardless on how many registrations happened in a block, and peers will be able to successfully propagate messages in a time frame corresponding to roughly the size of the roots window times the block mining time. - -Atomic processing of the blocks are necessary so that even if the peer is unable to process one event, the previous roots remain valid, and can be used to generate valid RateLimitProof's. - -This also allows peers which are not well connected to the network to be able to send messages, accounting for network delay. -This network delay is related to the nature of asynchronous network conditions, which means that peers see membership changes asynchronously, and therefore may have differing local Merkle trees. -See [Recommended System Parameters](#recommended-system-parameters) on choosing an appropriate `acceptable_root_window_size`. - -### Proof Verification +**Proof Verification** The routing peers MUST check whether the zero-knowledge proof `proof` is valid. It does so by running the zk verification algorithm as explained in [RLN](/spec/32). If `proof` is invalid then the message is discarded. -### Spam detection +**Spam detection** To enable local spam detection and slashing, routing peers MUST record the `nullifier`, `share_x`, and `share_y` of incoming messages which are not discarded i.e., not found spam or with invalid proof or epoch. To spot spam messages, the peer checks whether a message with an identical `nullifier` has already been relayed. 1. If such a message exists and its `share_x` and `share_y` components are different from the incoming message, then slashing takes place. @@ -147,7 +129,7 @@ An overview of the routing procedure and slashing is provided in Figure 2. -![Figure 2: Publishing, Routing and Slashing workflow.](./images/rln-message-verification.png) +![Figure 2: Publishing, Routing and Slashing workflow.](../../../../rfcs/17/rln-message-verification.png) ------- @@ -171,11 +153,10 @@ message RateLimitProof { message WakuMessage { bytes payload = 1; - string content_topic = 2; - optional uint32 version = 3; - optional sint64 timestamp = 10; - optional bool ephemeral = 31; -+ optional bytes rate_limit_proof = 21; + string contentTopic = 2; + uint32 version = 3; + double timestamp = 4; ++ RateLimitProof rate_limit_proof = 21; } ``` @@ -200,16 +181,15 @@ The system parameters are summarized in the following table, and the recommended | Parameter | Description | | ----: |----------- | | `period` | the length of `epoch` in seconds | -| `staked_fund` | the amount of wei to be staked by peers at the registration | +| `staked_fund` | the amount of ether to be staked by peers at the registration | | `reward_portion` | the percentage of `staked_fund` to be rewarded to the slashers | | `max_epoch_gap` | the maximum allowed gap between the `epoch` of a routing peer and the incoming message | -| `acceptable_root_window_size` | The maximum number of past Merkle roots to store | ## Epoch Length A sensible value for the `period` depends on the application for which the spam protection is going to be used. For example, while the `period` of `1` second i.e., messaging rate of `1` per second, might be acceptable for a chat application, might be too low for communication among Ethereum network validators. One should look at the desired throughput of the application to decide on a proper `period` value. -In the proof of concept implementation of `17/WAKU2-RLN-RELAY` protocol which is available in [nim-waku](https://github.com/status-im/nim-waku), the `period` is set to `1` second. +In the proof of concept implementation of `17/WAKU-RLN-RELAY` protocol which is available in [nim-waku](https://github.com/status-im/nim-waku), the `period` is set to `1` second. Nevertheless, this value is also subject to change depending on user experience. ## Maximum Epoch Gap @@ -219,22 +199,10 @@ The value of `max_epoch_gap` can be measured based on the following factors. - Clock asynchrony `Clock_Asynchrony`: The maximum difference between the Unix epoch clocks perceived by network peers which can be due to clock drifts. With a reasonable approximation of the preceding values, one can set `max_epoch_gap` as -`max_epoch_gap` $= \lceil \frac{\text{Network Delay} + \text{Clock Asynchrony}}{\text{Epoch Length}}\rceil$ where `period` is the length of the `epoch` in seconds. +$$max\\_epoch\\_gap = \lceil \frac{\text{Network Delay} + \text{Clock Asynchrony}}{\text{Epoch Length}}\rceil$$ where `period` is the length of the `epoch` in seconds. `Network_Delay` and `Clock_Asynchrony` MUST have the same resolution as `period` . By this formulation, `max_epoch_gap` indeed measures the maximum number of `epoch`s that can elapse since a message gets routed from its origin to all the other peers in the network. -`acceptable_root_window_size` depends upon the underlying chain's average blocktime, `block_time` - -The lower bound for the `acceptable_root_window_size` SHOULD be set as $acceptable_root_window_size=(Network_Delay)/block_time$ - -`Network_Delay` MUST have the same resolution as `block_time`. - -By this formulation, `acceptable_root_window_size` will provide a lower bound of how many roots can be acceptable by a routing peer. - -The `acceptable_root_window_size` should indicate how many blocks may have been mined during the time it takes for a peer to receive a message. -This formula represents a lower bound of the number of acceptable roots. - - # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 5400b1157349ad48fa04920403764a36daa68ed9 Mon Sep 17 00:00:00 2001 From: Jimmy Debe <91767824+jimstir@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:18:56 -0500 Subject: [PATCH 2/4] Create single.html --- waku/standards/core/17/images/single.html | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 waku/standards/core/17/images/single.html diff --git a/waku/standards/core/17/images/single.html b/waku/standards/core/17/images/single.html new file mode 100644 index 000000000..b8b41d44f --- /dev/null +++ b/waku/standards/core/17/images/single.html @@ -0,0 +1,52 @@ +{{ define "main" }} +
+ {{ printf "# %s" .Params.title | markdownify }} + {{ if .Params.name }} + {{ printf "# %s" .Params.name | markdownify }} + {{ end }} + + {{ if eq .Params.status "raw" }} + + {{ end }} + {{ if eq .Params.status "draft" }} + + {{ end }} + {{ if eq .Params.status "stable" }} + + {{ end }} + {{ if eq .Params.status "deprecated" }} + + {{ end }} + {{ if eq .Params.status "retired" }} + + {{ end }} + +
    +
  • Status: {{ .Params.status | markdownify }}
  • +
  • Editor: {{ .Params.editor | markdownify }}
  • + {{ if .Params.contributors }} +
  • Contributors: + {{ range $index, $element := .Params.contributors }} + {{if $index}},{{end}} + {{ . | markdownify }} + {{ end }} +
  • + {{ end }} +
+ + {{- .Content -}} +
+{{ end }} + +{{ define "toc" }} + {{ partial "docs/toc" . }} + + + +{{ end }} From 39843595c7a6571a32199874174ad464c9be4b9d Mon Sep 17 00:00:00 2001 From: Jimmy Debe <91767824+jimstir@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:20:24 -0500 Subject: [PATCH 3/4] Create book.scss_50fc8c04e12a2f59027287995557ceff.content --- .../17/images/book.scss_50fc8c04e12a2f59027287995557ceff.content | 1 + 1 file changed, 1 insertion(+) create mode 100644 waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.content diff --git a/waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.content b/waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.content new file mode 100644 index 000000000..b33022a0d --- /dev/null +++ b/waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.content @@ -0,0 +1 @@ +:root{--gray-100:#f8f9fa;--gray-200:#e9ecef;--gray-500:#adb5bd;--color-link:#0055bb;--color-visited-link:#8440f1;--body-background:white;--body-font-color:black;--icon-filter:none;--hint-color-info:#6bf;--hint-color-warning:#fd6;--hint-color-danger:#f66}/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}.flex{display:flex}.flex-auto{flex:auto}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.hidden{display:none}input.toggle{height:0;width:0;overflow:hidden;opacity:0;position:absolute}.clearfix::after{content:"";display:table;clear:both}html{font-size:16px;scroll-behavior:smooth;touch-action:manipulation}body{min-width:20rem;color:var(--body-font-color);background:var(--body-background);letter-spacing:.33px;font-weight:400;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}body *{box-sizing:inherit}h1,h2,h3,h4,h5{font-weight:400}a{text-decoration:none;color:var(--color-link)}img{vertical-align:baseline}:focus{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}aside nav ul{padding:0;margin:0;list-style:none}aside nav ul li{margin:1em 0;position:relative}aside nav ul a{display:block}aside nav ul a:hover{opacity:.5}aside nav ul ul{padding-inline-start:1rem}ul.pagination{display:flex;justify-content:center;list-style-type:none}ul.pagination .page-item a{padding:1rem}.container{max-width:80rem;margin:0 auto}.book-icon{filter:var(--icon-filter)}.book-brand{margin-top:0}.book-brand img{height:1.5em;width:auto;vertical-align:middle;margin-inline-end:.5rem}.book-menu{flex:0 0 16rem;font-size:.875rem}.book-menu .book-menu-content{width:16rem;padding:1rem;background:var(--body-background);position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-menu a,.book-menu label{color:inherit;cursor:pointer;word-wrap:break-word}.book-menu a.active{color:var(--color-link)}.book-menu input.toggle+label+ul{display:none}.book-menu input.toggle:checked+label+ul{display:block}.book-section-flat{margin-bottom:2rem}.book-section-flat:not(:first-child){margin-top:2rem}.book-section-flat>a,.book-section-flat>span,.book-section-flat>label{font-weight:bolder}.book-section-flat>ul{padding-inline-start:0}.book-page{min-width:20rem;flex-grow:1;padding:1rem}.book-post{margin-bottom:3rem}.book-header{display:none;margin-bottom:1rem}.book-header label{line-height:0}.book-search{position:relative;margin:1rem 0;border-bottom:1px solid transparent}.book-search input{width:100%;padding:.5rem;border:0;border-radius:.25rem;background:var(--gray-100);color:var(--body-font-color)}.book-search input:required+.book-search-spinner{display:block}.book-search .book-search-spinner{position:absolute;top:0;margin:.5rem;margin-inline-start:calc(100% - 1.5rem);width:1rem;height:1rem;border:1px solid transparent;border-top-color:var(--body-font-color);border-radius:50%;animation:spin 1s ease infinite}@keyframes spin{100%{transform:rotate(360deg)}}.book-search small{opacity:.5}.book-toc{flex:0 0 16rem;font-size:.75rem}.book-toc .book-toc-content{width:16rem;padding:1rem;position:fixed;top:0;bottom:0;overflow-x:hidden;overflow-y:auto}.book-toc img{height:1em}.book-toc nav>ul>li:first-child{margin-top:0}.book-footer{padding-top:1rem;font-size:.875rem}.book-footer img{height:1em;margin-inline-end:.5rem}.book-comments{margin-top:1rem}.book-languages{position:relative;overflow:visible;padding:1rem;margin:-1rem}.book-languages ul{margin:0;padding:0;list-style:none}.book-languages ul li{white-space:nowrap;cursor:pointer}.book-languages:hover .book-languages-list,.book-languages:focus .book-languages-list,.book-languages:focus-within .book-languages-list{display:block}.book-languages .book-languages-list{display:none;position:absolute;bottom:100%;left:0;padding:.5rem 0;background:var(--body-background);box-shadow:0 0 .25rem rgba(0,0,0,.1)}.book-languages .book-languages-list li img{opacity:.25}.book-languages .book-languages-list li.active img,.book-languages .book-languages-list li:hover img{opacity:initial}.book-languages .book-languages-list a{color:inherit;padding:.5rem 1rem}.book-home{padding:1rem}.book-menu-content,.book-toc-content,.book-page,.book-header aside,.markdown{transition:.2s ease-in-out;transition-property:transform,margin,opacity,visibility;will-change:transform,margin,opacity}@media screen and (max-width:56rem){#menu-control,#toc-control{display:inline}.book-menu{visibility:hidden;margin-inline-start:-16rem;font-size:16px;z-index:1}.book-toc{display:none}.book-header{display:block}#menu-control:focus~main label[for=menu-control]{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}#menu-control:checked~main .book-menu{visibility:initial}#menu-control:checked~main .book-menu .book-menu-content{transform:translateX(16rem);box-shadow:0 0 .5rem rgba(0,0,0,.1)}#menu-control:checked~main .book-page{opacity:.25}#menu-control:checked~main .book-menu-overlay{display:block;position:absolute;top:0;bottom:0;left:0;right:0}#toc-control:focus~main label[for=toc-control]{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}#toc-control:checked~main .book-header aside{display:block}body[dir=rtl] #menu-control:checked+main .book-menu .book-menu-content{transform:translateX(-16rem)}}@media screen and (min-width:80rem){.book-page,.book-menu .book-menu-content,.book-toc .book-toc-content{padding:2rem 1rem}}@font-face{font-family:roboto;font-style:italic;font-weight:300;font-display:swap;src:local("Roboto Light Italic"),local("Roboto-LightItalic"),url(fonts/roboto-v19-latin-300italic.woff2)format("woff2"),url(fonts/roboto-v19-latin-300italic.woff)format("woff")}@font-face{font-family:roboto;font-style:normal;font-weight:400;font-display:swap;src:local("Roboto"),local("Roboto-Regular"),url(fonts/roboto-v19-latin-regular.woff2)format("woff2"),url(fonts/roboto-v19-latin-regular.woff)format("woff")}@font-face{font-family:roboto;font-style:normal;font-weight:700;font-display:swap;src:local("Roboto Bold"),local("Roboto-Bold"),url(fonts/roboto-v19-latin-700.woff2)format("woff2"),url(fonts/roboto-v19-latin-700.woff)format("woff")}@font-face{font-family:roboto mono;font-style:normal;font-weight:400;font-display:swap;src:local("Roboto Mono"),local("RobotoMono-Regular"),url(fonts/roboto-mono-v6-latin-regular.woff2)format("woff2"),url(fonts/roboto-mono-v6-latin-regular.woff)format("woff")}body{font-family:roboto,sans-serif}code{font-family:roboto mono,monospace}@media print{.book-menu,.book-footer,.book-toc{display:none}.book-header,.book-header aside{display:block}main{display:block!important}}.markdown{line-height:1.6}.markdown>:first-child{margin-top:0}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:400;line-height:1;margin-top:1.5em;margin-bottom:1rem}.markdown h1 a.anchor,.markdown h2 a.anchor,.markdown h3 a.anchor,.markdown h4 a.anchor,.markdown h5 a.anchor,.markdown h6 a.anchor{opacity:0;font-size:.75em;vertical-align:middle;text-decoration:none}.markdown h1:hover a.anchor,.markdown h1 a.anchor:focus,.markdown h2:hover a.anchor,.markdown h2 a.anchor:focus,.markdown h3:hover a.anchor,.markdown h3 a.anchor:focus,.markdown h4:hover a.anchor,.markdown h4 a.anchor:focus,.markdown h5:hover a.anchor,.markdown h5 a.anchor:focus,.markdown h6:hover a.anchor,.markdown h6 a.anchor:focus{opacity:initial}.markdown h4,.markdown h5,.markdown h6{font-weight:bolder}.markdown h5{font-size:.875em}.markdown h6{font-size:.75em}.markdown b,.markdown optgroup,.markdown strong{font-weight:bolder}.markdown a{text-decoration:none}.markdown a:hover{text-decoration:underline}.markdown a:visited{color:var(--color-visited-link)}.markdown img{max-width:100%}.markdown code{padding:0 .25rem;background:var(--gray-200);border-radius:.25rem;font-size:.875em}.markdown pre{padding:1rem;background:var(--gray-100);border-radius:.25rem;overflow-x:auto}.markdown pre code{padding:0;background:0 0}.markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-inline-start:.25rem solid var(--gray-200);border-radius:.25rem}.markdown blockquote :first-child{margin-top:0}.markdown blockquote :last-child{margin-bottom:0}.markdown table{overflow:auto;display:block;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem}.markdown table tr th,.markdown table tr td{padding:.5rem 1rem;border:1px solid var(--gray-200)}.markdown table tr:nth-child(2n){background:var(--gray-100)}.markdown hr{height:1px;border:none;background:var(--gray-200)}.markdown ul,.markdown ol{padding-inline-start:2rem}.markdown dl dt{font-weight:bolder;margin-top:1rem}.markdown dl dd{margin-inline-start:1rem;margin-bottom:1rem}.markdown .highlight table tr td:nth-child(1) pre{margin:0;padding-inline-end:0}.markdown .highlight table tr td:nth-child(2) pre{margin:0;padding-inline-start:0}.markdown details{padding:1rem;border:1px solid var(--gray-200);border-radius:.25rem}.markdown details summary{line-height:1;padding:1rem;margin:-1rem;cursor:pointer}.markdown details[open] summary{margin-bottom:0}.markdown figure{margin:1rem 0}.markdown figure figcaption p{margin-top:0}.markdown-inner>:first-child{margin-top:0}.markdown-inner>:last-child{margin-bottom:0}.markdown .book-expand{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:.25rem;overflow:hidden}.markdown .book-expand .book-expand-head{background:var(--gray-100);padding:.5rem 1rem;cursor:pointer}.markdown .book-expand .book-expand-content{display:none;padding:1rem}.markdown .book-expand input[type=checkbox]:checked+.book-expand-content{display:block}.markdown .book-tabs{margin-top:1rem;margin-bottom:1rem;border:1px solid var(--gray-200);border-radius:.25rem;overflow:hidden;display:flex;flex-wrap:wrap}.markdown .book-tabs label{display:inline-block;padding:.5rem 1rem;border-bottom:1px transparent;cursor:pointer}.markdown .book-tabs .book-tabs-content{order:999;width:100%;border-top:1px solid var(--gray-100);padding:1rem;display:none}.markdown .book-tabs input[type=radio]:checked+label{border-bottom:1px solid var(--color-link)}.markdown .book-tabs input[type=radio]:checked+label+.book-tabs-content{display:block}.markdown .book-tabs input[type=radio]:focus+label{outline-style:auto;outline-color:currentColor;outline-color:-webkit-focus-ring-color}.markdown .book-columns{margin-left:-1rem;margin-right:-1rem}.markdown .book-columns>div{margin:1rem 0;min-width:10rem;padding:0 1rem}.markdown a.book-btn{display:inline-block;font-size:.875rem;color:var(--color-link);line-height:2rem;padding:0 1rem;border:1px solid var(--color-link);border-radius:.25rem;cursor:pointer}.markdown a.book-btn:hover{text-decoration:none}.markdown .book-hint.info{border-color:#6bf;background-color:rgba(102,187,255,.1)}.markdown .book-hint.warning{border-color:#fd6;background-color:rgba(255,221,102,.1)}.markdown .book-hint.danger{border-color:#f66;background-color:rgba(255,102,102,.1)} From 7c6d071407986104bcb1a86be8dd1da7749d1562 Mon Sep 17 00:00:00 2001 From: Jimmy Debe <91767824+jimstir@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:21:53 -0500 Subject: [PATCH 4/4] Create book.scss_50fc8c04e12a2f59027287995557ceff.json --- .../17/images/book.scss_50fc8c04e12a2f59027287995557ceff.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.json diff --git a/waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.json b/waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.json new file mode 100644 index 000000000..dc5c59c95 --- /dev/null +++ b/waku/standards/core/17/images/book.scss_50fc8c04e12a2f59027287995557ceff.json @@ -0,0 +1 @@ +{"Target":"book.min.e935e20bd0d469378cb482f0958edf258c731a4f895dccd55799c6fbc8043f23.css","MediaType":"text/css","Data":{"Integrity":"sha256-6TXiC9DUaTeMtILwlY7fJYxzGk+JXczVV5nG+8gEPyM="}}