Skip to content

Commit

Permalink
fix(utils): fix block identifier (#1076)
Browse files Browse the repository at this point in the history
* fix(utils): fix block identifier

* docs: class Block docs
  • Loading branch information
tabaktoni authored Apr 11, 2024
1 parent 11dc600 commit 0a3499d
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 23 deletions.
133 changes: 133 additions & 0 deletions __tests__/utils/block.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { Block } from '../../src/utils/provider';

describe('new Block()', () => {
test('decimal number 0 BlockIdentifier', () => {
const block = new Block(0);
expect(block.identifier).toMatchObject({ block_number: 0 });
expect(block.queryIdentifier).toBe('blockNumber=0');
expect(block.hash).toBe(null);
expect(block.number).toBe(0);
expect(block.tag).toBe(null);
});

test('decimal number 631581 BlockIdentifier', () => {
const block1 = new Block(631581);
expect(block1.identifier).toMatchObject({ block_number: 631581 });
expect(block1.queryIdentifier).toBe('blockNumber=631581');
expect(block1.hash).toBe(null);
expect(block1.number).toBe(631581);
expect(block1.tag).toBe(null);
});

test('non-decimal number -1 BlockIdentifier', () => {
expect(() => {
const block = new Block(-1);
return block;
}).toThrow(TypeError);
});

test('decimal string `0` BlockIdentifier', () => {
const block = new Block('0');
expect(block.identifier).toMatchObject({ block_number: 0 });
expect(block.queryIdentifier).toBe('blockNumber=0');
expect(block.hash).toBe(null);
expect(block.number).toBe(0);
expect(block.tag).toBe(null);
});

test('decimal string `631581` BlockIdentifier', () => {
const block1 = new Block('631581');
expect(block1.identifier).toMatchObject({ block_number: 631581 });
expect(block1.queryIdentifier).toBe('blockNumber=631581');
expect(block1.hash).toBe(null);
expect(block1.number).toBe(631581);
expect(block1.tag).toBe(null);
});

test('non-decimal string `-1` BlockIdentifier', () => {
expect(() => {
const block = new Block('-1');
return block;
}).toThrow(TypeError);
});

test('(Irregular support) hex string `0x0` BlockIdentifier.', () => {
const block = new Block('0x0');
expect(block.identifier).toMatchObject({ block_hash: '0x0' });
expect(block.queryIdentifier).toBe('blockHash=0x0');
expect(block.hash).toBe('0x0');
expect(block.number).toBe(null);
expect(block.tag).toBe(null);
});

test('hex string `0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb` BlockIdentifier', () => {
const block = new Block('0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb');
expect(block.identifier).toMatchObject({
block_hash: '0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb',
});
expect(block.queryIdentifier).toBe(
'blockHash=0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb'
);
expect(block.hash).toBe('0x2a70fb03fe363a2d6be843343a1d81ce6abeda1e9bd5cc6ad8fa9f45e30fdeb');
expect(block.number).toBe(null);
expect(block.tag).toBe(null);
});

test('BigInt 1100871802642964430494835386862140987097292376415056243504467124241116103854n BlockIdentifier', () => {
const block = new Block(
1100871802642964430494835386862140987097292376415056243504467124241116103854n
);
expect(block.identifier).toMatchObject({
block_hash: '0x26f12449d649a5339d4891b312a381f23ebc1106792d169b42e6646e87304ae',
});
expect(block.queryIdentifier).toBe(
'blockHash=0x26f12449d649a5339d4891b312a381f23ebc1106792d169b42e6646e87304ae'
);
expect(block.hash).toBe('0x26f12449d649a5339d4891b312a381f23ebc1106792d169b42e6646e87304ae');
expect(block.number).toBe(null);
expect(block.tag).toBe(null);
});

test('String BigInt `1100871802642964430494835386862140987097292376415056243504467124241116103854n` BlockIdentifier', () => {
expect(() => {
const block = new Block(
'1100871802642964430494835386862140987097292376415056243504467124241116103854n'
);
return block;
}).toThrow(TypeError);
});

test('string `pending` BlockIdentifier', () => {
const block1 = new Block('pending');
expect(block1.identifier).toBe('pending');
expect(block1.queryIdentifier).toBe('blockNumber=pending');
expect(block1.hash).toBe(null);
expect(block1.number).toBe(null);
expect(block1.tag).toBe('pending');
});

test('string `latest` BlockIdentifier', () => {
const block1 = new Block('latest');
expect(block1.identifier).toBe('latest');
expect(block1.queryIdentifier).toBe('blockNumber=latest');
expect(block1.hash).toBe(null);
expect(block1.number).toBe(null);
expect(block1.tag).toBe('latest');
});

test('False string `supernova` BlockIdentifier', () => {
expect(() => {
const block = new Block('supernova');
return block;
}).toThrow(TypeError);
});

test('null BlockIdentifier', () => {
const block1 = new Block(null);
expect(block1.identifier).toBe('pending');
expect(block1.queryIdentifier).toBe('blockNumber=pending');
expect(block1.hash).toBe(null);
expect(block1.number).toBe(null);
expect(block1.tag).toBe('pending');
});
});
17 changes: 0 additions & 17 deletions __tests__/utils/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as starkCurve from '@scure/starknet';

import { constants, ec, hash, num, stark } from '../../src';
import { Block } from '../../src/utils/provider';
import { isBigInt, isHex } from '../../src/utils/num';

const { IS_BROWSER } = constants;
Expand Down Expand Up @@ -117,22 +116,6 @@ describe('calculateContractAddressFromHash()', () => {
});
});

