Skip to content

Commit

Permalink
feat(cardano-services): changes the way tx metadatum are read from db…
Browse files Browse the repository at this point in the history
…, from json to raw bytes
  • Loading branch information
iccicci committed Feb 9, 2023
1 parent 6ab352c commit ca9a110
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 27 deletions.
21 changes: 16 additions & 5 deletions packages/cardano-services/src/Metadata/mappers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Cardano, ProviderUtil } from '@cardano-sdk/core';
import { CML, Cardano, cmlToCore } from '@cardano-sdk/core';
import { TxMetadataModel } from './types';
import { usingAutoFree } from '@cardano-sdk/util';

export const mapTxMetadata = (metadataModel: Pick<TxMetadataModel, 'json_value' | 'key'>[]): Cardano.TxMetadata =>
export const mapTxMetadata = (metadataModel: Pick<TxMetadataModel, 'bytes' | 'key'>[]): Cardano.TxMetadata =>
metadataModel.reduce((map, metadatum) => {
const { key, json_value } = metadatum;
if (!json_value || !key) return map;
map.set(BigInt(key), ProviderUtil.jsonToMetadatum(json_value));
const { bytes, key } = metadatum;

if (bytes && key) {
const biKey = BigInt(key);
const metadata = usingAutoFree((_) => cmlToCore.txMetadata(CML.GeneralTransactionMetadata.from_bytes(bytes)));

if (metadata) {
const datum = metadata.get(biKey);

if (datum) map.set(biKey, datum);
}
}

return map;
}, new Map<bigint, Cardano.Metadatum>());
16 changes: 8 additions & 8 deletions packages/cardano-services/src/Metadata/queries.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export const findTxMetadata = `
SELECT
meta."key" AS "key",
meta."json" AS json_value,
tx.hash AS tx_id
FROM tx_metadata AS meta
JOIN tx ON meta.tx_id = tx.id
WHERE tx.hash = ANY($1)
ORDER BY meta.id ASC`;
SELECT
key,
bytes,
hash AS tx_id
FROM tx_metadata AS meta
JOIN tx ON tx_id = tx.id
WHERE hash = ANY($1)
ORDER BY meta.id ASC`;
2 changes: 1 addition & 1 deletion packages/cardano-services/src/Metadata/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface TxMetadataService {
}

export interface TxMetadataModel {
bytes: Uint8Array;
key: string;
json_value: { [k: string]: unknown };
tx_id: Buffer;
}
41 changes: 28 additions & 13 deletions packages/cardano-services/test/Metadata/mappers.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { Cardano, ProviderUtil } from '@cardano-sdk/core';
import { Buffer } from 'buffer';
import { Cardano, cmlToCore, coreToCml, metadatum } from '@cardano-sdk/core';
import { TxMetadataModel, mapTxMetadata } from '../../src/Metadata';
import { usingAutoFree } from '@cardano-sdk/util';

const toBytes = (data: Cardano.Metadatum) => usingAutoFree((scope) => coreToCml.txMetadatum(scope, data).to_bytes());

describe('mapTxMetadata', () => {
it('maps TxMetadataModel to Cardano.TxMetadata', () => {
const transactionHash = 'cefd2fcf657e5e5d6c35975f4e052f427819391b153ebb16ad8aa107ba5a3819';
const txMetadataModel: TxMetadataModel[] = [
{
json_value: { v: 1 },
bytes: toBytes(new Map([[127n, metadatum.jsonToMetadatum({ v: 1 })]])),
key: '127',
tx_id: Buffer.from(transactionHash, 'hex')
},
{
json_value: { a: 2 },
bytes: toBytes(new Map([[500n, metadatum.jsonToMetadatum({ a: 2 })]])),
key: '500',
tx_id: Buffer.from(transactionHash, 'hex')
}
Expand All @@ -29,22 +33,33 @@ describe('mapTxMetadata', () => {
expect(mapTxMetadata([])).toEqual(new Map());
});

it('ignores non-metadata objects (with no metadata "key" or "json_value")', () => {
expect(mapTxMetadata([{ json_value: { a: 1 }, key: '' }])).toEqual(new Map());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(mapTxMetadata([{ json_value: null, key: '123' } as any])).toEqual(new Map());
it('ignores non-metadata objects (with no metadata "key")', () => {
expect(mapTxMetadata([{ bytes: toBytes(new Map([[127n, '']])), key: '' }])).toEqual(new Map());
});

it('ignores non-metadata objects (with no metadata "bytes")', () => {
expect(mapTxMetadata([{ bytes: null as unknown as Uint8Array, key: '123' }])).toEqual(new Map());
});

it('throws if non-metadata objects (with metadata "bytes" which is not a Map)', () => {
expect(() => mapTxMetadata([{ bytes: toBytes('test'), key: '123' }])).toThrow();
});

it('ignores non-metadata objects (with metadata "bytes" which is a Map but doesn\'t contain key)', () => {
expect(mapTxMetadata([{ bytes: toBytes(new Map([[127n, '']])), key: '123' }])).toEqual(new Map());
});

it('throws if key cannot be parse to bigint', () => {
expect(() => mapTxMetadata([{ json_value: { a: 1 }, key: 'bad' }])).toThrow();
expect(() => mapTxMetadata([{ bytes: toBytes('test'), key: 'bad' }])).toThrow();
});

it('uses ProviderUtil.jsonToMetadata to map json_value', () => {
const spy = jest.spyOn(ProviderUtil, 'jsonToMetadatum');
it.skip('uses cmlToCore.txMetadatum to map bytes', () => {
const bytes = toBytes(new Map([[127n, 'test']]));
const spy = jest.spyOn(cmlToCore, 'txMetadatum');
spy.mockReset();
const json_value = { a: 1 };
mapTxMetadata([{ json_value, key: '123' }]);

mapTxMetadata([{ bytes, key: '127' }]);
expect(spy).toBeCalledTimes(1);
expect(spy).toBeCalledWith(json_value);
expect(spy).toBeCalledWith(bytes);
});
});

0 comments on commit ca9a110

Please sign in to comment.