All files / src/chain block-id.ts

78.12% Statements 25/32
50% Branches 3/6
90% Functions 9/10
77.41% Lines 24/31

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              1x     64x     64x 64x             18x       2x 2x 2x 2x 2x 2x 2x 2x           84x     84x                         21x       40x       37x       44x       6x 6x 6x 24x   6x      
import {Bytes, BytesType, Checksum256, Checksum256Type, isInstanceOf, UInt32, UInt32Type} from '..'
import {ABIDecoder, ABIEncoder, ABISerializableObject} from '../serializer'
import {arrayEquals, arrayToHex} from '../utils'
 
export type BlockIdType = BlockId | BytesType | {blockNum: UInt32Type; checksum: Checksum256Type}
 
export class BlockId implements ABISerializableObject {
    static abiName = 'block_id_type' // eosio contract context defines this with a _type suffix for some reason
 
    static from(value: BlockIdType) {
        Iif (isInstanceOf(value, this)) {
            return value
        }
        Eif (Bytes.isBytes(value)) {
            return new this(Bytes.from(value).array)
        } else {
            return this.fromBlockChecksum(value.checksum, value.blockNum)
        }
    }
 
    static fromABI(decoder: ABIDecoder) {
        return new this(decoder.readArray(32))
    }
 
    static fromBlockChecksum(checksum: Checksum256Type, blockNum: UInt32Type): BlockId {
        const id = new BlockId(Checksum256.from(checksum).array)
        const numBuffer = new Uint8Array(4)
        numBuffer[0] = (Number(blockNum) >> 24) & 0xff
        numBuffer[1] = (Number(blockNum) >> 16) & 0xff
        numBuffer[2] = (Number(blockNum) >> 8) & 0xff
        numBuffer[3] = Number(blockNum) & 0xff
        id.array.set(numBuffer, 0)
        return id
    }
 
    readonly array: Uint8Array
 
    constructor(array: Uint8Array) {
        Iif (array.byteLength !== 32) {
            throw new Error(`BlockId size mismatch, expected 32 bytes got ${array.byteLength}`)
        }
        this.array = array
    }
 
    equals(other: BlockIdType): boolean {
        const self = this.constructor as typeof BlockId
        try {
            return arrayEquals(this.array, self.from(other).array)
        } catch {
            return false
        }
    }
 
    toABI(encoder: ABIEncoder) {
        encoder.writeArray(this.array)
    }
 
    toString() {
        return this.hexString
    }
 
    toJSON() {
        return this.toString()
    }
 
    get hexString(): string {
        return arrayToHex(this.array)
    }
 
    get blockNum(): UInt32 {
        const bytes = this.array.slice(0, 4)
        let num = 0
        for (let i = 0; i < 4; i++) {
            num = (num << 8) + bytes[i]
        }
        return UInt32.from(num)
    }
}