@@ -64,8 +64,8 @@ function DynamicArray<
6464 let innerType : Provable < ProvableValue , Value > = ProvableType . get ( type ) ;
6565
6666 // assert capacity bounds
67- assert ( capacity >= 0 , 'capacity must be >= 0' ) ;
68- assert ( capacity < 2 ** 16 , 'capacity must be < 2^16' ) ;
67+ assert ( capacity >= 0 , 'DynamicArray(): capacity must be >= 0' ) ;
68+ assert ( capacity < 2 ** 16 , 'DynamicArray(): capacity must be < 2^16' ) ;
6969
7070 class DynamicArray_ extends DynamicArrayBase < ProvableValue , Value > {
7171 get innerType ( ) {
@@ -101,10 +101,10 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
101101
102102 // properties to override in subclass
103103 get innerType ( ) : Provable < ProvableValue , Value > {
104- throw Error ( 'Inner type must be defined in a subclass. ' ) ;
104+ throw Error ( 'Inner type must be defined in a subclass' ) ;
105105 }
106106 static get capacity ( ) : number {
107- throw Error ( 'Capacity must be defined in a subclass. ' ) ;
107+ throw Error ( 'Capacity must be defined in a subclass' ) ;
108108 }
109109
110110 // derived property
@@ -147,12 +147,12 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
147147
148148 assert (
149149 a . length <= this . capacity ,
150- 'Array must not exceed capacity'
150+ 'DynamicArray(): array must not exceed capacity'
151151 ) ;
152152 if ( length ?. isConstant ( ) ) {
153153 assert (
154154 l . toBigInt ( ) <= BigInt ( a . length ) ,
155- 'length must be at most as long as the array'
155+ 'DynamicArray(): length must be at most as long as the array'
156156 ) ;
157157 }
158158
@@ -164,14 +164,19 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
164164 * In-circuit assertion that the given index is within the bounds of the
165165 * dynamic array.
166166 * Asserts 0 <= i < this.length, using a cached check that's not
167- * duplicated when doing it on the same variable multiple times.
167+ * duplicated when doing it on the same variable multiple times, failing
168+ * with an error message otherwise.
169+ *
170+ * @param i - the index to check
171+ * @param message - optional error message to use in case the assertion fails
168172 */
169- assertIndexInRange ( i : Field ) : void {
173+ assertIndexInRange ( i : Field , message ?: string ) : void {
174+ let errorMessage = message ?? `assertIndexInRange(): index ${ i } must be in range [0, ${ this . length } ]` ;
170175 if ( ! this . #indicesInRange. has ( i ) ) {
171176 if ( i . isConstant ( ) && this . length . isConstant ( ) ) {
172- assert ( i . toBigInt ( ) < this . length . toBigInt ( ) , 'assertIndexInRange' ) ;
177+ assert ( i . toBigInt ( ) < this . length . toBigInt ( ) , errorMessage ) ;
173178 }
174- i . lessThan ( this . length ) . assertTrue ( ) ;
179+ i . assertLessThan ( this . length , errorMessage ) ;
175180 this . #indicesInRange. add ( i ) ;
176181 }
177182 }
@@ -232,8 +237,9 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
232237 /**
233238 * Sets a value at index i and proves that the index is in the array.
234239 */
235- set ( i : Field , value : ProvableValue ) : void {
236- this . assertIndexInRange ( i ) ;
240+ set ( i : Field , value : ProvableValue , message ?: string ) : void {
241+ let errorMessage = message ?? `set(): index ${ i } must be in range [0, ${ this . length } ]` ;
242+ this . assertIndexInRange ( i , errorMessage ) ;
237243 this . setOrDoNothing ( i , value ) ;
238244 }
239245
@@ -286,9 +292,14 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
286292 *
287293 * **Note**: this doesn't cost constraints, but currently doesn't preserve any
288294 * cached constraints.
295+ *
296+ * @param capacity - the new capacity of the array
289297 */
290- growCapacityTo ( capacity : number ) : DynamicArray < ProvableValue , Value > {
291- assert ( capacity >= this . capacity , 'new capacity must be greater or equal' ) ;
298+ growCapacityTo ( capacity : number , message ?: string ) : DynamicArray < ProvableValue , Value > {
299+ let errorMessage =
300+ message ??
301+ `growCapacityTo: new capacity ${ capacity } must be greater than current capacity ${ this . capacity } ` ;
302+ assert ( capacity >= this . capacity , errorMessage ) ;
292303 let NewArray = DynamicArray ( this . innerType , { capacity } ) ;
293304 let NULL = ProvableType . synthesize ( this . innerType ) ;
294305 let array = pad ( this . array , capacity , NULL ) ;
@@ -302,20 +313,19 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
302313 *
303314 * **Note**: this doesn't cost constraints, but currently doesn't preserve any
304315 * cached constraints.
316+ *
317+ * @param increment - the amount to increase the capacity by
305318 */
306319 growCapacityBy ( increment : number ) : DynamicArray < ProvableValue > {
307320 return this . growCapacityTo ( this . capacity + increment ) ;
308321 }
309322
310323 /**
311324 * Increments the length of the current array by n elements, checking that the
312- * new length is within the capacity.
313- *
314- * An optional error message can be provided to be used in case the inner
315- * assertion fails.
325+ * new length is within the capacity, failing with the error message otherwise.
316326 *
317- * @param n
318- * @param message
327+ * @param n - the number of elements to increase the length by
328+ * @param message - optional error message to use in case the assertion fails
319329 */
320330 increaseLengthBy ( n : Field , message ?: string ) : void {
321331 let errorMessage =
@@ -329,13 +339,11 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
329339
330340 /**
331341 * Decrements the length of the current array by `n` elements, checking that
332- * the `n` is less or equal than the current length.
342+ * the `n` is less or equal than the current length, failing with the error
343+ * message otherwise.
333344 *
334- * An optional error message can be provided to be used in case the inner
335- * assertion fails.
336- *
337- * @param n
338- * @param message
345+ * @param n - the number of elements to decrease the length by
346+ * @param message - optional error message to use in case the assertion fails
339347 */
340348 decreaseLengthBy ( n : Field , message ?: string ) : void {
341349 let errorMessage =
@@ -354,13 +362,16 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
354362 * An optional error message can be provided to be used in case the inner
355363 * assertion fails.
356364 *
357- * @param newLength
358- * @param message
365+ * @param newLength - the new length to set the array to
366+ * @param message - optional error message
359367 *
360368 * **Warning**: This does not change (add nor remove) the values of the array.
361369 */
362370 setLengthTo ( n : Field , message ?: string ) : void {
363- n . assertLessThanOrEqual ( new Field ( this . capacity ) ) ;
371+ let errorMessage =
372+ message ??
373+ `setLengthTo: cannot set length to ${ n } because it exceeds capacity ${ this . capacity } ` ;
374+ n . assertLessThanOrEqual ( new Field ( this . capacity ) , errorMessage ) ;
364375 this . length = n ;
365376 }
366377
@@ -375,10 +386,16 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
375386 * array = array.growCapacityhBy(1);
376387 * array.push(value);
377388 * ```
389+ *
390+ * @param value - the value to push into the array
391+ * @param message - optional error message to use in case the assertion fails
378392 */
379- push ( value : ProvableValue ) : void {
393+ push ( value : ProvableValue , message ?: string ) : void {
394+ let errorMessage =
395+ message ??
396+ `push(): cannot push value because it would exceed capacity ${ this . capacity } .` ;
380397 let oldLength = this . length ;
381- this . increaseLengthBy ( new Field ( 1 ) ) ;
398+ this . increaseLengthBy ( new Field ( 1 ) , errorMessage ) ;
382399 this . setOrDoNothing ( oldLength , value ) ;
383400 }
384401
@@ -387,11 +404,16 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
387404 * by n. If no amount is provided, only one element is popped. The popped
388405 * positions are set to NULL values.
389406 *
390- * @param n
407+ * @param n - the number of elements to pop (one if not provided)
408+ * @param message - optional error message to use in case the assertion fails
391409 */
392- pop ( n ?: Field ) : void {
410+ pop ( n ?: Field , message ?: string ) : void {
411+ let errorMessage =
412+ message ??
413+ `pop(): cannot pop ${ n } elements because the length is smaller` ;
414+
393415 let dec = n !== undefined ? n : new Field ( 1 ) ;
394- this . decreaseLengthBy ( dec ) ;
416+ this . decreaseLengthBy ( dec , errorMessage ) ;
395417
396418 let NULL : ProvableValue = ProvableType . synthesize ( this . innerType ) ;
397419 if ( n !== undefined ) {
@@ -420,12 +442,17 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
420442 }
421443
422444 /**
423- * Shifts all elements of the array to the left by n positions, reducing the
424- * length by n, which must be less than or equal to the current length.
445+ * Shifts all elements of the array to the left by `n` positions, reducing
446+ * the length by `n`, which must be less than or equal to the current length
447+ * (failing with an error message otherwise).
425448 *
426- * @param n
449+ * @param n - the number of positions to shift left
450+ * @param message - optional error message to use in case the assertion fails
427451 */
428- shiftLeft ( n : Field ) : void {
452+ shiftLeft ( n : Field , message ?: string ) : void {
453+ let errorMessage =
454+ message ??
455+ `shiftLeft(): cannot shift left because provided n would exceed current length.` ;
429456 let NULL = ProvableType . synthesize ( this . innerType ) ;
430457 for ( let i = 0 ; i < this . capacity ; i ++ ) {
431458 let offset = new Field ( i ) . add ( n ) ;
@@ -436,18 +463,23 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
436463 NULL
437464 ) ;
438465 }
439- this . decreaseLengthBy ( n ) ;
466+ this . decreaseLengthBy ( n , errorMessage ) ;
440467 }
441468
442469 /**
443- * Shifts all elements of the array to the right by n positions, increasing
444- * the length by n, which must result in less than or equal to the capacity.
445- * The new elements on the left are set to NULL values.
470+ * Shifts all elements of the array to the right by `n` positions, increasing
471+ * the length by `n`, which must result in less than or equal to the capacity
472+ * (failing with an error message otherwise). The new elements on the left are
473+ * set to NULL values.
446474 *
447- * @param n
475+ * @param n - the number of positions to shift right
476+ * @param message - optional error message to use in case the assertion fails
448477 */
449- shiftRight ( n : Field ) : void {
450- this . increaseLengthBy ( n ) ;
478+ shiftRight ( n : Field , message ?: string ) : void {
479+ let errorMessage =
480+ message ??
481+ `shiftRight(): cannot shift right because provided n would exceed capacity ${ this . capacity } ` ;
482+ this . increaseLengthBy ( n , errorMessage ) ;
451483 let NULL = ProvableType . synthesize ( this . innerType ) ;
452484
453485 for ( let i = this . capacity - 1 ; i >= 0 ; i -- ) {
@@ -481,16 +513,17 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
481513 * provided, it defaults to 0. If `end` is not provided, it defaults to the
482514 * length of the array.
483515 *
484- * @param start
485- * @param end
486- * @returns
516+ * @param start - the starting index of the slice (inclusive)
517+ * @param end - the ending index of the slice (exclusive)
518+ *
519+ * @returns a new DynamicArray instance with the sliced values
487520 */
488521 slice ( start ?: Field , end ?: Field ) : DynamicArray < ProvableValue , Value > {
489522 start ??= new Field ( 0 ) ;
490523 end ??= this . length ;
491524 let sliced = this . copy ( ) ;
492- sliced . shiftLeft ( start ) ;
493- sliced . pop ( this . length . sub ( end ) ) ;
525+ sliced . shiftLeft ( start , `slice(): provided start is greater than current length` ) ;
526+ sliced . pop ( this . length . sub ( end ) , `slice(): provided end is greater than current length` ) ;
494527 return sliced ;
495528 }
496529
@@ -499,8 +532,9 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
499532 * dynamic array with the values of both arrays. The capacity of the new array
500533 * is the sum of the capacities of the two arrays.
501534 *
502- * @param other
503- * @returns
535+ * @param other - the dynamic array to concatenate
536+ *
537+ * @returns a new DynamicArray instance with the concatenated values
504538 */
505539 concat ( other : DynamicArray < ProvableValue , Value > ) : DynamicArray < ProvableValue , Value > {
506540 let res = this . growCapacityTo ( this . capacity + other . capacity ) ;
@@ -523,12 +557,16 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
523557 * the right by one. The length of the array is increased by one, which must
524558 * result in less than or equal to the capacity.
525559 *
526- * @param i
527- * @param value
560+ * @param i - the index at which to insert the value
561+ * @param value - the value to insert
562+ * @param message - optional error message to use in case the assertion fails
528563 */
529- insert ( index : Field , value : ProvableValue ) : void {
564+ insert ( index : Field , value : ProvableValue , message ?: string ) : void {
565+ let errorMessage =
566+ message ??
567+ `insert(): cannot insert value at index ${ index } because it would exceed capacity ${ this . capacity } .` ;
530568 const right = this . slice ( index , this . length ) ;
531- this . increaseLengthBy ( new Field ( 1 ) ) ;
569+ this . increaseLengthBy ( new Field ( 1 ) , errorMessage ) ;
532570 this . set ( index , value ) ;
533571 for ( let i = 0 ; i < this . capacity ; i ++ ) {
534572 let offset = new Field ( i ) . sub ( index ) . sub ( new Field ( 1 ) ) ;
@@ -544,7 +582,7 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
544582 /**
545583 * Checks whether the dynamic array includes a value.
546584 *
547- * @param value
585+ * @param value - the value to check for inclusion in the array
548586 * @returns
549587 */
550588 includes ( value : ProvableValue ) : Bool {
@@ -596,6 +634,11 @@ class DynamicArrayBase<ProvableValue = any, Value = any> {
596634 return mask ;
597635 }
598636
637+ /**
638+ * Converts the current instance of the dynamic array to a plain array of values.
639+ *
640+ * @returns An array of values representing the elements in the dynamic array.
641+ */
599642 toValue ( ) : Value [ ] {
600643 return ( this . constructor as any as { provable : Provable < any , Value [ ] > } ) . provable . toValue ( this ) ;
601644 }
0 commit comments