-
Notifications
You must be signed in to change notification settings - Fork 9
describe provable assertions #123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I think the discussion at the start around ordering is not necessary, since we are not pre-empting an L1 block in this discussion. I am just saving the current state in case I'd like to return to it.
- it now mentions ENS and price feed. - it also explains how this mechanism does not constrain the sequencer
Note that creating an "asserter" address actually undermines the ability for contracts to trust assertions that are made by the expected address (since the address would change every publication)
This is in response to feedback that it was the most confusing section
The examples were incorrectly including the value as part of the assertion ID.
linoscope
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice document! Enjoyed the intro/summary part and the diagrams too.
Finished reading the parts before the implementation description and left some comments.
|
|
||
| When an L2 publication spans several L1 slots, it will be useful if every intermediate L1 state root is asserted in the L2 state as soon as it's known, which would allow the L2 contracts to respond to L1 updates as they occur. For example, the dark green transaction could be an update to an ENS resolver, or a new price in a price feed. The light green transaction could be a DeFi protocol that responds to that change immediately (as soon as the state is asserted), even though it occurred in the middle of a publication. This could be achieved straightforwardly by applying the anchor mechanism to every block. | ||
|
|
||
| Naively this appears to require the Inbox to make a different `blockhash` call for each intermediate block, but as an optimisation, the sequencer could reproduce the entire chain of L1 block headers on L2 (starting from the last validated one) when proving the assertions. If the last block hash is validated on L1, this implicitly validates the entire chain. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| This mechanism allows users to simply state their desired outcome, offloading the coordination and complexity to the block builders. | ||
|
|
||
| It also allows complex transactions to progressively resolve over time. For example, consider a user who offers to withdraw funds from their DeFi investment and provide an unsecured loan to anyone as long as the funds are returned with some minimum interest payment, potentially shared with the builder to justify the effort. This is like offering a flash loan in the sense that no collateral is required and the loan must be repaid or it never occurred, but it could span several L1 slots (as long as it's still within the sequencer's publication window). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enabling flashloan-like use case without having full-blown "synchronous" composability (i.e., contract in one rollup can call contract in another rollup as if same execution env) is very interesting! Guess the trade-off compared to sync composability would be DevEx and risk/complexity tolerance in proposers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're on the same page, but just to clarify: this would all be happening on one rollup, so it's not a direct alternative to synchronous composability. Any cross-rollup or L1-to-L2 steps within the flash loan would use the same assertion mechanism.
| - the rollup A's state transition function validates the consistency of the entire bundle, which includes confirming (among many other things) that Bob's transaction is recorded in the claimed rollup B state root (so the assertion is proven). | ||
|
|
||
| Note that there is an extra level of indirection, which introduces a new risk. All the assertions in the article are treated as validity conditions for the whole bundle, so L2 contracts can build on them, blindly assuming they are correct. If they are not proven, any dependent transactions are discarded (or will revert) anyway. However, in this case, the assertion is only that Bob's transaction is recorded in the _claimed_ rollup B state root. This assertion could be correct even if the claimed state root is eventually proven to be incorrect. In this scenario: | ||
| - Alice's transaction would be included in rollup A, but the whole rollup B publication would be discarded (so Alice would end up sending a one-sided transfer). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds pretty bad...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not just bad for Alice, which may be somewhat fine if Alice is aware of the risk. It can potentially break the fundamental invariants between rollups. For example, rollup B can have "outgoing ETH" that exceeds the total ETH that was ever deposited to rollup B's bridge if, for example:
- Rollup B has, in total, 10 ETH deposited to its bridge.
- The malicious proposer of B commits to an unproven state root that bridges out 100 ETH.
- Rollup A builds upon the unproven-but-committed state root and mints 100ETH in it's state. Alice acts upon the newly minted ETH.
- Rollup B's unproven state turns out to be invalid. Rollup B batch is discarded.
- However, rollup A is stuck with invalidly minted ETH in its state. It cannot recover from the invalid state.
We can disable transfers of native assets as prevention, but that would undermine a large portion of use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I think it's better to have both rollups when one leg of the composability is invalid. Or else we either have to forfeit on seamless asset transfers, or introduce risks of one rollup getting stuck into an unrecoverable state (it has assets minted without any matching deposits).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good points - I mostly agree! However, I think I may be approaching this from a different angle, so let me share some thoughts and see if they resonate.
I think my general attitude is to make sure the rollup itself is simple, secure and flexible. Within those bounds, users can build whatever they want and take on whatever risks they choose. Our designs should make sure those risks are self-contained (so Alice cannot take risks on behalf of Bob) but should not be opinionated about which risks are acceptable.
Overall, this is just a new kind of power: a proposer can assert anything they want to about their own plans, and about what's going on outside the L2 (on L1 or other rollups). The rollup's job is to offer users the tools needed to tie those claims to independently verifiable information. The interesting thing is the time discrepancy, where the claims can be made as soon as the proposer believes them, but they only need to be verifiable at publication time. Anyone who does not want to use the power should be free to ignore it (just like anyone can decide which preconfirmations, if any, to accept).
So with that in mind, I don't think the native ETH bridge should rely on sequencer assertions at all (at least not the stake-based version - the general assertion mechanism might still be useful to propagate the result of validity proofs around the ecosystem). We should not be interfering with the rules of the rollup, except in the limited sense that the rollup will now guarantee that:
- any assertion contracts that need it can get access to verifiable information from L1 at publication time.
- all assertions are proven (up to the arbitrary standard of their defining L2 contract) every publication.
Whatever anyone wants to build within those bounds is completely open (although we have some examples in listed here and implemented in preemptive provable assertions #78)
If someone wants to make a WETH bridge that accepts stake-based assertions, that's up to them, although I would share your concerns about getting out of sync. Potentially they could alleviate those risks with reputation or by providing an insurance fund (although that starts to look like a solver mechanism).
However, I could imagine less risky use cases that use the cross-rollup mechanism to take advantage of the timing / information (but not value) passing features. For instance, you could have an assertion on rollup A that says: the sequencer will guarantee that if the L1 DAO votes for this upgrade transaction within the next 5 L1 blocks, then that upgrade will be propagated to the components of the system that exist on rollup A and rollup B. In this scenario the assertion would be used provide synchronisation guarantees, but may not be financially important. Users on rollup A would be guaranteed (and they could build on these facts immediately) that:
- if the L1 DAO does not vote for the upgrade within 5 blocks, no upgrade happens
- if the DAO does vote for the upgrade, it will happen on rollup A or nothing happens on rollup A (and the sequencer loses their stake/order flow).
- if the DAO does vote for the upgrade, it will happen on rollup B or nothing happens on rollup B (and the sequencer loses their stake/order flow).
|
|
||
| Note that there is an extra level of indirection, which introduces a new risk. All the assertions in the article are treated as validity conditions for the whole bundle, so L2 contracts can build on them, blindly assuming they are correct. If they are not proven, any dependent transactions are discarded (or will revert) anyway. However, in this case, the assertion is only that Bob's transaction is recorded in the _claimed_ rollup B state root. This assertion could be correct even if the claimed state root is eventually proven to be incorrect. In this scenario: | ||
| - Alice's transaction would be included in rollup A, but the whole rollup B publication would be discarded (so Alice would end up sending a one-sided transfer). | ||
| - The sequencer would lose all transaction fees associated with the discarded rollup B publication, along with any deposited stake. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the slashed stake can be used to compensate Alice? But there are fundamental limitations there, though, as it's hard to tell how much "damage" Alice was inflicted (e.g., she didn't receive some volatile meme coin as a result of equivocation - how much is such meme coin denominated in the slashed asset ETH?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed!
EDIT: I just realised that's not particularly informative. I meant: "I agree that trying to quantify exactly how much damage is done to whom is a losing game, so the rollup itself should not try to redistribute staked funds"
| - an opportunity arises when a particular entity can sequence transactions for both rollup A and rollup B. | ||
| - this sequencer includes both interdependent transactions in their publications. Alice's transaction on rollup A should only succeed if Bob's transaction succeeds on rollup B. | ||
| - once the bundles are published, anyone running nodes for both rollups can reconstruct the state of both rollups and can confirm that both transactions succeeded. | ||
| - however, the next rollup A sequencer may not be running a rollup B node or know anything about the rollup B state. If they are unable to determine whether Bob's transaction succeeded on rollup B, they do not know whether Alice's transaction should succeed on rollup A. The rollup B state will eventually be proven on L1, but until then the rollup A sequencer cannot determine the current state of rollup A so they cannot build on top of it and the rollup will stall. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rollup B state will eventually be proven on L1, but until then the rollup A sequencer cannot determine the current state of rollup A so they cannot build on top of it and the rollup will stall.
Related to the other thread on only reverting one leg of the rollup.
I feel like the risk here is over-emphasized.
- If both rollups are based, the next preconfer/builder is likely to also be sequencing both A and B, hence not knowing the other rollup state won't be an issue.
- Even if the next preconfer/builder is not aware of one of the rollups, they can still rely on the committed state root from the previous preconfer/builder. If previous preconfer/builder can be slashed due to equivocation on there commitments, next preconfer/builder will be fairly confident on building upon their state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps related to the other comment, my concern is not so much about how likely it is to happen, but whether or not they have been forced to take a risk that they didn't opt in to.
In contrast to the assertion mechanism, this is the sort of decision that is happening at the rollup level. If we have a rule that says "this collection of rollups have agreed to do shared sequencing", then the sequencer for one of them is obligated to sequence all of them. This works, but it does mean the question of whether some small rollup or appchain can be included is a matter of convincing the governance mechanism that picks which chains are in the collection.
If we don't have that rule, then I don't think you can't rely on the fact that many based sequencers likely sequence the same rollups. You still hit the question: if someone sequencer makes a publication that references the state of another rollup, what is the next sequencer expected to do? You could have a rule that says they should rely on the last preconfirmation, but I think this reverts back to the first situation (because without gatekeeping the chains, I could always do a cross-rollup transaction with a small appchain that nobody else sequences, and then the value of their whole publication is dependent on my minimal-value preconfirmation).
Having said all that, I expect you're right that as long as we're talking about transfers between major chains (which admittedly, is the main use case), then shared sequencing makes complete sense.
I'm not sure why they were out of sync but I just reran the compile script
WalkthroughThree new documentation files have been introduced: a detailed markdown document on "Preemptive Provable Assertions" outlining mechanisms for rollup flexibility and L1/L2 state assertions, a Bash script to generate diagram images from LaTeX, and a LaTeX source file producing a series of TikZ diagrams visualizing assertion concepts. Example Solidity pseudocode is included in the markdown. Changes
Sequence Diagram(s)sequenceDiagram
participant L2User
participant L2Contract
participant Sequencer
participant L1Chain
participant AssertionContract
L2User->>L2Contract: Submit transaction relying on assertion
L2Contract->>Sequencer: Request assertion creation
Sequencer->>AssertionContract: Create assertion (e.g. L1 state, future L2 call)
Sequencer->>L2Contract: Include assertion in anchor/publication
Sequencer->>L1Chain: Publish anchor with assertion data
L1Chain-->>AssertionContract: Provide proof (consistency hash, state root)
AssertionContract->>L2Contract: Resolve assertion, clear if proven
Poem
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🧹 Nitpick comments (6)
documentation/provable_assertion_images.tex (3)
16-28: Consider adding documentation for the parameter system.The parameterized approach using
\renewcommandis elegant and allows for easy customization across diagrams. However, the parameters could benefit from inline comments explaining their purpose and valid ranges.+% Configuration parameters for diagram generation +% \anchorBlockNum: Index of the anchor block (0-based) +% \numLOneBlocks: Number of L1 blocks to display +% \numLTwoBlocks: Number of L2 blocks to display +% \rollupName: Label for the rollup (A, B, etc.) +% \rollupColor: Color scheme for the rollup +% \rollupOffset: Vertical offset for L2 transaction positioning
254-258: Consider improving the block removal approach.The current method of overwriting blocks with white fill is functional but could be more robust. Consider using clipping or layer management for cleaner visual results.
+% Alternative: Use clipping for cleaner block removal +% \begin{scope} +% \clip (area-to-keep); +% \lTwoTransactions +% \end{scope}
462-466: Add proper LaTeX document closure.The document ends correctly but has trailing empty lines that could be cleaned up.
\end{document} - - -documentation/compile_provable_assertion_images.sh (2)
1-1: Use more portable shebang.The current shebang assumes bash is in
/usr/bin/env, which is portable, but consider making it more explicit about bash requirements.-#!/usr/bin/env bash +#!/usr/bin/env bash +# Requires: pdflatex, convert (ImageMagick)
11-11: Improve cleanup robustness.The cleanup command should handle cases where files don't exist and should be more explicit about what's being removed.
-rm $name.aux $name.log $name.pdf +# Clean up auxiliary files (ignore errors if files don't exist) +rm -f $name.aux $name.log $name.pdfdocumentation/PreemptiveProvableAssertions.md (1)
447-447: Remove trailing empty line.The document ends with an unnecessary empty line after the line number.
<p align="center"><img src="./provable_assertion_images.19.png"/></p> -
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (20)
documentation/provable_assertion_images.0.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.1.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.10.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.11.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.12.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.13.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.14.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.15.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.16.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.17.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.18.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.19.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.2.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.3.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.4.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.5.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.6.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.7.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.8.pngis excluded by!**/*.pngdocumentation/provable_assertion_images.9.pngis excluded by!**/*.png
📒 Files selected for processing (3)
documentation/PreemptiveProvableAssertions.md(1 hunks)documentation/compile_provable_assertion_images.sh(1 hunks)documentation/provable_assertion_images.tex(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
documentation/PreemptiveProvableAssertions.md (1)
Learnt from: nikeshnazareth
PR: OpenZeppelin/minimal-rollup#134
File: test/ProverManager/InvariantTest.t.sol:10-20
Timestamp: 2025-06-24T01:29:22.272Z
Learning: In ProverManager invariant tests, it's acceptable to rely on Solidity mapping behavior that returns zero values for non-existent keys when testing that periods are unused. The zero values serve as a proxy to confirm that a period is not initialized, which is the intended behavior for the invariant tests.
🪛 LanguageTool
documentation/PreemptiveProvableAssertions.md
[style] ~40-~40: Omitting these overused filler words can make your writing sound more assertive.
Context: ...fore it is actually published to L1, we really just mean that it can influence later transaction...
(REALLY_JUST)
[style] ~117-~117: In American English, abbreviations like “etc.” require a period.
Context: ...g. oracle updates, airdrops, DAO votes, etc) that leave remnants in publicly access...
(ETC_PERIOD)
[style] ~222-~222: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ever, the opportunistic context creates a very strong requirement that complicates composabil...
(EN_WEAK_ADJECTIVE)
[style] ~245-~245: ‘whether or not’ might be wordy. Consider a shorter alternative.
Context: ... be proven against the claimed state, whether or not it is eventually proven correct. Using ...
(EN_WORDINESS_PREMIUM_WHETHER_OR_NOT)
[style] ~339-~339: Consider using “who” when you are referring to a person instead of an object.
Context: ...pay enough fees. For example: - a user that claims the block hash for L1 block B ...
(THAT_WHO)
[style] ~340-~340: Consider using “who” when you are referring to a person instead of an object.
Context: ...r the blockhash query on L1. - a user that wants an assertion that some property w...
(THAT_WHO)
🪛 markdownlint-cli2 (0.17.2)
documentation/PreemptiveProvableAssertions.md
30-30: Images should have alternate text (alt text)
(MD045, no-alt-text)
34-34: Images should have alternate text (alt text)
(MD045, no-alt-text)
38-38: Images should have alternate text (alt text)
(MD045, no-alt-text)
55-55: Images should have alternate text (alt text)
(MD045, no-alt-text)
59-59: Images should have alternate text (alt text)
(MD045, no-alt-text)
74-74: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
79-79: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
80-80: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
99-99: Images should have alternate text (alt text)
(MD045, no-alt-text)
105-105: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
133-133: Images should have alternate text (alt text)
(MD045, no-alt-text)
141-141: Images should have alternate text (alt text)
(MD045, no-alt-text)
147-147: Hard tabs
Column: 1
(MD010, no-hard-tabs)
148-148: Hard tabs
Column: 1
(MD010, no-hard-tabs)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
155-155: Hard tabs
Column: 1
(MD010, no-hard-tabs)
157-157: Hard tabs
Column: 1
(MD010, no-hard-tabs)
158-158: Hard tabs
Column: 1
(MD010, no-hard-tabs)
159-159: Hard tabs
Column: 1
(MD010, no-hard-tabs)
188-188: Hard tabs
Column: 1
(MD010, no-hard-tabs)
189-189: Hard tabs
Column: 1
(MD010, no-hard-tabs)
190-190: Hard tabs
Column: 1
(MD010, no-hard-tabs)
193-193: Hard tabs
Column: 1
(MD010, no-hard-tabs)
194-194: Hard tabs
Column: 1
(MD010, no-hard-tabs)
195-195: Hard tabs
Column: 1
(MD010, no-hard-tabs)
214-214: Images should have alternate text (alt text)
(MD045, no-alt-text)
265-265: Images should have alternate text (alt text)
(MD045, no-alt-text)
291-291: Images should have alternate text (alt text)
(MD045, no-alt-text)
317-317: Images should have alternate text (alt text)
(MD045, no-alt-text)
348-348: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
352-352: Images should have alternate text (alt text)
(MD045, no-alt-text)
370-370: Images should have alternate text (alt text)
(MD045, no-alt-text)
380-380: Images should have alternate text (alt text)
(MD045, no-alt-text)
386-386: Images should have alternate text (alt text)
(MD045, no-alt-text)
404-404: Images should have alternate text (alt text)
(MD045, no-alt-text)
411-411: Images should have alternate text (alt text)
(MD045, no-alt-text)
438-438: Images should have alternate text (alt text)
(MD045, no-alt-text)
444-444: Images should have alternate text (alt text)
(MD045, no-alt-text)
🔇 Additional comments (8)
documentation/provable_assertion_images.tex (3)
1-12: Document structure and imports look good.The LaTeX document is well-structured with appropriate standalone class and necessary TikZ libraries. The style definitions are clean and semantically meaningful.
29-36: Timeline command is well-implemented.The timeline generation using a foreach loop is clean and efficient. The positioning and styling are appropriate for the visual representation.
81-96: Conditional rendering pattern is elegant.The use of
\ifnum \sourceNofor conditional rendering allows generating multiple diagrams from a single source file. This is a clean approach for maintaining consistency across related visualizations.documentation/PreemptiveProvableAssertions.md (5)
1-24: Excellent introduction and scope definition.The overview clearly establishes the core concept and provides a good roadmap. The clarification about protocol flexibility vs. specific implementations is valuable.
255-260: Excellent analysis of cross-rollup assertion risks.The detailed explanation of the risks when claimed state roots are incorrect is thorough and aligns well with the concerns raised in past review comments about cross-rollup composability failures.
275-277: Clear and well-designed assertion interface.The mapping-based assertion system is elegant and provides a clean separation of concerns. The use of
assertionIdas a hash andmsg.senderfor clearing provides good security properties.
304-316: Robust proving mechanism design.The consistency hash approach and end-of-publication transaction design provides strong guarantees while maintaining flexibility. The state-transition-function requirements ensure proper validation.
337-343: Innovative pauser mechanism for cost coordination.The pauser mechanism for coordinating assertion costs and enabling transcript-level transaction conditions is a clever solution that addresses practical deployment concerns.
| for i in {0..19} | ||
| do | ||
| pdflatex "\def\sourceNo{$i}\input{$name.tex}"; | ||
| convert -density 600x600 $name.pdf -quality 90 $name.$i.png; | ||
| done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for compilation failures.
The script doesn't handle compilation errors, which could leave the system in an inconsistent state with partial files.
for i in {0..19}
do
- pdflatex "\def\sourceNo{$i}\input{$name.tex}";
- convert -density 600x600 $name.pdf -quality 90 $name.$i.png;
+ if ! pdflatex "\def\sourceNo{$i}\input{$name.tex}"; then
+ echo "Error: pdflatex failed for sourceNo=$i"
+ exit 1
+ fi
+ if ! convert -density 600x600 $name.pdf -quality 90 $name.$i.png; then
+ echo "Error: convert failed for sourceNo=$i"
+ exit 1
+ fi
done🤖 Prompt for AI Agents
In documentation/compile_provable_assertion_images.sh around lines 5 to 9, the
script lacks error handling for pdflatex compilation failures. Modify the loop
to check the exit status of the pdflatex command after each run, and if it
fails, print an error message and exit the script immediately to prevent further
processing and partial file generation.
| name="provable_assertion_images"; | ||
|
|
||
| for i in {0..19} | ||
| do | ||
| pdflatex "\def\sourceNo{$i}\input{$name.tex}"; | ||
| convert -density 600x600 $name.pdf -quality 90 $name.$i.png; | ||
| done | ||
|
|
||
| rm $name.aux $name.log $name.pdf No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add dependency checking.
The script should verify required tools are available before attempting to use them.
name="provable_assertion_images";
+# Check for required dependencies
+for cmd in pdflatex convert; do
+ if ! command -v "$cmd" &> /dev/null; then
+ echo "Error: $cmd is not installed or not in PATH"
+ exit 1
+ fi
+done
+
for i in {0..19}🤖 Prompt for AI Agents
In documentation/compile_provable_assertion_images.sh around lines 3 to 11, the
script uses pdflatex and convert without checking if these tools are installed.
Add checks at the beginning of the script to verify that both pdflatex and
convert commands are available on the system, and if not, print an error message
and exit the script to prevent runtime failures.
|
|
||
| Let's walkthrough a possible price-feed example in detail using the [sample `PreemptiveAssertions` and `RealtimeL1State` contracts](https://github.com/OpenZeppelin/minimal-rollup/pull/78) deployed on L2. This may be overkill if the publications are only a few L1 blocks long (since we're only saving a few L1 `blockhash` calls) but this example is detailed enough to elucidate the mechanism. | ||
|
|
||
| #### Context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix heading level increment violation.
The heading jumps from h2 to h4, which violates markdown best practices.
-#### Context
+### ContextApply similar fixes to other h4 headings that should be h3: Steps 1-8 in the walkthrough section.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #### Context | |
| ### Context |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
348-348: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
🤖 Prompt for AI Agents
In documentation/PreemptiveProvableAssertions.md at line 348, the heading level
jumps from h2 to h4, violating markdown best practices. Change the h4 heading at
this line to h3 to maintain proper heading hierarchy. Also, review and adjust
other h4 headings in the walkthrough section (Steps 1-8) to h3 where appropriate
to ensure consistent and correct heading levels.
| - the L2 sequencer believes this transaction will be included before their own publication transaction and it will succeed. | ||
| - typically this implies the L2 sequencer is also the L1 sequencer (i.e. it is a based rollup) but it could also be achieved with L1 preconfirmations. | ||
| - the sequencer constructs the corresponding "signal" (a hash of the deposit details) and passes it to the anchor transaction, which saves it in the L2 state. This should be interpreted as an assertion from the sequencer that the deposit will occur on L1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix nested list indentation.
Another instance of incorrect indentation in the nested list.
- the L2 sequencer believes this transaction will be included before their own publication transaction and it will succeed.
- - typically this implies the L2 sequencer is also the L1 sequencer (i.e. it is a based rollup) but it could also be achieved with L1 preconfirmations.
+ - typically this implies the L2 sequencer is also the L1 sequencer (i.e. it is a based rollup) but it could also be achieved with L1 preconfirmations.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - the L2 sequencer believes this transaction will be included before their own publication transaction and it will succeed. | |
| - typically this implies the L2 sequencer is also the L1 sequencer (i.e. it is a based rollup) but it could also be achieved with L1 preconfirmations. | |
| - the sequencer constructs the corresponding "signal" (a hash of the deposit details) and passes it to the anchor transaction, which saves it in the L2 state. This should be interpreted as an assertion from the sequencer that the deposit will occur on L1. | |
| - the L2 sequencer believes this transaction will be included before their own publication transaction and it will succeed. | |
| - typically this implies the L2 sequencer is also the L1 sequencer (i.e. it is a based rollup) but it could also be achieved with L1 preconfirmations. | |
| - the sequencer constructs the corresponding "signal" (a hash of the deposit details) and passes it to the anchor transaction, which saves it in the L2 state. This should be interpreted as an assertion from the sequencer that the deposit will occur on L1. |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
105-105: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
🤖 Prompt for AI Agents
In documentation/PreemptiveProvableAssertions.md around lines 104 to 106, the
nested list indentation is incorrect, causing formatting issues. Adjust the
indentation of the nested list items so that subpoints are properly indented
under their parent list item, ensuring consistent markdown list structure and
readability.
| ```solidity | ||
| contract PrisonersDilemma is IPrisonersDilemma { | ||
| const uint256 COOPERATE = 1; | ||
| const uint256 DEFECT = 2; | ||
|
|
||
| mapping(address participant => uint256 choice) public choices; | ||
|
|
||
| function choose(uint256 choice) public { | ||
| require(choices[msg.sender] == 0); | ||
| choices[msg.sender] = choice; | ||
| } | ||
|
|
||
| function payout() public { | ||
| // partition rewards according to the Prisoner's dilemma payout table | ||
| } | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix indentation and tab issues in Solidity code.
The static analysis flags hard tabs that should be replaced with spaces for consistency.
contract PrisonersDilemma is IPrisonersDilemma {
- const uint256 COOPERATE = 1;
- const uint256 DEFECT = 2;
-
- mapping(address participant => uint256 choice) public choices;
-
- function choose(uint256 choice) public {
- require(choices[msg.sender] == 0);
- choices[msg.sender] = choice;
- }
-
- function payout() public {
- // partition rewards according to the Prisoner's dilemma payout table
- }
+ const uint256 COOPERATE = 1;
+ const uint256 DEFECT = 2;
+
+ mapping(address participant => uint256 choice) public choices;
+
+ function choose(uint256 choice) public {
+ require(choices[msg.sender] == 0);
+ choices[msg.sender] = choice;
+ }
+
+ function payout() public {
+ // partition rewards according to the Prisoner's dilemma payout table
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```solidity | |
| contract PrisonersDilemma is IPrisonersDilemma { | |
| const uint256 COOPERATE = 1; | |
| const uint256 DEFECT = 2; | |
| mapping(address participant => uint256 choice) public choices; | |
| function choose(uint256 choice) public { | |
| require(choices[msg.sender] == 0); | |
| choices[msg.sender] = choice; | |
| } | |
| function payout() public { | |
| // partition rewards according to the Prisoner's dilemma payout table | |
| } | |
| } | |
| ``` |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
147-147: Hard tabs
Column: 1
(MD010, no-hard-tabs)
148-148: Hard tabs
Column: 1
(MD010, no-hard-tabs)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
155-155: Hard tabs
Column: 1
(MD010, no-hard-tabs)
157-157: Hard tabs
Column: 1
(MD010, no-hard-tabs)
158-158: Hard tabs
Column: 1
(MD010, no-hard-tabs)
159-159: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🤖 Prompt for AI Agents
In documentation/PreemptiveProvableAssertions.md around lines 145 to 161, the
Solidity code uses hard tabs for indentation which causes inconsistency. Replace
all hard tabs with spaces to ensure consistent indentation throughout the code
block.
| <p align="center"><img src="./provable_assertion_images.0.png"/></p> | ||
|
|
||
| L2 transactions are derived from data published in an L1 transaction. Typically, they are aggregated into L2 blocks with a shorter block time, so there are several L2 blocks per L1 block. | ||
|
|
||
| <p align="center"><img src="./provable_assertion_images.1.png"/></p> | ||
|
|
||
| We are focussed on potential functionality that can be offered by an L2 sequencer with monopoly rights until a particular slot, typically spanning several L1 blocks (although just two are depicted here). | ||
|
|
||
| <p align="center"><img src="./provable_assertion_images.2.png"/></p> | ||
|
|
||
| Such a sequencer would be partially limited in their flexibility to reorganise L2 transactions over several slots, because they may offer preconfirmations or liveness guarantees to users. Whenever we discuss a transaction occurring on L2 before it is actually published to L1, we really just mean that it can influence later transactions and the sequencer is unlikely to remove or delay it. For simplicity, this article will default to describing L2 blocks as if they are continuously created and finalised in real time. | ||
|
|
||
| ## Anchor blocks | ||
|
|
||
| We need a mechanism to send messages from L1 to L2, so that L2 users and contracts can react to L1 activity. I will describe Taiko's standard architecture, although the concepts are broadly applicable across rollups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add alt text to images as flagged by static analysis.
All images throughout the document are missing alt text, which affects accessibility and SEO.
-<p align="center"><img src="./provable_assertion_images.0.png"/></p>
+<p align="center"><img src="./provable_assertion_images.0.png" alt="L1 timeline showing block proposers every 12 seconds"/></p>Apply similar changes to all images (lines 30, 34, 38, 55, 59, 99, 133, 141, 214, 265, 291, 317, 352, 370, 380, 386, 404, 411, 438, 444).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <p align="center"><img src="./provable_assertion_images.0.png"/></p> | |
| L2 transactions are derived from data published in an L1 transaction. Typically, they are aggregated into L2 blocks with a shorter block time, so there are several L2 blocks per L1 block. | |
| <p align="center"><img src="./provable_assertion_images.1.png"/></p> | |
| We are focussed on potential functionality that can be offered by an L2 sequencer with monopoly rights until a particular slot, typically spanning several L1 blocks (although just two are depicted here). | |
| <p align="center"><img src="./provable_assertion_images.2.png"/></p> | |
| Such a sequencer would be partially limited in their flexibility to reorganise L2 transactions over several slots, because they may offer preconfirmations or liveness guarantees to users. Whenever we discuss a transaction occurring on L2 before it is actually published to L1, we really just mean that it can influence later transactions and the sequencer is unlikely to remove or delay it. For simplicity, this article will default to describing L2 blocks as if they are continuously created and finalised in real time. | |
| ## Anchor blocks | |
| We need a mechanism to send messages from L1 to L2, so that L2 users and contracts can react to L1 activity. I will describe Taiko's standard architecture, although the concepts are broadly applicable across rollups. | |
| <p align="center"><img src="./provable_assertion_images.0.png" alt="L1 timeline showing block proposers every 12 seconds"/></p> | |
| L2 transactions are derived from data published in an L1 transaction. Typically, they are aggregated into L2 blocks with a shorter block time, so there are several L2 blocks per L1 block. | |
| <p align="center"><img src="./provable_assertion_images.1.png"/></p> | |
| We are focussed on potential functionality that can be offered by an L2 sequencer with monopoly rights until a particular slot, typically spanning several L1 blocks (although just two are depicted here). | |
| <p align="center"><img src="./provable_assertion_images.2.png"/></p> | |
| Such a sequencer would be partially limited in their flexibility to reorganise L2 transactions over several slots, because they may offer preconfirmations or liveness guarantees to users. Whenever we discuss a transaction occurring on L2 before it is actually published to L1, we really just mean that it can influence later transactions and the sequencer is unlikely to remove or delay it. For simplicity, this article will default to describing L2 blocks as if they are continuously created and finalised in real time. | |
| ## Anchor blocks | |
| We need a mechanism to send messages from L1 to L2, so that L2 users and contracts can react to L1 activity. I will describe Taiko's standard architecture, although the concepts are broadly applicable across rollups. |
🧰 Tools
🪛 LanguageTool
[style] ~40-~40: Omitting these overused filler words can make your writing sound more assertive.
Context: ...fore it is actually published to L1, we really just mean that it can influence later transaction...
(REALLY_JUST)
🪛 markdownlint-cli2 (0.17.2)
30-30: Images should have alternate text (alt text)
(MD045, no-alt-text)
34-34: Images should have alternate text (alt text)
(MD045, no-alt-text)
38-38: Images should have alternate text (alt text)
(MD045, no-alt-text)
🤖 Prompt for AI Agents
In documentation/PreemptiveProvableAssertions.md around lines 30 to 44, the
images lack alt text attributes, which impacts accessibility and SEO. Add
descriptive alt text to each image tag to clearly convey the image content or
purpose. Apply this fix consistently to all images listed in the comment at the
specified line numbers throughout the document.
| - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article. | ||
| - the sequencer continues to build L2 blocks, and possibly preconfirms them. | ||
| - eventually the sequencer submits the whole bundle to the L1 Inbox contract. | ||
| - the Inbox contract calls `blockhash(anchorBlockNumber)` and saves (a hash of) it along with the publication. | ||
| - the rollup's state transition function, implemented by the rollup nodes, validates the consistency of the entire bundle, which includes confirming (among many other things) that: | ||
| - the anchor transaction is called exactly once at the start of every block. | ||
| - the block number and state root arguments are consistent with the block hash queried by the L1 inbox. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix list indentation as flagged by markdownlint.
The nested list items should use 2-space indentation instead of 4.
- the sequencer reads the latest L1 state and block number from their node.
- the sequencer passes these values to the anchor transactions, which saves them in the L2 state.
- - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article.
+ - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article.
- the sequencer continues to build L2 blocks, and possibly preconfirms them.
- eventually the sequencer submits the whole bundle to the L1 Inbox contract.
- the Inbox contract calls `blockhash(anchorBlockNumber)` and saves (a hash of) it along with the publication.
- the rollup's state transition function, implemented by the rollup nodes, validates the consistency of the entire bundle, which includes confirming (among many other things) that:
- - the anchor transaction is called exactly once at the start of every block.
- - the block number and state root arguments are consistent with the block hash queried by the L1 inbox.
+ - the anchor transaction is called exactly once at the start of every block.
+ - the block number and state root arguments are consistent with the block hash queried by the L1 inbox.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article. | |
| - the sequencer continues to build L2 blocks, and possibly preconfirms them. | |
| - eventually the sequencer submits the whole bundle to the L1 Inbox contract. | |
| - the Inbox contract calls `blockhash(anchorBlockNumber)` and saves (a hash of) it along with the publication. | |
| - the rollup's state transition function, implemented by the rollup nodes, validates the consistency of the entire bundle, which includes confirming (among many other things) that: | |
| - the anchor transaction is called exactly once at the start of every block. | |
| - the block number and state root arguments are consistent with the block hash queried by the L1 inbox. | |
| - the sequencer reads the latest L1 state and block number from their node. | |
| - the sequencer passes these values to the anchor transactions, which saves them in the L2 state. | |
| - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article. | |
| - the sequencer continues to build L2 blocks, and possibly preconfirms them. | |
| - eventually the sequencer submits the whole bundle to the L1 Inbox contract. | |
| - the Inbox contract calls `blockhash(anchorBlockNumber)` and saves (a hash of) it along with the publication. | |
| - the rollup's state transition function, implemented by the rollup nodes, validates the consistency of the entire bundle, which includes confirming (among many other things) that: | |
| - the anchor transaction is called exactly once at the start of every block. | |
| - the block number and state root arguments are consistent with the block hash queried by the L1 inbox. |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
74-74: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
79-79: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
80-80: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
🤖 Prompt for AI Agents
In documentation/PreemptiveProvableAssertions.md around lines 74 to 80, the
nested list items use 4-space indentation which violates markdownlint rules.
Adjust the indentation of the nested list items to use 2 spaces instead of 4 to
fix the list formatting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
documentation/PreemptiveProvableAssertions.md (2)
32-41: Alt-text still missing for multiple<img>tagsAll images in this span (and many further down) lack an
altattribute, breaking accessibility & MD045. This was flagged in prior reviews.
74-82: Fix unordered-list indentation (MD007)Two-space nesting is required; the current 4-space indentation violates markdownlint. Already raised previously.
🧹 Nitpick comments (2)
documentation/PreemptiveProvableAssertions.md (2)
42-42: Tighten wording – drop filler “really just”-…we really just mean that it can influence later transactions… +…we mean that it can influence later transactions…
118-126: Minor grammar – add period after “etc.” and prefer “e.g.”-…oracle updates, airdrops, DAO votes, etc) that leave… +…oracle updates, airdrops, DAO votes, etc.) that leave…
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
documentation/PreemptiveProvableAssertions.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
documentation/PreemptiveProvableAssertions.md
[style] ~42-~42: Omitting these overused filler words can make your writing sound more assertive.
Context: ...fore it is actually published to L1, we really just mean that it can influence later transaction...
(REALLY_JUST)
[style] ~119-~119: In American English, abbreviations like “etc.” require a period.
Context: ...g. oracle updates, airdrops, DAO votes, etc) that leave remnants in publicly access...
(ETC_PERIOD)
[style] ~224-~224: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ever, the opportunistic context creates a very strong requirement that complicates composabil...
(EN_WEAK_ADJECTIVE)
[style] ~247-~247: ‘whether or not’ might be wordy. Consider a shorter alternative.
Context: ... be proven against the claimed state, whether or not it is eventually proven correct. Using ...
(EN_WORDINESS_PREMIUM_WHETHER_OR_NOT)
[style] ~341-~341: Consider using “who” when you are referring to a person instead of an object.
Context: ...pay enough fees. For example: - a user that claims the block hash for L1 block B ...
(THAT_WHO)
[style] ~342-~342: Consider using “who” when you are referring to a person instead of an object.
Context: ...r the blockhash query on L1. - a user that wants an assertion that some property w...
(THAT_WHO)
🪛 markdownlint-cli2 (0.17.2)
documentation/PreemptiveProvableAssertions.md
32-32: Images should have alternate text (alt text)
(MD045, no-alt-text)
36-36: Images should have alternate text (alt text)
(MD045, no-alt-text)
40-40: Images should have alternate text (alt text)
(MD045, no-alt-text)
57-57: Images should have alternate text (alt text)
(MD045, no-alt-text)
61-61: Images should have alternate text (alt text)
(MD045, no-alt-text)
76-76: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
81-81: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
82-82: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
101-101: Images should have alternate text (alt text)
(MD045, no-alt-text)
107-107: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
135-135: Images should have alternate text (alt text)
(MD045, no-alt-text)
143-143: Images should have alternate text (alt text)
(MD045, no-alt-text)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
155-155: Hard tabs
Column: 1
(MD010, no-hard-tabs)
156-156: Hard tabs
Column: 1
(MD010, no-hard-tabs)
157-157: Hard tabs
Column: 1
(MD010, no-hard-tabs)
159-159: Hard tabs
Column: 1
(MD010, no-hard-tabs)
160-160: Hard tabs
Column: 1
(MD010, no-hard-tabs)
161-161: Hard tabs
Column: 1
(MD010, no-hard-tabs)
190-190: Hard tabs
Column: 1
(MD010, no-hard-tabs)
191-191: Hard tabs
Column: 1
(MD010, no-hard-tabs)
192-192: Hard tabs
Column: 1
(MD010, no-hard-tabs)
195-195: Hard tabs
Column: 1
(MD010, no-hard-tabs)
196-196: Hard tabs
Column: 1
(MD010, no-hard-tabs)
197-197: Hard tabs
Column: 1
(MD010, no-hard-tabs)
216-216: Images should have alternate text (alt text)
(MD045, no-alt-text)
267-267: Images should have alternate text (alt text)
(MD045, no-alt-text)
293-293: Images should have alternate text (alt text)
(MD045, no-alt-text)
319-319: Images should have alternate text (alt text)
(MD045, no-alt-text)
350-350: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
354-354: Images should have alternate text (alt text)
(MD045, no-alt-text)
372-372: Images should have alternate text (alt text)
(MD045, no-alt-text)
382-382: Images should have alternate text (alt text)
(MD045, no-alt-text)
388-388: Images should have alternate text (alt text)
(MD045, no-alt-text)
406-406: Images should have alternate text (alt text)
(MD045, no-alt-text)
413-413: Images should have alternate text (alt text)
(MD045, no-alt-text)
440-440: Images should have alternate text (alt text)
(MD045, no-alt-text)
446-446: Images should have alternate text (alt text)
(MD045, no-alt-text)
| contract PrisonersDilemma is IPrisonersDilemma { | ||
| const uint256 COOPERATE = 1; | ||
| const uint256 DEFECT = 2; | ||
|
|
||
| mapping(address participant => uint256 choice) public choices; | ||
|
|
||
| function choose(uint256 choice) public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solidity snippet won’t compile – incorrect const keyword & malformed mapping
const is not valid Solidity syntax; use uint256 constant.
The typed-mapping also repeats the value identifier inside the type.
- const uint256 COOPERATE = 1;
- const uint256 DEFECT = 2;
-
- mapping(address participant => uint256 choice) public choices;
+ uint256 constant COOPERATE = 1;
+ uint256 constant DEFECT = 2;
+
+ // Typed mapping syntax: mapping(keyType => valueType) <variableName>;
+ mapping(address participant => uint256) public choices;Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🤖 Prompt for AI Agents
In documentation/PreemptiveProvableAssertions.md around lines 148 to 154, the
Solidity snippet uses the invalid keyword 'const' and incorrectly defines the
mapping type. Replace 'const uint256' with 'uint256 constant' for the constants,
and correct the mapping declaration by removing the repeated value identifier
inside the type, using the proper Solidity mapping syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (4)
documentation/PreemptiveProvableAssertions.md (4)
73-82: Fix nested list indentation (MD007)Sub-items are indented with 4 spaces instead of 2, breaking Markdown rendering.
- - in the Taiko case there is an anchor transaction ... + - in the Taiko case there is an anchor transaction ...Apply the same 2-space indentation to lines 81-82 as well.
188-199: Second Solidity block: hard-tabs & readabilitySame tab issue repeats; also the closing
assertFutureStatearguments are mis-aligned, hurting readability.- block.number + 1, - prisonersDilemma, - abi.encodeCall(IPrisonersDilemma.choices, alice), COOPERATE + block.number + 1, + prisonersDilemma, + abi.encodeCall(IPrisonersDilemma.choices, alice), + COOPERATEApply the same fix to the Bob assertion immediately below.
30-41: Add descriptive alt text to all images & fix heading level jumpEvery
<img>tag in the highlighted ranges is missingalttext (MD045).
Additionally, the#### Contextheading (line 350) skips from##to####, violating MD001.Minimal diff illustrating both fixes (apply pattern-wise to the rest of the file):
-<p align="center"><img src="./provable_assertion_images.0.png"/></p> +<p align="center"><img src="./provable_assertion_images.0.png" alt="L1 proposer timeline"/></p> -#### Context +### ContextPlease replicate the
altattribute for every remaining image and review all heading levels so they increment by exactly one.Also applies to: 56-62, 99-108, 133-139, 214-218, 265-269, 291-297, 317-323, 350-356, 370-377, 380-389, 404-408, 438-447
147-161: Solidity snippet: invalid syntax & hard-tabs
constis not valid Solidity; useuint256 constant.
Mapping declaration repeats the value identifier and the whole block is indented with hard tabs (MD010).-contract PrisonersDilemma is IPrisonersDilemma { - const uint256 COOPERATE = 1; - const uint256 DEFECT = 2; - - mapping(address participant => uint256 choice) public choices; +contract PrisonersDilemma is IPrisonersDilemma { + uint256 constant COOPERATE = 1; + uint256 constant DEFECT = 2; + + mapping(address => uint256) public choices;Replace remaining tabs with 4 spaces for consistency.
🧹 Nitpick comments (1)
documentation/PreemptiveProvableAssertions.md (1)
42-43: Trim filler phrase for crisper proseThe wording “we really just mean” is verbose. Consider:
“we mean it can influence later transactions …”
Purely stylistic; ignore if you prefer current tone.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
documentation/PreemptiveProvableAssertions.md(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
documentation/PreemptiveProvableAssertions.md (1)
Learnt from: nikeshnazareth
PR: OpenZeppelin/minimal-rollup#134
File: test/ProverManager/InvariantTest.t.sol:10-20
Timestamp: 2025-06-24T01:29:22.272Z
Learning: In ProverManager invariant tests, it's acceptable to rely on Solidity mapping behavior that returns zero values for non-existent keys when testing that periods are unused. The zero values serve as a proxy to confirm that a period is not initialized, which is the intended behavior for the invariant tests.
🪛 LanguageTool
documentation/PreemptiveProvableAssertions.md
[style] ~42-~42: Omitting these overused filler words can make your writing sound more assertive.
Context: ...fore it is actually published to L1, we really just mean that it can influence later transaction...
(REALLY_JUST)
[style] ~119-~119: In American English, abbreviations like “etc.” require a period.
Context: ...g. oracle updates, airdrops, DAO votes, etc) that leave remnants in publicly access...
(ETC_PERIOD)
[style] ~224-~224: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ever, the opportunistic context creates a very strong requirement that complicates composabil...
(EN_WEAK_ADJECTIVE)
[style] ~247-~247: ‘whether or not’ might be wordy. Consider a shorter alternative.
Context: ... be proven against the claimed state, whether or not it is eventually proven correct. Using ...
(EN_WORDINESS_PREMIUM_WHETHER_OR_NOT)
[style] ~341-~341: Consider using “who” when you are referring to a person instead of an object.
Context: ...pay enough fees. For example: - a user that claims the block hash for L1 block B ...
(THAT_WHO)
[style] ~342-~342: Consider using “who” when you are referring to a person instead of an object.
Context: ...r the blockhash query on L1. - a user that wants an assertion that some property w...
(THAT_WHO)
🪛 markdownlint-cli2 (0.17.2)
documentation/PreemptiveProvableAssertions.md
32-32: Images should have alternate text (alt text)
(MD045, no-alt-text)
36-36: Images should have alternate text (alt text)
(MD045, no-alt-text)
40-40: Images should have alternate text (alt text)
(MD045, no-alt-text)
57-57: Images should have alternate text (alt text)
(MD045, no-alt-text)
61-61: Images should have alternate text (alt text)
(MD045, no-alt-text)
76-76: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
81-81: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
82-82: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
101-101: Images should have alternate text (alt text)
(MD045, no-alt-text)
107-107: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
135-135: Images should have alternate text (alt text)
(MD045, no-alt-text)
143-143: Images should have alternate text (alt text)
(MD045, no-alt-text)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
155-155: Hard tabs
Column: 1
(MD010, no-hard-tabs)
156-156: Hard tabs
Column: 1
(MD010, no-hard-tabs)
157-157: Hard tabs
Column: 1
(MD010, no-hard-tabs)
159-159: Hard tabs
Column: 1
(MD010, no-hard-tabs)
160-160: Hard tabs
Column: 1
(MD010, no-hard-tabs)
161-161: Hard tabs
Column: 1
(MD010, no-hard-tabs)
190-190: Hard tabs
Column: 1
(MD010, no-hard-tabs)
191-191: Hard tabs
Column: 1
(MD010, no-hard-tabs)
192-192: Hard tabs
Column: 1
(MD010, no-hard-tabs)
195-195: Hard tabs
Column: 1
(MD010, no-hard-tabs)
196-196: Hard tabs
Column: 1
(MD010, no-hard-tabs)
197-197: Hard tabs
Column: 1
(MD010, no-hard-tabs)
216-216: Images should have alternate text (alt text)
(MD045, no-alt-text)
267-267: Images should have alternate text (alt text)
(MD045, no-alt-text)
293-293: Images should have alternate text (alt text)
(MD045, no-alt-text)
319-319: Images should have alternate text (alt text)
(MD045, no-alt-text)
350-350: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
354-354: Images should have alternate text (alt text)
(MD045, no-alt-text)
372-372: Images should have alternate text (alt text)
(MD045, no-alt-text)
382-382: Images should have alternate text (alt text)
(MD045, no-alt-text)
388-388: Images should have alternate text (alt text)
(MD045, no-alt-text)
406-406: Images should have alternate text (alt text)
(MD045, no-alt-text)
413-413: Images should have alternate text (alt text)
(MD045, no-alt-text)
440-440: Images should have alternate text (alt text)
(MD045, no-alt-text)
446-446: Images should have alternate text (alt text)
(MD045, no-alt-text)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (5)
documentation/PreemptiveProvableAssertions.md (5)
32-32: Add descriptive alt text for every image tagAll
<img>tags are missingaltattributes (MD045). This hurts accessibility, SEO, and screen-reader usability.-<p align="center"><img src="./provable_assertion_images.0.png"/></p> +<p align="center"><img src="./provable_assertion_images.0.png" alt="L1 proposer timeline"/></p>Apply a similar fix to every image listed in these lines.
Also applies to: 36-36, 40-40, 57-57, 61-61, 101-101, 135-135, 143-143, 229-229, 280-280, 306-306, 332-332, 367-367, 385-385, 395-395, 401-401, 419-419, 426-426, 453-453, 459-459
74-82: Fix unordered-list indentation (MD007)Sub-items must be indented by 2 spaces, not 4.
- - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article. + - in the Taiko case there is an anchor transaction per L2 block but only ones that update the latest L1 state are relevant for this article.Do the same for the sub-list in the Same-slot section (lines 105-109).
Also applies to: 105-109
363-365: Heading level jumps from H2 to H4Change
#### Contextto### Context(and audit subsequent headings) to keep incremental levels (MD001).
149-161: Replace hard tabs with spaces for consistent formatting (MD010)Convert each leading tab to 4 spaces inside code blocks:
- assertFutureState( - block.number + 1, + assertFutureState( + block.number + 1,Applies to all Solidity snippets in the indicated ranges.
Also applies to: 188-199, 208-214
149-154: Solidity snippet won’t compile – invalidconstkeyword & malformed mappingSame issue was raised previously and is still unresolved.
- const uint256 COOPERATE = 1; - const uint256 DEFECT = 2; - - mapping(address participant => uint256 choice) public choices; + uint256 constant COOPERATE = 1; + uint256 constant DEFECT = 2; + + mapping(address => uint256) public choices;This makes the example compile on ≥0.8.0.
🧹 Nitpick comments (2)
documentation/PreemptiveProvableAssertions.md (2)
204-206: Spelling: “simplfiied” → “simplified”-… It could be simplfiied further if the participants … +… It could be simplified further if the participants …
217-218: Spelling: “independendently” → “independently”-… rather than compensating the sequencer independendently, … +… rather than compensating the sequencer independently, …
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
documentation/PreemptiveProvableAssertions.md(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
documentation/PreemptiveProvableAssertions.md (1)
Learnt from: nikeshnazareth
PR: OpenZeppelin/minimal-rollup#134
File: test/ProverManager/InvariantTest.t.sol:10-20
Timestamp: 2025-06-24T01:29:22.272Z
Learning: In ProverManager invariant tests, it's acceptable to rely on Solidity mapping behavior that returns zero values for non-existent keys when testing that periods are unused. The zero values serve as a proxy to confirm that a period is not initialized, which is the intended behavior for the invariant tests.
🪛 LanguageTool
documentation/PreemptiveProvableAssertions.md
[style] ~42-~42: Omitting these overused filler words can make your writing sound more assertive.
Context: ...fore it is actually published to L1, we really just mean that it can influence later transaction...
(REALLY_JUST)
[style] ~119-~119: In American English, abbreviations like “etc.” require a period.
Context: ...g. oracle updates, airdrops, DAO votes, etc) that leave remnants in publicly access...
(ETC_PERIOD)
[grammar] ~204-~204: Ensure spelling is correct
Context: ...xity to the block builders. It could be simplfiied further if the participants make the as...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~217-~217: Ensure spelling is correct
Context: ... rather than compensating the sequencer independendently, and removes the possibility that she w...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[style] ~237-~237: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ever, the opportunistic context creates a very strong requirement that complicates composabil...
(EN_WEAK_ADJECTIVE)
[style] ~260-~260: ‘whether or not’ might be wordy. Consider a shorter alternative.
Context: ... be proven against the claimed state, whether or not it is eventually proven correct. Using ...
(EN_WORDINESS_PREMIUM_WHETHER_OR_NOT)
[style] ~354-~354: Consider using “who” when you are referring to a person instead of an object.
Context: ...pay enough fees. For example: - a user that claims the block hash for L1 block B ...
(THAT_WHO)
[style] ~355-~355: Consider using “who” when you are referring to a person instead of an object.
Context: ...r the blockhash query on L1. - a user that wants an assertion that some property w...
(THAT_WHO)
🪛 markdownlint-cli2 (0.17.2)
documentation/PreemptiveProvableAssertions.md
32-32: Images should have alternate text (alt text)
(MD045, no-alt-text)
36-36: Images should have alternate text (alt text)
(MD045, no-alt-text)
40-40: Images should have alternate text (alt text)
(MD045, no-alt-text)
57-57: Images should have alternate text (alt text)
(MD045, no-alt-text)
61-61: Images should have alternate text (alt text)
(MD045, no-alt-text)
76-76: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
81-81: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
82-82: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
101-101: Images should have alternate text (alt text)
(MD045, no-alt-text)
107-107: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
135-135: Images should have alternate text (alt text)
(MD045, no-alt-text)
143-143: Images should have alternate text (alt text)
(MD045, no-alt-text)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
155-155: Hard tabs
Column: 1
(MD010, no-hard-tabs)
156-156: Hard tabs
Column: 1
(MD010, no-hard-tabs)
157-157: Hard tabs
Column: 1
(MD010, no-hard-tabs)
159-159: Hard tabs
Column: 1
(MD010, no-hard-tabs)
160-160: Hard tabs
Column: 1
(MD010, no-hard-tabs)
161-161: Hard tabs
Column: 1
(MD010, no-hard-tabs)
188-188: Hard tabs
Column: 1
(MD010, no-hard-tabs)
189-189: Hard tabs
Column: 1
(MD010, no-hard-tabs)
190-190: Hard tabs
Column: 1
(MD010, no-hard-tabs)
191-191: Hard tabs
Column: 1
(MD010, no-hard-tabs)
192-192: Hard tabs
Column: 1
(MD010, no-hard-tabs)
193-193: Hard tabs
Column: 1
(MD010, no-hard-tabs)
194-194: Hard tabs
Column: 1
(MD010, no-hard-tabs)
195-195: Hard tabs
Column: 1
(MD010, no-hard-tabs)
196-196: Hard tabs
Column: 1
(MD010, no-hard-tabs)
197-197: Hard tabs
Column: 1
(MD010, no-hard-tabs)
198-198: Hard tabs
Column: 1
(MD010, no-hard-tabs)
199-199: Hard tabs
Column: 1
(MD010, no-hard-tabs)
209-209: Hard tabs
Column: 1
(MD010, no-hard-tabs)
210-210: Hard tabs
Column: 1
(MD010, no-hard-tabs)
211-211: Hard tabs
Column: 1
(MD010, no-hard-tabs)
229-229: Images should have alternate text (alt text)
(MD045, no-alt-text)
280-280: Images should have alternate text (alt text)
(MD045, no-alt-text)
306-306: Images should have alternate text (alt text)
(MD045, no-alt-text)
332-332: Images should have alternate text (alt text)
(MD045, no-alt-text)
363-363: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
367-367: Images should have alternate text (alt text)
(MD045, no-alt-text)
385-385: Images should have alternate text (alt text)
(MD045, no-alt-text)
395-395: Images should have alternate text (alt text)
(MD045, no-alt-text)
401-401: Images should have alternate text (alt text)
(MD045, no-alt-text)
419-419: Images should have alternate text (alt text)
(MD045, no-alt-text)
426-426: Images should have alternate text (alt text)
(MD045, no-alt-text)
453-453: Images should have alternate text (alt text)
(MD045, no-alt-text)
459-459: Images should have alternate text (alt text)
(MD045, no-alt-text)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (4)
documentation/PreemptiveProvableAssertions.md (4)
149-154: Issue with Solidity snippet (constkeyword and mapping syntax) was already raised in an earlier review.
188-199: Hard-tab indentation in this Solidity example has been flagged before.
32-40: Missingalttext for images was previously noted.
363-364: Heading-level jump (h2➜h4) already covered in earlier feedback.
🧹 Nitpick comments (1)
documentation/PreemptiveProvableAssertions.md (1)
217-218: Fix typo “independendently” → “independently”Minor spelling correction keeps the document polished.
- …rather than compensating the sequencer independendently, and removes the possibility… + …rather than compensating the sequencer independently, and removes the possibility…
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
documentation/PreemptiveProvableAssertions.md(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
documentation/PreemptiveProvableAssertions.md (1)
Learnt from: nikeshnazareth
PR: OpenZeppelin/minimal-rollup#134
File: test/ProverManager/InvariantTest.t.sol:10-20
Timestamp: 2025-06-24T01:29:22.272Z
Learning: In ProverManager invariant tests, it's acceptable to rely on Solidity mapping behavior that returns zero values for non-existent keys when testing that periods are unused. The zero values serve as a proxy to confirm that a period is not initialized, which is the intended behavior for the invariant tests.
🪛 LanguageTool
documentation/PreemptiveProvableAssertions.md
[style] ~42-~42: Omitting these overused filler words can make your writing sound more assertive.
Context: ...fore it is actually published to L1, we really just mean that it can influence later transaction...
(REALLY_JUST)
[style] ~119-~119: In American English, abbreviations like “etc.” require a period.
Context: ...g. oracle updates, airdrops, DAO votes, etc) that leave remnants in publicly access...
(ETC_PERIOD)
[grammar] ~217-~217: Ensure spelling is correct
Context: ... rather than compensating the sequencer independendently, and removes the possibility that she w...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[style] ~237-~237: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ever, the opportunistic context creates a very strong requirement that complicates composabil...
(EN_WEAK_ADJECTIVE)
[style] ~260-~260: ‘whether or not’ might be wordy. Consider a shorter alternative.
Context: ... be proven against the claimed state, whether or not it is eventually proven correct. Using ...
(EN_WORDINESS_PREMIUM_WHETHER_OR_NOT)
[style] ~354-~354: Consider using “who” when you are referring to a person instead of an object.
Context: ...pay enough fees. For example: - a user that claims the block hash for L1 block B ...
(THAT_WHO)
[style] ~355-~355: Consider using “who” when you are referring to a person instead of an object.
Context: ...r the blockhash query on L1. - a user that wants an assertion that some property w...
(THAT_WHO)
🪛 markdownlint-cli2 (0.17.2)
documentation/PreemptiveProvableAssertions.md
32-32: Images should have alternate text (alt text)
(MD045, no-alt-text)
36-36: Images should have alternate text (alt text)
(MD045, no-alt-text)
40-40: Images should have alternate text (alt text)
(MD045, no-alt-text)
57-57: Images should have alternate text (alt text)
(MD045, no-alt-text)
61-61: Images should have alternate text (alt text)
(MD045, no-alt-text)
76-76: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
81-81: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
82-82: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
101-101: Images should have alternate text (alt text)
(MD045, no-alt-text)
107-107: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
135-135: Images should have alternate text (alt text)
(MD045, no-alt-text)
143-143: Images should have alternate text (alt text)
(MD045, no-alt-text)
149-149: Hard tabs
Column: 1
(MD010, no-hard-tabs)
150-150: Hard tabs
Column: 1
(MD010, no-hard-tabs)
151-151: Hard tabs
Column: 1
(MD010, no-hard-tabs)
152-152: Hard tabs
Column: 1
(MD010, no-hard-tabs)
153-153: Hard tabs
Column: 1
(MD010, no-hard-tabs)
154-154: Hard tabs
Column: 1
(MD010, no-hard-tabs)
155-155: Hard tabs
Column: 1
(MD010, no-hard-tabs)
156-156: Hard tabs
Column: 1
(MD010, no-hard-tabs)
157-157: Hard tabs
Column: 1
(MD010, no-hard-tabs)
159-159: Hard tabs
Column: 1
(MD010, no-hard-tabs)
160-160: Hard tabs
Column: 1
(MD010, no-hard-tabs)
161-161: Hard tabs
Column: 1
(MD010, no-hard-tabs)
188-188: Hard tabs
Column: 1
(MD010, no-hard-tabs)
189-189: Hard tabs
Column: 1
(MD010, no-hard-tabs)
190-190: Hard tabs
Column: 1
(MD010, no-hard-tabs)
191-191: Hard tabs
Column: 1
(MD010, no-hard-tabs)
192-192: Hard tabs
Column: 1
(MD010, no-hard-tabs)
193-193: Hard tabs
Column: 1
(MD010, no-hard-tabs)
194-194: Hard tabs
Column: 1
(MD010, no-hard-tabs)
195-195: Hard tabs
Column: 1
(MD010, no-hard-tabs)
196-196: Hard tabs
Column: 1
(MD010, no-hard-tabs)
197-197: Hard tabs
Column: 1
(MD010, no-hard-tabs)
198-198: Hard tabs
Column: 1
(MD010, no-hard-tabs)
199-199: Hard tabs
Column: 1
(MD010, no-hard-tabs)
209-209: Hard tabs
Column: 1
(MD010, no-hard-tabs)
210-210: Hard tabs
Column: 1
(MD010, no-hard-tabs)
211-211: Hard tabs
Column: 1
(MD010, no-hard-tabs)
229-229: Images should have alternate text (alt text)
(MD045, no-alt-text)
280-280: Images should have alternate text (alt text)
(MD045, no-alt-text)
306-306: Images should have alternate text (alt text)
(MD045, no-alt-text)
332-332: Images should have alternate text (alt text)
(MD045, no-alt-text)
363-363: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
367-367: Images should have alternate text (alt text)
(MD045, no-alt-text)
385-385: Images should have alternate text (alt text)
(MD045, no-alt-text)
395-395: Images should have alternate text (alt text)
(MD045, no-alt-text)
401-401: Images should have alternate text (alt text)
(MD045, no-alt-text)
419-419: Images should have alternate text (alt text)
(MD045, no-alt-text)
426-426: Images should have alternate text (alt text)
(MD045, no-alt-text)
453-453: Images should have alternate text (alt text)
(MD045, no-alt-text)
459-459: Images should have alternate text (alt text)
(MD045, no-alt-text)
Just pushing the current state of the draft for review.
It is missing:a discussion about sub-slot provingan implementation details sectionShould be ready for review
Summary by CodeRabbit