Skip to content

Commit

Permalink
fix(core)!: add support to genesis delegate as slot leader
Browse files Browse the repository at this point in the history
  • Loading branch information
mkazlauskas authored and rhyslbw committed Jan 24, 2022
1 parent b3dc768 commit d1c098c
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 22 deletions.
34 changes: 30 additions & 4 deletions packages/core/src/Cardano/types/Block.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BlockNo, BlockSize, Slot } from '@cardano-ogmios/schema';
import { Cardano } from '../..';
import { Epoch, Lovelace, PoolId } from '.';
import { Hash32ByteBase16, OpaqueString, typedBech32 } from '../util';
import { Hash28ByteBase16, Hash32ByteBase16, OpaqueString, typedBech32 } from '../util';
import { InvalidStringError } from '../..';

export { BlockNo } from '@cardano-ogmios/schema';

Expand Down Expand Up @@ -32,15 +32,41 @@ export { BlockSize };
export type VrfVkBech32 = OpaqueString<'VrfVkBech32'>;
export const VrfVkBech32 = (value: string) => typedBech32<VrfVkBech32>(value, 'vrf_vk', 52);

/**
* Shelley genesis delegate
* Either a 28 byte hex string, or 'ShelleyGenesis-[8byte-hex-string]'
*/
export type GenesisDelegate = OpaqueString<'GenesisDelegate'>;
export const GenesisDelegate = (value: string): GenesisDelegate => {
// eslint-disable-next-line wrap-regex
if (/ShelleyGenesis-[\da-f]{16}/.test(value)) {
return value as unknown as GenesisDelegate;
}
return Hash28ByteBase16(value);
};

export type SlotLeader = PoolId | GenesisDelegate;
export const SlotLeader = (value: string): SlotLeader => {
try {
return PoolId(value);
} catch {
try {
return GenesisDelegate(value);
} catch (error) {
throw new InvalidStringError('Expected either PoolId or GenesisDelegate', error);
}
}
};

export interface Block {
header: PartialBlockHeader;
date: Date;
epoch: Epoch;
epochSlot: number;
slotLeader: PoolId;
slotLeader: SlotLeader;
size: BlockSize;
txCount: number;
totalOutput: Cardano.Lovelace;
totalOutput: Lovelace;
fees: Lovelace;
vrf: VrfVkBech32;
previousBlock?: BlockId;
Expand Down
15 changes: 2 additions & 13 deletions packages/core/src/Cardano/types/StakePool/primitives.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Hash28ByteBase16, OpaqueString, typedBech32, typedHex } from '../../util';
import { InvalidStringError } from '../../..';

/**
* pool operator verification key hash as bech32 string or a genesis pool ID
*/
export type PoolId = OpaqueString<'PoolId'>;

/**
* @param {string} value blake2b_224 digest of an operator verification key hash or a genesis pool ID
* @param {string} value blake2b_224 digest of an operator verification key hash
* @throws InvalidStringError
*/
export const PoolId = (value: string): PoolId => {
try {
return typedBech32(value, 'pool', 45);
} catch (error: unknown) {
// eslint-disable-next-line prettier/prettier
if ((/^ShelleyGenesis-[\dA-Fa-f]{16}$/).test(value)) {
return value as unknown as PoolId;
}
throw new InvalidStringError('Expected PoolId to be either bech32 or genesis stake pool', error);
}
};
export const PoolId = (value: string): PoolId => typedBech32(value, 'pool', 45);

/**
* pool operator verification key hash as hex string
Expand Down
19 changes: 18 additions & 1 deletion packages/core/test/Cardano/types/Block.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { BlockId, VrfVkBech32, util } from '../../../src/Cardano';
import { BlockId, SlotLeader, VrfVkBech32, util } from '../../../src/Cardano';
import { InvalidStringError } from '../../../src';

jest.mock('../../../src/Cardano/util/primitives', () => {
const actual = jest.requireActual('../../../src/Cardano/util/primitives');
return {
Hash28ByteBase16: jest.fn().mockImplementation((...args) => actual.Hash28ByteBase16(...args)),
Hash32ByteBase16: jest.fn().mockImplementation((...args) => actual.Hash32ByteBase16(...args)),
typedBech32: jest.fn().mockImplementation((...args) => actual.typedBech32(...args))
};
Expand All @@ -22,4 +24,19 @@ describe('Cardano/types/Block', () => {
52
);
});

describe('SlotLeader()', () => {
it('accepts a valid PoolId and is implemented using util.typedBech32', () => {
expect(() => SlotLeader('pool1zuevzm3xlrhmwjw87ec38mzs02tlkwec9wxpgafcaykmwg7efhh')).not.toThrow();
});
it('accepts a valid Shelley genesis delegate', () => {
expect(() => SlotLeader('eff1b5b26e65b791d6f236c7c0264012bd1696759d22bdb4dd0f6f56')).not.toThrow();
});
it('accepts a valid Shelley genesis in prefix format', () => {
expect(() => SlotLeader('ShelleyGenesis-eff1b5b26e65b791')).not.toThrow();
});
it('throws for any other strings', () => {
expect(() => SlotLeader('ShelleyGenesis-eff1b5b26e65b79')).toThrowError(InvalidStringError);
});
});
});
4 changes: 0 additions & 4 deletions packages/core/test/Cardano/types/StakePool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ describe('Cardano/types/StakePool', () => {
expect(() => Cardano.PoolId('pool1zuevzm3xlrhmwjw87ec38mzs02tlkwec9wxpgafcaykmwg7efhh')).not.toThrow();
});

it('PoolId() accepts a valid genesis pool ID', () => {
expect(() => Cardano.PoolId('ShelleyGenesis-eff1b5b26e65b791')).not.toThrow();
});

it('PoolIdHex() accepts a valid pool id hex string', () => {
expect(() => Cardano.PoolIdHex('e4b1c8ec89415ce6349755a1aa44b4affbb5f1248ff29943d190c715')).not.toThrow();
});
Expand Down

0 comments on commit d1c098c

Please sign in to comment.