All files / lib/messages RoundingIntervals.ts

100% Statements 36/36
80% Branches 8/10
100% Functions 8/8
100% Lines 33/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 1291x   1x 1x             1x 1x               27x   27x   27x             27x               43x 43x   43x   43x 44x 44x   44x     43x           87x   87x                 3x 5x 1x         2x 2x     1x                 15x   15x                       125x   125x   125x 126x 126x     125x                                    
import { BufferReader, BufferWriter } from '@node-dlc/bufio';
 
import { MessageType } from '../MessageType';
import { toBigInt } from '../util';
import { IDlcMessage } from './DlcMessage';
 
/**
 * RoundingIntervals defines rounding intervals for numeric outcome contracts.
 * Updated to match dlcspecs format (no longer uses TLV).
 */
export class RoundingIntervals implements IDlcMessage {
  public static type = MessageType.RoundingIntervals;
 
  /**
   * Creates a RoundingIntervals from JSON data
   * @param json JSON object representing rounding intervals
   */
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
  public static fromJSON(json: any): RoundingIntervals {
    const instance = new RoundingIntervals();
 
    const intervals = json.intervals || [];
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    instance.intervals = intervals.map((interval: any) => ({
      beginInterval: toBigInt(
        interval.beginInterval || interval.begin_interval,
      ),
      roundingMod: toBigInt(interval.roundingMod || interval.rounding_mod),
    }));
 
    return instance;
  }
 
  /**
   * Deserializes a rounding_intervals message
   * @param buf
   */
  public static deserialize(buf: Buffer): RoundingIntervals {
    const instance = new RoundingIntervals();
    const reader = new BufferReader(buf);
 
    const numRoundingIntervals = Number(reader.readBigSize());
 
    for (let i = 0; i < numRoundingIntervals; i++) {
      const beginInterval = reader.readUInt64BE();
      const roundingMod = reader.readUInt64BE();
 
      instance.intervals.push({ beginInterval, roundingMod });
    }
 
    return instance;
  }
 
  /**
   * The type for rounding_intervals message. rounding_intervals = 42788
   */
  public type = RoundingIntervals.type;
 
  public intervals: IInterval[] = [];
 
  /**
   * Validates correctness of all fields in the message
   * https://github.com/discreetlogcontracts/dlcspecs/blob/master/NumericOutcome.md#requirements
   * @throws Will throw an error if validation fails
   */
  public validate(): void {
    // 1. Intervals must be non-negative
    for (const interval of this.intervals) {
      if (interval.beginInterval < 0) {
        throw new Error('beginInterval must be non-negative');
      }
    }
 
    // 2. Intervals must be strictly increasing
    for (let i = 1; i < this.intervals.length; ++i) {
      if (
        this.intervals[i - 1].beginInterval >= this.intervals[i].beginInterval
      ) {
        throw new Error(`Intervals must be strictly increasing`);
      }
    }
  }
 
  /**
   * Converts rounding_intervals to JSON
   */
  public toJSON(): IRoundingIntervalsJSON {
    return {
      intervals: this.intervals.map((interval) => {
        return {
          beginInterval: Number(interval.beginInterval),
          roundingMod: Number(interval.roundingMod),
        };
      }),
    };
  }
 
  /**
   * Serializes the rounding_intervals message into a Buffer
   */
  public serialize(): Buffer {
    const writer = new BufferWriter();
 
    writer.writeBigSize(this.intervals.length);
 
    for (const interval of this.intervals) {
      writer.writeUInt64BE(interval.beginInterval);
      writer.writeUInt64BE(interval.roundingMod);
    }
 
    return writer.toBuffer();
  }
}
 
interface IInterval {
  beginInterval: bigint;
  roundingMod: bigint;
}
 
interface IIntervalJSON {
  beginInterval: number;
  roundingMod: number;
}
 
export interface IRoundingIntervalsJSON {
  type?: number; // Optional for rust-dlc compatibility
  intervals: IIntervalJSON[];
}