-
Notifications
You must be signed in to change notification settings - Fork 644
Add proof enhancer system with customda enhancers #3750
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
Open
Tristan-Wilson
wants to merge
8
commits into
master
Choose a base branch
from
customda-proof-enhancer
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+875
−0
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
25e2c61
Add proof enhancer system with customda enhancers
Tristan-Wilson d25d882
Add more comments explaining proof enhancement
Tristan-Wilson 274cfec
ProofMarker byte type alias
Tristan-Wilson b99f026
Remove hardcoded values
Tristan-Wilson 905bc0e
Merge branch 'master' into customda-proof-enhancer
Tristan-Wilson 25da751
Move proof enhancer to its own package
Tristan-Wilson 51ad714
Convenience method for creating custom DA proof enhancers
Tristan-Wilson b89fe9d
add comments about enhancement flags
Tristan-Wilson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright 2025, Offchain Labs, Inc. | ||
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE.md | ||
package proofenhancement | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/offchainlabs/nitro/arbutil" | ||
"github.com/offchainlabs/nitro/daprovider" | ||
"github.com/offchainlabs/nitro/staker" | ||
) | ||
|
||
const ( | ||
// Enhancement flag in machine status byte (first byte in proof) | ||
ProofEnhancementFlag = 0x80 | ||
|
||
// Marker bytes for different enhancement types (last byte in an un-enhanced proof) | ||
MarkerCustomDAReadPreimage = 0xDA | ||
MarkerCustomDAValidateCertificate = 0xDB | ||
|
||
// SequencerMessageHeaderSize is the size of the sequencer message header | ||
// (MinTimestamp + MaxTimestamp + MinL1Block + MaxL1Block + AfterDelayedMessages = 8+8+8+8+8) | ||
SequencerMessageHeaderSize = 40 | ||
|
||
// Sizes for proof enhancement marker data | ||
CertificateHashSize = 32 // Size of keccak256 hash of the certificate | ||
OffsetSize = 8 // Size of uint64 offset | ||
MarkerSize = 1 // Size of marker byte | ||
CertificateSizeFieldSize = 8 // Size of uint64 certificate size field | ||
|
||
// MinCertificateSize is the minimum size of a certificate (just the header byte). | ||
// Real certificates will have more data, but the proof enhancer system doesn't | ||
// put any further constraints on certificate structure. | ||
MinCertificateSize = 1 | ||
) | ||
|
||
// ProofMarker identifies the type of proof enhancement needed | ||
type ProofMarker byte | ||
|
||
// ProofEnhancer enhances one-step proofs with additional data. | ||
// For proving certain opcodes, like for CustomDA, Arbitrator doesn't have enough information | ||
// to generate the full proofs. In the case of CustomDA, daprovider implementations usually | ||
// need network access to talk to external DA systems to get full proof details. To indicate | ||
// that a proof needs enhancement, Arbitrator sets the ProofEnhancementFlag on the machine | ||
// status byte of the proof that it returns, and also appends one of the Marker bytes to | ||
// indicate which ProofEnhancer is required. | ||
type ProofEnhancer interface { | ||
// EnhanceProof checks if enhancement is needed and applies it | ||
// Returns the enhanced proof or the original if no enhancement needed | ||
EnhanceProof(ctx context.Context, messageNum arbutil.MessageIndex, proof []byte) ([]byte, error) | ||
} | ||
|
||
// ProofEnhancementManager allows registration of ProofEnhancers and provides forwarding of EnhanceProof | ||
// requests to the appropriate ProofEnhancer. | ||
type ProofEnhancementManager struct { | ||
enhancers map[ProofMarker]ProofEnhancer | ||
} | ||
|
||
// NewProofEnhancementManager creates a new proof enhancement manager | ||
func NewProofEnhancementManager() *ProofEnhancementManager { | ||
return &ProofEnhancementManager{ | ||
enhancers: make(map[ProofMarker]ProofEnhancer), | ||
} | ||
} | ||
|
||
// NewCustomDAProofEnhancer creates a ProofEnhancementManager pre-configured with both | ||
// CustomDA proof enhancers (ReadPreimage and ValidateCertificate). This is the recommended | ||
// constructor for production use with CustomDA systems. | ||
// | ||
// For testing or custom configurations, use NewProofEnhancementManager and RegisterEnhancer directly. | ||
func NewCustomDAProofEnhancer( | ||
daValidator daprovider.Validator, | ||
inboxTracker staker.InboxTrackerInterface, | ||
inboxReader staker.InboxReaderInterface, | ||
) *ProofEnhancementManager { | ||
manager := NewProofEnhancementManager() | ||
|
||
// Register both CustomDA enhancers | ||
manager.RegisterEnhancer( | ||
MarkerCustomDAReadPreimage, | ||
NewReadPreimageProofEnhancer(daValidator, inboxTracker, inboxReader), | ||
) | ||
manager.RegisterEnhancer( | ||
MarkerCustomDAValidateCertificate, | ||
NewValidateCertificateProofEnhancer(daValidator, inboxTracker, inboxReader), | ||
) | ||
|
||
return manager | ||
} | ||
|
||
// RegisterEnhancer registers an enhancer for a specific marker byte | ||
func (m *ProofEnhancementManager) RegisterEnhancer(marker ProofMarker, enhancer ProofEnhancer) { | ||
m.enhancers[marker] = enhancer | ||
} | ||
|
||
// EnhanceProof implements ProofEnhancer interface to forward EnhanceProof requests | ||
// to the appropriate registered ProofEnhancer implementation, if there is any | ||
// and proof enhancement was requested. | ||
func (m *ProofEnhancementManager) EnhanceProof(ctx context.Context, messageNum arbutil.MessageIndex, proof []byte) ([]byte, error) { | ||
rauljordan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if len(proof) == 0 { | ||
return proof, nil | ||
} | ||
|
||
// Check if enhancement flag is set | ||
if proof[0]&ProofEnhancementFlag == 0 { | ||
return proof, nil // No enhancement needed | ||
} | ||
|
||
// Find marker at end of proof | ||
if len(proof) < 2 { // Need at least the marker byte after the enhancement flag | ||
return nil, fmt.Errorf("proof too short for enhancement: %d bytes", len(proof)) | ||
} | ||
marker := ProofMarker(proof[len(proof)-1]) | ||
enhancer, exists := m.enhancers[marker] | ||
if !exists { | ||
return nil, fmt.Errorf("unknown enhancement marker: 0x%02x", marker) | ||
} | ||
|
||
// Remove enhancement flag from machine status | ||
enhancedProof := make([]byte, len(proof)) | ||
copy(enhancedProof, proof) | ||
enhancedProof[0] &= ^byte(ProofEnhancementFlag) | ||
|
||
// Let specific enhancer handle the proof | ||
return enhancer.EnhanceProof(ctx, messageNum, enhancedProof) | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
why not register both enhancers directly here?
That'll allow you to keep the separate enhancers private, and if I understand correctly - these exact two enhancers are used by our "static" node
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 made a convenience method to construct the enhancement manager directly with the customda enhancers, that Nitro can use.
I didn't make the enhancers private because system tests need to create them and wrap them to get the evil enhancer behavior.