@btc-vision/btc-runtime 1.4.5 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ import { Blockchain } from '../env';
5
5
  import { encodePointer } from '../math/abi';
6
6
  import { MemorySlotPointer } from '../memory/MemorySlotPointer';
7
7
  import { Revert } from '../types/Revert';
8
- import { U256_BYTE_LENGTH } from '../utils/lengths';
8
+ import { U256_BYTE_LENGTH } from '../utils';
9
9
 
10
10
  // Similar to a struct in Solidity. (Use in worst case scenario, consume a lot of gas)
11
11
  export abstract class Serializable {
@@ -54,12 +54,16 @@ export abstract class Serializable {
54
54
  if (chunks.length !== this.chunkCount) {
55
55
  throw new Revert(
56
56
  'Invalid chunk count, expected ' +
57
- this.chunkCount.toString() +
58
- ' but got ' +
59
- chunks.length.toString(),
57
+ this.chunkCount.toString() +
58
+ ' but got ' +
59
+ chunks.length.toString(),
60
60
  );
61
61
  }
62
62
 
63
+ if (chunks.length > 255) {
64
+ throw new Revert('Too many chunks to save. You may only write up to 8160 bytes per object.');
65
+ }
66
+
63
67
  for (let index: u8 = 0; index < u8(chunks.length); index++) {
64
68
  Blockchain.setStorageAt(this.getPointer(this.subPointer, index), chunks[index]);
65
69
  }
@@ -69,8 +73,8 @@ export abstract class Serializable {
69
73
  const chunks: u256[] = [];
70
74
 
71
75
  for (let index: i32 = 0; index < buffer.byteLength; index += 32) {
72
- if (chunks.length === 255) {
73
- throw new Revert('Too many chunks to save');
76
+ if (chunks.length === 256) {
77
+ throw new Revert(`Too many chunks to save You may only write up to 8160 bytes per object.`);
74
78
  }
75
79
 
76
80
  const chunk = buffer.slice(index, index + 32);
@@ -81,12 +85,11 @@ export abstract class Serializable {
81
85
  }
82
86
 
83
87
  protected chunksToBytes(chunks: u256[]): BytesReader {
84
- if (this.chunkCount >= u8(255)) {
85
- //67108863
86
- throw new Revert('Too many chunks received');
88
+ if (this.chunkCount > u8(255)) {
89
+ throw new Revert(`Too many chunks received. You may only write up to 8160 bytes per object.`);
87
90
  }
88
91
 
89
- const buffer: Uint8Array = new Uint8Array(this.chunkCount * 32);
92
+ const buffer: Uint8Array = new Uint8Array(i32(this.chunkCount) * i32(32));
90
93
  let offset: i32 = 0;
91
94
 
92
95
  for (let indexChunk: i32 = 0; indexChunk < chunks.length; indexChunk++) {
@@ -65,7 +65,10 @@ export class StoredAddressArray {
65
65
  */
66
66
  @inline
67
67
  public get(index: u64): Address {
68
- assert(index < this._length, 'Index out of bounds');
68
+ if (index >= this._length) {
69
+ throw new Revert('Get operation failed: Index out of bounds.');
70
+ }
71
+
69
72
  const slotIndex: u32 = <u32>index;
70
73
  this.ensureValues(slotIndex);
71
74
  const value = this._values.get(slotIndex);
@@ -80,7 +83,10 @@ export class StoredAddressArray {
80
83
  */
81
84
  @inline
82
85
  public set(index: u64, value: Address): void {
83
- assert(index < this._length, 'Index exceeds current array length');
86
+ if (index > this.MAX_LENGTH) {
87
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
88
+ }
89
+
84
90
  const slotIndex: u32 = <u32>index;
85
91
  this.ensureValues(slotIndex);
86
92
 
@@ -125,7 +131,7 @@ export class StoredAddressArray {
125
131
  * @param {Address} value - The Address to append.
126
132
  */
127
133
  public push(value: Address): void {
128
- if (this._length >= this.MAX_LENGTH) {
134
+ if (this._length > this.MAX_LENGTH) {
129
135
  throw new Revert(
130
136
  'Push operation failed: Array has reached its maximum allowed length.',
131
137
  );
@@ -197,37 +203,6 @@ export class StoredAddressArray {
197
203
  }
198
204
  }
199
205
 
200
- /**
201
- * @method shift
202
- * @description Removes the first element of the array.
203
- */
204
- public shift(): void {
205
- if (this._length === 0) {
206
- throw new Revert('Shift operation failed: Array is empty.');
207
- }
208
-
209
- const currentStartIndex: u64 = this._startIndex;
210
- const slotIndex: u32 = <u32>currentStartIndex;
211
- this.ensureValues(slotIndex);
212
-
213
- const currentValue = this._values.get(slotIndex);
214
- if (currentValue != this.defaultValue) {
215
- this._values.set(slotIndex, this.defaultValue);
216
- this._isChanged.add(slotIndex);
217
- }
218
-
219
- this._length -= 1;
220
- this._isChangedLength = true;
221
-
222
- // Increment the startIndex with wrap-around
223
- if (this._startIndex < this.MAX_LENGTH - 1) {
224
- this._startIndex += 1;
225
- } else {
226
- this._startIndex = 0;
227
- }
228
- this._isChangedStartIndex = true;
229
- }
230
-
231
206
  /**
232
207
  * @method save
233
208
  * @description Persists all changes to storage.
@@ -303,7 +278,10 @@ export class StoredAddressArray {
303
278
  */
304
279
  @inline
305
280
  public getAll(startIndex: u32, count: u32): Address[] {
306
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
281
+ if ((startIndex + count) > this._length) {
282
+ throw new Revert('Requested range exceeds array length');
283
+ }
284
+
307
285
  const result: Address[] = new Array<Address>(count);
308
286
  for (let i: u32 = 0; i < count; i++) {
309
287
  result[i] = this.get(<u64>(startIndex + i));
@@ -383,27 +361,6 @@ export class StoredAddressArray {
383
361
  return this._startIndex;
384
362
  }
385
363
 
386
- /**
387
- * @method setLength
388
- * @description Sets the length of the array, truncating if necessary.
389
- * @param {u64} newLength - The new length.
390
- */
391
- public setLength(newLength: u64): void {
392
- if (newLength > this.MAX_LENGTH) {
393
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
394
- }
395
-
396
- if (newLength < this._length) {
397
- // Truncate the array if newLength is smaller
398
- for (let i: u64 = newLength; i < this._length; i++) {
399
- this.delete(i);
400
- }
401
- }
402
-
403
- this._length = newLength;
404
- this._isChangedLength = true;
405
- }
406
-
407
364
  /**
408
365
  * @private
409
366
  * @method ensureValues
@@ -64,7 +64,9 @@ export class StoredBooleanArray {
64
64
  */
65
65
  @inline
66
66
  public get(index: u64): bool {
67
- assert(index < this._length, 'Index out of bounds');
67
+ if (index >= this._length) {
68
+ return false;
69
+ }
68
70
 
69
71
  const slotIndex: u64 = index / 256; // Each slot holds 256 bits
70
72
  const bitIndex: u16 = <u16>(index % 256); // 0 to 255
@@ -85,7 +87,10 @@ export class StoredBooleanArray {
85
87
  */
86
88
  @inline
87
89
  public set(index: u64, value: bool): void {
88
- assert(index < this._length, 'Index exceeds current array length');
90
+ if (index > this.MAX_LENGTH) {
91
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
92
+ }
93
+
89
94
  const slotIndex: u64 = index / 256;
90
95
  const bitIndex: u16 = <u16>(index % 256);
91
96
  this.ensureValues(slotIndex);
@@ -106,7 +111,7 @@ export class StoredBooleanArray {
106
111
  * @param {bool} value - The boolean value to append.
107
112
  */
108
113
  public push(value: bool): void {
109
- if (this._length >= this.MAX_LENGTH) {
114
+ if (this._length > this.MAX_LENGTH) {
110
115
  throw new Revert(
111
116
  'Push operation failed: Array has reached its maximum allowed length.',
112
117
  );
@@ -158,43 +163,6 @@ export class StoredBooleanArray {
158
163
  }
159
164
  }
160
165
 
161
- /**
162
- * @method shift
163
- * @description Removes the first element of the array by setting it to false, decrementing the length, and incrementing the startIndex.
164
- * If the startIndex reaches the maximum value of u64, it wraps around to 0.
165
- */
166
- public shift(): void {
167
- if (this._length === 0) {
168
- throw new Revert('Shift operation failed: Array is empty.');
169
- }
170
-
171
- const currentStartIndex: u64 = this._startIndex;
172
- const slotIndex: u64 = currentStartIndex / 256;
173
- const bitIndex: u16 = <u16>(currentStartIndex % 256);
174
- this.ensureValues(slotIndex);
175
-
176
- const slotValue = this._values.get(slotIndex);
177
- if (slotValue) {
178
- const oldValue = this.getBit(slotValue, bitIndex);
179
- if (oldValue != false) {
180
- this.setBit(slotValue, bitIndex, false);
181
- this._isChanged.add(slotIndex);
182
- }
183
- }
184
-
185
- // Decrement the length
186
- this._length -= 1;
187
- this._isChangedLength = true;
188
-
189
- // Increment the startIndex with wrap-around
190
- if (this._startIndex < this.MAX_LENGTH - 1) {
191
- this._startIndex += 1;
192
- } else {
193
- this._startIndex = 0;
194
- }
195
- this._isChangedStartIndex = true;
196
- }
197
-
198
166
  /**
199
167
  * @method save
200
168
  * @description Persists all cached boolean values, the length, and the startIndex to their respective storage slots if any have been modified.
@@ -272,7 +240,9 @@ export class StoredBooleanArray {
272
240
  */
273
241
  @inline
274
242
  public getAll(startIndex: u64, count: u64): bool[] {
275
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
243
+ if ((startIndex + count) > this._length) {
244
+ throw new Revert('Requested range exceeds array length');
245
+ }
276
246
 
277
247
  if (u32.MAX_VALUE < count) {
278
248
  throw new Revert('Requested range exceeds maximum allowed value.');
@@ -366,27 +336,6 @@ export class StoredBooleanArray {
366
336
  return this._startIndex;
367
337
  }
368
338
 
369
- /**
370
- * @method setLength
371
- * @description Sets the length of the array.
372
- * @param {u64} newLength - The new length to set.
373
- */
374
- public setLength(newLength: u64): void {
375
- if (newLength > this.MAX_LENGTH) {
376
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
377
- }
378
-
379
- if (newLength < this._length) {
380
- // Truncate the array if newLength is smaller
381
- for (let i: u64 = newLength; i < this._length; i++) {
382
- this.delete(i);
383
- }
384
- }
385
-
386
- this._length = newLength;
387
- this._isChangedLength = true;
388
- }
389
-
390
339
  /**
391
340
  * @method deleteLast
392
341
  * @description Deletes the last element of the array by setting it to false and decrementing the length.
@@ -440,7 +389,9 @@ export class StoredBooleanArray {
440
389
  * @returns {bool} - The value of the bit at the specified index.
441
390
  */
442
391
  private getBit(value: u256, bitIndex: u16): bool {
443
- assert(bitIndex < 256, 'Bit index out of range');
392
+ if (!(bitIndex < 256)) {
393
+ throw new Revert('Bit index out of range');
394
+ }
444
395
 
445
396
  if (bitIndex < 64) {
446
397
  return ((value.lo1 >> bitIndex) & 0b1) == 1;
@@ -462,7 +413,9 @@ export class StoredBooleanArray {
462
413
  * @param {bool} bitValue - The value to set (true or false).
463
414
  */
464
415
  private setBit(value: u256, bitIndex: u16, bitValue: bool): void {
465
- assert(bitIndex < 256, 'Bit index out of range');
416
+ if (!(bitIndex < 256)) {
417
+ throw new Revert('Bit index out of range');
418
+ }
466
419
 
467
420
  if (bitIndex < 64) {
468
421
  const mask = u64(1) << bitIndex;
@@ -64,7 +64,10 @@ export class StoredU128Array {
64
64
  */
65
65
  @inline
66
66
  public get(index: u64): u128 {
67
- assert(index < this._length, 'Index out of bounds');
67
+ if (index >= this._length) {
68
+ return u128.Zero;
69
+ }
70
+
68
71
  const slotIndex: u32 = <u32>(index / 2); // Each slot holds two u128s
69
72
  const subIndex: u8 = <u8>(index % 2); // 0 or 1
70
73
  this.ensureValues(slotIndex);
@@ -84,7 +87,10 @@ export class StoredU128Array {
84
87
  */
85
88
  @inline
86
89
  public set(index: u64, value: u128): void {
87
- assert(index < this._length, 'Index exceeds current array length');
90
+ if (index > this.MAX_LENGTH) {
91
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
92
+ }
93
+
88
94
  const slotIndex: u32 = <u32>(index / 2);
89
95
  const subIndex: u8 = <u8>(index % 2);
90
96
  this.ensureValues(slotIndex);
@@ -103,7 +109,7 @@ export class StoredU128Array {
103
109
  * @param {u128} value - The u128 value to append.
104
110
  */
105
111
  public push(value: u128): void {
106
- if (this._length >= this.MAX_LENGTH) {
112
+ if (this._length > this.MAX_LENGTH) {
107
113
  throw new Revert(
108
114
  'Push operation failed: Array has reached its maximum allowed length.',
109
115
  );
@@ -155,43 +161,6 @@ export class StoredU128Array {
155
161
  }
156
162
  }
157
163
 
158
- /**
159
- * @method shift
160
- * @description Removes the first element of the array by setting it to zero, decrementing the length, and incrementing the startIndex.
161
- * If the startIndex reaches the maximum value of u64, it wraps around to 0.
162
- */
163
- public shift(): void {
164
- if (this._length === 0) {
165
- throw new Revert('Shift operation failed: Array is empty.');
166
- }
167
-
168
- const currentStartIndex: u64 = this._startIndex;
169
- const slotIndex: u32 = <u32>(currentStartIndex / 2);
170
- const subIndex: u8 = <u8>(currentStartIndex % 2);
171
- this.ensureValues(slotIndex);
172
-
173
- const slotValues = this._values.get(slotIndex);
174
- if (slotValues) {
175
- // Set the current start element to zero
176
- if (!u128.eq(slotValues[subIndex], u128.Zero)) {
177
- slotValues[subIndex] = u128.Zero;
178
- this._isChanged.add(slotIndex);
179
- }
180
- }
181
-
182
- // Decrement the length
183
- this._length -= 1;
184
- this._isChangedLength = true;
185
-
186
- // Increment the startIndex with wrap-around
187
- if (this._startIndex < this.MAX_LENGTH - 1) {
188
- this._startIndex += 1;
189
- } else {
190
- this._startIndex = 0;
191
- }
192
- this._isChangedStartIndex = true;
193
- }
194
-
195
164
  /**
196
165
  * @method save
197
166
  * @description Persists all cached u128 values, the length, and the startIndex to their respective storage slots if any have been modified.
@@ -280,7 +249,10 @@ export class StoredU128Array {
280
249
  */
281
250
  @inline
282
251
  public getAll(startIndex: u32, count: u32): u128[] {
283
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
252
+ if ((startIndex + count) > this._length) {
253
+ throw new Revert('Requested range exceeds array length');
254
+ }
255
+
284
256
  const result: u128[] = new Array<u128>(count);
285
257
  for (let i: u32 = 0; i < count; i++) {
286
258
  result[i] = this.get(<u64>(startIndex + i));
@@ -353,25 +325,6 @@ export class StoredU128Array {
353
325
  return this._length;
354
326
  }
355
327
 
356
- /**
357
- * @method setLength
358
- * @description Sets the length of the array.
359
- * @param {u64} newLength - The new length to set.
360
- */
361
- public setLength(newLength: u64): void {
362
- if (newLength > this.MAX_LENGTH) {
363
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
364
- }
365
-
366
- if (newLength > this._startIndex) {
367
- this._startIndex = newLength;
368
- this._isChangedStartIndex = true;
369
- }
370
-
371
- this._length = newLength;
372
- this._isChangedLength = true;
373
- }
374
-
375
328
  /**
376
329
  * @private
377
330
  * @method ensureValues
@@ -64,7 +64,9 @@ export class StoredU16Array {
64
64
  */
65
65
  @inline
66
66
  public get(index: u64): u16 {
67
- assert(index < this._length, 'Index out of bounds');
67
+ if (index >= this._length) {
68
+ return 0;
69
+ }
68
70
 
69
71
  const slotIndex: u64 = index / 16; // Each slot holds sixteen u16s
70
72
  const subIndex: u8 = <u8>(index % 16); // 0 to 15
@@ -81,7 +83,10 @@ export class StoredU16Array {
81
83
  */
82
84
  @inline
83
85
  public set(index: u64, value: u16): void {
84
- assert(index < this._length, 'Index exceeds current array length');
86
+ if (index > this.MAX_LENGTH) {
87
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
88
+ }
89
+
85
90
  const slotIndex: u64 = index / 16;
86
91
  const subIndex: u8 = <u8>(index % 16);
87
92
  this.ensureValues(slotIndex);
@@ -99,7 +104,7 @@ export class StoredU16Array {
99
104
  * @param {u16} value - The u16 value to append.
100
105
  */
101
106
  public push(value: u16): void {
102
- if (this._length >= this.MAX_LENGTH) {
107
+ if (this._length > this.MAX_LENGTH) {
103
108
  throw new Revert(
104
109
  'Push operation failed: Array has reached its maximum allowed length.',
105
110
  );
@@ -148,40 +153,6 @@ export class StoredU16Array {
148
153
  }
149
154
  }
150
155
 
151
- /**
152
- * @method shift
153
- * @description Removes the first element of the array by setting it to zero, decrementing the length, and incrementing the startIndex.
154
- * If the startIndex reaches the maximum value of u64, it wraps around to 0.
155
- */
156
- public shift(): void {
157
- if (this._length === 0) {
158
- throw new Revert('Shift operation failed: Array is empty.');
159
- }
160
-
161
- const currentStartIndex: u64 = this._startIndex;
162
- const slotIndex: u64 = currentStartIndex / 16;
163
- const subIndex: u8 = <u8>(currentStartIndex % 16);
164
- this.ensureValues(slotIndex);
165
-
166
- const slotValues = this._values.get(slotIndex);
167
- if (slotValues && slotValues[subIndex] !== 0) {
168
- slotValues[subIndex] = 0;
169
- this._isChanged.add(slotIndex);
170
- }
171
-
172
- // Decrement the length
173
- this._length -= 1;
174
- this._isChangedLength = true;
175
-
176
- // Increment the startIndex with wrap-around
177
- if (this._startIndex < this.MAX_LENGTH - 1) {
178
- this._startIndex += 1;
179
- } else {
180
- this._startIndex = 0;
181
- }
182
- this._isChangedStartIndex = true;
183
- }
184
-
185
156
  /**
186
157
  * @method save
187
158
  * @description Persists all cached u16 values, the length, and the startIndex to their respective storage slots if any have been modified.
@@ -257,7 +228,9 @@ export class StoredU16Array {
257
228
  */
258
229
  @inline
259
230
  public getAll(startIndex: u64, count: u64): u16[] {
260
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
231
+ if ((startIndex + count) > this._length) {
232
+ throw new Revert('Requested range exceeds array length');
233
+ }
261
234
 
262
235
  if (u32.MAX_VALUE < count) {
263
236
  throw new Revert('Requested range exceeds maximum allowed value.');
@@ -344,25 +317,6 @@ export class StoredU16Array {
344
317
  return this._startIndex;
345
318
  }
346
319
 
347
- /**
348
- * @method setLength
349
- * @description Sets the length of the array.
350
- * @param {u64} newLength - The new length to set.
351
- */
352
- public setLength(newLength: u64): void {
353
- if (newLength > this.MAX_LENGTH) {
354
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
355
- }
356
-
357
- if (newLength > this._startIndex) {
358
- this._startIndex = newLength;
359
- this._isChangedStartIndex = true;
360
- }
361
-
362
- this._length = newLength;
363
- this._isChangedLength = true;
364
- }
365
-
366
320
  public deleteLast(): void {
367
321
  if (this._length === 0) {
368
322
  throw new Revert('DeleteLast operation failed: Array is empty.');
@@ -19,13 +19,13 @@ export class StoredU256Array {
19
19
  private _isChanged: Set<u64> = new Set(); // Set of slotIndexes that are modified
20
20
 
21
21
  // Internal variables for length and startIndex management
22
- private _length: u64 = 0; // Current length of the array
22
+ private _length: u64 = 0; // Current length of the array
23
23
  private _startIndex: u64 = 0; // Starting index of the array
24
- private _isChangedLength: bool = false; // Indicates if the length has been modified
25
- private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
24
+ private _isChangedLength: bool = false; // Indicates if the length has been modified
25
+ private _isChangedStartIndex: bool = false; // Indicates if the startIndex has been modified
26
26
 
27
27
  // Define a maximum allowed length to prevent excessive storage usage
28
- private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1); // we need to check what happen in overflow situation to be able to set it to u64.MAX_VALUE
28
+ private readonly MAX_LENGTH: u64 = u64(u32.MAX_VALUE - 1);
29
29
 
30
30
  /**
31
31
  * @constructor
@@ -52,19 +52,23 @@ export class StoredU256Array {
52
52
  this.lengthPointer = lengthPointer;
53
53
  this.baseU256Pointer = baseU256Pointer;
54
54
 
55
- this._length = storedLengthAndStartIndex.lo1; // Bytes 0-7: length
55
+ this._length = storedLengthAndStartIndex.lo1; // Bytes 0-7: length
56
56
  this._startIndex = storedLengthAndStartIndex.lo2; // Bytes 8-15: startIndex
57
57
  }
58
58
 
59
59
  /**
60
60
  * @method get
61
61
  * @description Retrieves the u256 value at the specified global index.
62
+ * Returns zero instead of reverting if the index is out of bounds.
62
63
  * @param {u64} index - The global index (0 to ∞) of the u256 value to retrieve.
63
- * @returns {u256} - The u256 value at the specified index.
64
+ * @returns {u256} - The u256 value at the specified index or zero if out of bounds.
64
65
  */
65
66
  @inline
66
67
  public get(index: u64): u256 {
67
- assert(index < this._length, 'Index out of bounds');
68
+ if (index >= this._length) {
69
+ return u256.Zero;
70
+ }
71
+
68
72
  const slotIndex: u32 = <u32>index;
69
73
  this.ensureValues(slotIndex);
70
74
  const value = this._values.get(slotIndex);
@@ -79,7 +83,10 @@ export class StoredU256Array {
79
83
  */
80
84
  @inline
81
85
  public set(index: u64, value: u256): void {
82
- assert(index < this._length, 'Index exceeds current array length');
86
+ if (index > this.MAX_LENGTH) {
87
+ throw new Revert('Set operation failed: Index exceeds maximum allowed value.');
88
+ }
89
+
83
90
  const slotIndex: u32 = <u32>index;
84
91
  this.ensureValues(slotIndex);
85
92
 
@@ -96,7 +103,7 @@ export class StoredU256Array {
96
103
  * @param {u256} value - The u256 value to append.
97
104
  */
98
105
  public push(value: u256): void {
99
- if (this._length >= this.MAX_LENGTH) {
106
+ if (this._length > this.MAX_LENGTH) {
100
107
  throw new Revert(
101
108
  'Push operation failed: Array has reached its maximum allowed length.',
102
109
  );
@@ -164,42 +171,10 @@ export class StoredU256Array {
164
171
  }
165
172
  }
166
173
 
167
- /**
168
- * @method shift
169
- * @description Removes the first element of the array by setting it to zero, decrementing the length, and incrementing the startIndex.
170
- * If the startIndex reaches the maximum value of u64, it wraps around to 0.
171
- */
172
- public shift(): void {
173
- if (this._length === 0) {
174
- throw new Revert('Shift operation failed: Array is empty.');
175
- }
176
-
177
- const currentStartIndex: u64 = this._startIndex;
178
- const slotIndex: u32 = <u32>currentStartIndex;
179
- this.ensureValues(slotIndex);
180
-
181
- const currentValue = this._values.get(slotIndex);
182
- if (!u256.eq(currentValue, u256.Zero)) {
183
- this._values.set(slotIndex, u256.Zero);
184
- this._isChanged.add(slotIndex);
185
- }
186
-
187
- // Decrement the length
188
- this._length -= 1;
189
- this._isChangedLength = true;
190
-
191
- // Increment the startIndex with wrap-around
192
- if (this._startIndex < this.MAX_LENGTH - 1) {
193
- this._startIndex += 1;
194
- } else {
195
- this._startIndex = 0;
196
- }
197
- this._isChangedStartIndex = true;
198
- }
199
-
200
174
  /**
201
175
  * @method save
202
- * @description Persists all cached u256 values, the length, and the startIndex to their respective storage slots if any have been modified.
176
+ * @description Persists all cached u256 values, the length, and the startIndex to their respective storage slots
177
+ * if any have been modified.
203
178
  */
204
179
  public save(): void {
205
180
  // Save all changed slots
@@ -210,6 +185,7 @@ export class StoredU256Array {
210
185
  const value = this._values.get(slotIndex);
211
186
  Blockchain.setStorageAt(storagePointer, value);
212
187
  }
188
+
213
189
  this._isChanged.clear();
214
190
 
215
191
  // Save length and startIndex if changed
@@ -239,6 +215,7 @@ export class StoredU256Array {
239
215
  // Reset the length and startIndex to zero
240
216
  const zeroLengthAndStartIndex = u256.Zero;
241
217
  Blockchain.setStorageAt(this.lengthPointer, zeroLengthAndStartIndex);
218
+
242
219
  this._length = 0;
243
220
  this._startIndex = 0;
244
221
  this._isChangedLength = false;
@@ -272,7 +249,9 @@ export class StoredU256Array {
272
249
  */
273
250
  @inline
274
251
  public getAll(startIndex: u32, count: u32): u256[] {
275
- assert(startIndex + count <= this._length, 'Requested range exceeds array length');
252
+ if ((startIndex + count) > this._length) {
253
+ throw new Revert('Requested range exceeds array length');
254
+ }
276
255
  const result: u256[] = new Array<u256>(count);
277
256
  for (let i: u32 = 0; i < count; i++) {
278
257
  result[i] = this.get(<u64>(startIndex + i));
@@ -354,25 +333,6 @@ export class StoredU256Array {
354
333
  return this._startIndex;
355
334
  }
356
335
 
357
- /**
358
- * @method setLength
359
- * @description Sets the length of the array.
360
- * @param {u64} newLength - The new length to set.
361
- */
362
- public setLength(newLength: u64): void {
363
- if (newLength > this.MAX_LENGTH) {
364
- throw new Revert('SetLength operation failed: Length exceeds maximum allowed value.');
365
- }
366
-
367
- if (newLength > this._startIndex) {
368
- this._startIndex = newLength;
369
- this._isChangedStartIndex = true;
370
- }
371
-
372
- this._length = newLength;
373
- this._isChangedLength = true;
374
- }
375
-
376
336
  /**
377
337
  * @private
378
338
  * @method ensureValues