@@ -43,36 +43,29 @@ struct AttestationProof {
4343/// @dev The DAVerifier verifies that some shares, which were posted on Celestia, were committed to
4444/// by the QGB smart contract.
4545library DAVerifier {
46- ////////////
47- // Errors //
48- ////////////
49-
50- /// @notice The shares to the rows proof is invalid.
51- /// @param i The index of the invalid proof.
52- error InvalidSharesToRowsProof (uint256 i );
53-
54- /// @notice The rows to the data root proof is invalid.
55- /// @param i The index of the invalid proof.
56- error InvalidRowsToDataRootProof (uint256 i );
57-
58- /// @notice The row to the data root proof is invalid.
59- error InvalidRowToDataRootProof ();
60-
61- /// @notice The data root tuple to the data root tuple roof proof is invalid.
62- error InvalidDataRootTupleToDataRootTupleRootProof ();
63-
64- /// @notice The number of share proofs isn't equal to the number of rows roots.
65- error UnequalShareProofsAndRowRootsNumber ();
66-
67- /// @notice The number of rows proofs isn't equal to the number of rows roots.
68- error UnequalRowProofsAndRowRootsNumber ();
69-
70- /// @notice The verifier data length isn't equal to the number of shares in the shares proofs.
71- error UnequalDataLengthAndNumberOfSharesProofs ();
72-
73- /// @notice The number of leaves in the binary merkle proof is not divisible by 4.
74- /// @param i The provided proof number of leaves.
75- error InvalidNumberOfLeavesInProof (uint256 i );
46+ /////////////////
47+ // Error codes //
48+ /////////////////
49+
50+ enum ErrorCodes {
51+ NoError,
52+ /// @notice The shares to the rows proof is invalid.
53+ InvalidSharesToRowsProof,
54+ /// @notice The rows to the data root proof is invalid.
55+ InvalidRowsToDataRootProof,
56+ /// @notice The row to the data root proof is invalid.
57+ InvalidRowToDataRootProof,
58+ /// @notice The data root tuple to the data root tuple roof proof is invalid.
59+ InvalidDataRootTupleToDataRootTupleRootProof,
60+ /// @notice The number of share proofs isn't equal to the number of rows roots.
61+ UnequalShareProofsAndRowRootsNumber,
62+ /// @notice The number of rows proofs isn't equal to the number of rows roots.
63+ UnequalRowProofsAndRowRootsNumber,
64+ /// @notice The verifier data length isn't equal to the number of shares in the shares proofs.
65+ UnequalDataLengthAndNumberOfSharesProofs,
66+ /// @notice The number of leaves in the binary merkle proof is not divisible by 4.
67+ InvalidNumberOfLeavesInProof
68+ }
7669
7770 ///////////////
7871 // Functions //
@@ -83,20 +76,23 @@ library DAVerifier {
8376 /// @param _sharesProof The proof of the shares to the data root tuple root.
8477 /// @param _root The data root of the block that contains the shares.
8578 /// @return `true` if the proof is valid, `false` otherwise.
79+ /// @return an error code if the proof is invalid, ErrorCodes.NoError otherwise.
8680 function verifySharesToDataRootTupleRoot (IDAOracle _bridge , SharesProof memory _sharesProof , bytes32 _root )
8781 external
8882 view
89- returns (bool )
83+ returns (bool , ErrorCodes )
9084 {
91- // checking that the data root was committed to by the QGB smart contract
92- // this will revert if the proof is not valid
93- verifyMultiRowRootsToDataRootTupleRoot (
85+ // checking that the data root was committed to by the QGB smart contract.
86+ (bool success , ErrorCodes errorCode ) = verifyMultiRowRootsToDataRootTupleRoot (
9487 _bridge, _sharesProof.rowRoots, _sharesProof.rowProofs, _sharesProof.attestationProof, _root
9588 );
89+ if (! success) {
90+ return (false , errorCode);
91+ }
9692
9793 // checking that the shares were committed to by the rows roots.
9894 if (_sharesProof.shareProofs.length != _sharesProof.rowRoots.length ) {
99- revert UnequalShareProofsAndRowRootsNumber ( );
95+ return ( false , ErrorCodes.UnequalShareProofsAndRowRootsNumber );
10096 }
10197
10298 uint256 numberOfSharesInProofs = 0 ;
@@ -105,7 +101,7 @@ library DAVerifier {
105101 }
106102
107103 if (_sharesProof.data.length != numberOfSharesInProofs) {
108- revert UnequalDataLengthAndNumberOfSharesProofs ( );
104+ return ( false , ErrorCodes.UnequalDataLengthAndNumberOfSharesProofs );
109105 }
110106
111107 uint256 cursor = 0 ;
@@ -121,12 +117,12 @@ library DAVerifier {
121117 slice (_sharesProof.data, cursor, cursor + sharesUsed)
122118 )
123119 ) {
124- revert InvalidSharesToRowsProof (i );
120+ return ( false , ErrorCodes.InvalidSharesToRowsProof );
125121 }
126122 cursor += sharesUsed;
127123 }
128124
129- return true ;
125+ return ( true , ErrorCodes.NoError) ;
130126 }
131127
132128 /// @notice Verifies that a row/column root, from a Celestia block, was committed to by the QGB smart contract.
@@ -135,28 +131,29 @@ library DAVerifier {
135131 /// @param _rowProof The proof of the row/column root to the data root.
136132 /// @param _root The data root of the block that contains the row.
137133 /// @return `true` if the proof is valid, `false` otherwise.
134+ /// @return an error code if the proof is invalid, ErrorCodes.NoError otherwise.
138135 function verifyRowRootToDataRootTupleRoot (
139136 IDAOracle _bridge ,
140137 NamespaceNode memory _rowRoot ,
141138 BinaryMerkleProof memory _rowProof ,
142139 AttestationProof memory _attestationProof ,
143140 bytes32 _root
144- ) public view returns (bool ) {
141+ ) public view returns (bool , ErrorCodes ) {
145142 // checking that the data root was committed to by the QGB smart contract
146143 if (
147144 ! _bridge.verifyAttestation (
148145 _attestationProof.tupleRootNonce, _attestationProof.tuple, _attestationProof.proof
149146 )
150147 ) {
151- revert InvalidDataRootTupleToDataRootTupleRootProof ( );
148+ return ( false , ErrorCodes.InvalidDataRootTupleToDataRootTupleRootProof );
152149 }
153150
154151 bytes memory rowRoot = abi.encodePacked (_rowRoot.min.toBytes (), _rowRoot.max.toBytes (), _rowRoot.digest);
155152 if (! BinaryMerkleTree.verify (_root, _rowProof, rowRoot)) {
156- revert InvalidRowToDataRootProof ( );
153+ return ( false , ErrorCodes.InvalidRowToDataRootProof );
157154 }
158155
159- return true ;
156+ return ( true , ErrorCodes.NoError) ;
160157 }
161158
162159 /// @notice Verifies that a set of rows/columns, from a Celestia block, were committed to by the QGB smart contract.
@@ -165,36 +162,37 @@ library DAVerifier {
165162 /// @param _rowProofs The set of proofs of the _rowRoots in the same order.
166163 /// @param _root The data root of the block that contains the rows.
167164 /// @return `true` if the proof is valid, `false` otherwise.
165+ /// @return an error code if the proof is invalid, ErrorCodes.NoError otherwise.
168166 function verifyMultiRowRootsToDataRootTupleRoot (
169167 IDAOracle _bridge ,
170168 NamespaceNode[] memory _rowRoots ,
171169 BinaryMerkleProof[] memory _rowProofs ,
172170 AttestationProof memory _attestationProof ,
173171 bytes32 _root
174- ) public view returns (bool ) {
172+ ) public view returns (bool , ErrorCodes ) {
175173 // checking that the data root was committed to by the QGB smart contract
176174 if (
177175 ! _bridge.verifyAttestation (
178176 _attestationProof.tupleRootNonce, _attestationProof.tuple, _attestationProof.proof
179177 )
180178 ) {
181- revert InvalidDataRootTupleToDataRootTupleRootProof ( );
179+ return ( false , ErrorCodes.InvalidDataRootTupleToDataRootTupleRootProof );
182180 }
183181
184182 // checking that the rows roots commit to the data root.
185183 if (_rowProofs.length != _rowRoots.length ) {
186- revert UnequalRowProofsAndRowRootsNumber ( );
184+ return ( false , ErrorCodes.UnequalRowProofsAndRowRootsNumber );
187185 }
188186
189187 for (uint256 i = 0 ; i < _rowProofs.length ; i++ ) {
190188 bytes memory rowRoot =
191189 abi.encodePacked (_rowRoots[i].min.toBytes (), _rowRoots[i].max.toBytes (), _rowRoots[i].digest);
192190 if (! BinaryMerkleTree.verify (_root, _rowProofs[i], rowRoot)) {
193- revert InvalidRowsToDataRootProof (i );
191+ return ( false , ErrorCodes.InvalidRowsToDataRootProof );
194192 }
195193 }
196194
197- return true ;
195+ return ( true , ErrorCodes.NoError) ;
198196 }
199197
200198 /// @notice computes the Celestia block square size from a row/column root to data root binary merkle proof.
@@ -204,13 +202,18 @@ library DAVerifier {
204202 /// Note: the minimum square size is 1. Thus, we don't expect the proof to have number of leaves equal to 0.
205203 /// @param _proof The proof of the row/column root to the data root.
206204 /// @return The square size of the corresponding block.
207- function computeSquareSizeFromRowProof (BinaryMerkleProof memory _proof ) external pure returns (uint256 ) {
205+ /// @return an error code if the _proof is invalid, Errors.NoError otherwise.
206+ function computeSquareSizeFromRowProof (BinaryMerkleProof memory _proof )
207+ external
208+ pure
209+ returns (uint256 , ErrorCodes)
210+ {
208211 if (_proof.numLeaves % 4 != 0 ) {
209- revert InvalidNumberOfLeavesInProof (_proof.numLeaves );
212+ return ( 0 , ErrorCodes.InvalidNumberOfLeavesInProof );
210213 }
211214 // we divide the number of leaves of the proof by 4 because the rows/columns tree is constructed
212215 // from the extended block row roots and column roots.
213- return _proof.numLeaves / 4 ;
216+ return ( _proof.numLeaves / 4 , ErrorCodes.NoError) ;
214217 }
215218
216219 /// @notice computes the Celestia block square size from a shares to row/column root proof.
0 commit comments