describe('new Block()', () => {
test('Block identifier and queryIdentifier', () => {
const blockA = new Block(0);
expect(blockA.identifier).toMatchObject({ block_number: 0 });
expect(blockA.queryIdentifier).toBe('blockNumber=0');

const blockB = new Block('latest');
expect(blockB.identifier).toBe('latest');
expect(blockB.queryIdentifier).toBe('blockNumber=latest');

const blockC = new Block('0x01');
expect(blockC.identifier).toMatchObject({ block_hash: '0x01' });
expect(blockC.queryIdentifier).toBe('blockHash=0x01');
});
});

describe('Num utility functions', () => {
describe('isBigInt', () => {
test('should return true for big integers', () => {
Expand Down
8 changes: 6 additions & 2 deletions src/types/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,13 @@ export enum BlockTag {
export type BlockNumber = BlockTag | null | number;

/**
* hex string and BN are detected as block hashes
* hex string and BigInt are detected as block hashes
*
* decimal string and number are detected as block numbers
* null appends nothing to the request url
*
* text string are detected as block tag
*
* null return 'pending' block tag
*/
export type BlockIdentifier = BlockNumber | BigNumberish;

Expand Down
21 changes: 19 additions & 2 deletions src/utils/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import { isSierra } from './contract';
import { formatSpaces } from './hash';
import { parse, stringify } from './json';
import { isBigInt, isHex, isNumber, toHex } from './num';
import { isDecimalString, isString } from './shortString';
import { compressProgram } from './stark';
import type { GetTransactionReceiptResponse } from './transactionReceipt';
import { isString } from './shortString';

/**
* Helper - Async Sleep for 'delay' time
Expand Down Expand Up @@ -103,6 +103,15 @@ export function txIdentifier(txHash?: BigNumberish, txId?: BigNumberish): string

export const validBlockTags = Object.values(BlockTag);

/**
* hex string and BigInt are detected as block hashes. identifier return { block_hash: hash }
*
* decimal string and number are detected as block numbers. identifier return { block_number: number }
*
* text string are detected as block tag. identifier return tag
*
* null is detected as 'pending' block tag. identifier return 'pending'
*/
export class Block {
hash: BlockIdentifier = null;

Expand All @@ -112,10 +121,14 @@ export class Block {

private setIdentifier(__identifier: BlockIdentifier) {
if (isString(__identifier)) {
if (isHex(__identifier)) {
if (isDecimalString(__identifier)) {
this.number = parseInt(__identifier, 10);
} else if (isHex(__identifier)) {
this.hash = __identifier;
} else if (validBlockTags.includes(__identifier as BlockTag)) {
this.tag = __identifier;
} else {
throw TypeError(`Block identifier unmanaged: ${__identifier}`);
}
} else if (isBigInt(__identifier)) {
this.hash = toHex(__identifier);
Expand All @@ -124,6 +137,10 @@ export class Block {
} else {
this.tag = BlockTag.pending;
}

if (isNumber(this.number) && this.number < 0) {
throw TypeError(`Block number (${this.number}) can't be negative`);
}
}

constructor(_identifier: BlockIdentifier) {
Expand Down
2 changes: 0 additions & 2 deletions src/utils/responseParser/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import { toBigInt } from '../num';
import { isString } from '../shortString';
import { estimateFeeToBounds, estimatedFeeToMaxFee } from '../stark';
import { ResponseParser } from '.';
import { isString } from '../shortString';


export class RPCResponseParser
implements
Expand Down

0 comments on commit 0a3499d

Please sign in to comment.