Skip to content

Commit

Permalink
fix: decode Bytes types for /runtime/metadata correctly (#907)
Browse files Browse the repository at this point in the history
* fix: hacky solution to properly decode Bytes

* add ISanitizeOptions type

* fix: add sanitizeMetadataExceptions and options

* add options to the necessary controllers

* add registry to the options

* fix logic to work with all types

* add tests

* pass in registry to options

* remove old comments

* cleanup

* correctly sanitize non integer values using sanitizeNumbers

* make sure options registry metadata matches rpc metadata response

* fix grumbles for inline comments

* add clarifying comment

* fix bug with option types, and large multiple type name fields

* destructure

* add type comments in tests

* inline comments

* add a test for Option<u128>

* fix sanitizeOptions to have metadataOpts

* add logic for multiple runtimes, and not just v14
  • Loading branch information
TarikGul committed Apr 29, 2022
1 parent 59aabc3 commit ce48c14
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 26 deletions.
9 changes: 7 additions & 2 deletions src/controllers/AbstractController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {

import { sanitizeNumbers } from '../sanitize';
import { isBasicLegacyError } from '../types/errors';
import { ISanitizeOptions } from '../types/sanitize';

type SidecarRequestHandler =
| RequestHandler<IAddressParam>
Expand Down Expand Up @@ -218,7 +219,11 @@ export default abstract class AbstractController<T extends AbstractService> {
* @param res Response
* @param body response body
*/
static sanitizedSend<T>(res: Response<AnyJson>, body: T): void {
res.send(sanitizeNumbers(body));
static sanitizedSend<T>(
res: Response<AnyJson>,
body: T,
options: ISanitizeOptions = {}
): void {
res.send(sanitizeNumbers(body, options));
}
}
15 changes: 11 additions & 4 deletions src/controllers/runtime/RuntimeMetadataController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,16 @@ export default class RuntimeMetadataController extends AbstractController<Runtim
): Promise<void> => {
const hash = await this.getHashFromAt(at);

RuntimeMetadataController.sanitizedSend(
res,
await this.service.fetchMetadata(hash)
);
let historicApi;
if (at) {
historicApi = await this.api.at(hash);
}

const registry = historicApi ? historicApi.registry : this.api.registry;
const metadata = await this.service.fetchMetadata(hash);

RuntimeMetadataController.sanitizedSend(res, metadata, {
metadataOpts: { registry, version: metadata.version },
});
};
}
93 changes: 92 additions & 1 deletion src/sanitize/sanitizeNumbers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ import {
MIN_I64,
MIN_I128,
} from '../test-helpers/constants';
import { kusamaRegistry, polkadotRegistry } from '../test-helpers/registries';
import {
kusamaRegistry,
polkadotRegistry,
polkadotRegistryV9190,
} from '../test-helpers/registries';
import {
PRE_SANITIZED_BALANCE_LOCK,
PRE_SANITIZED_OPTION_VESTING_INFO,
Expand Down Expand Up @@ -1157,4 +1161,91 @@ describe('sanitizeNumbers', () => {
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
]);
});

describe('handles metadata v14 correctly', () => {
const sanitizeOptions = {
metadataOpts: {
registry: polkadotRegistryV9190,
version: 14,
},
};

it('handles unknown struct bytes correctly for Option<u128>', () => {
const struct = new Struct(
polkadotRegistryV9190,
{ type: 'Text', value: 'Bytes' },
{ type: '535', value: '0x01005039278c0400000000000000000000' } // Option<u128>
);

expect(sanitizeNumbers(struct, sanitizeOptions)).toStrictEqual({
type: '535',
value: '5000000000000',
});
});

it('handles unknown struct bytes correctly for u128', () => {
const struct = new Struct(
polkadotRegistryV9190,
{ type: 'Text', value: 'Bytes' },
{ type: '6', value: '0x00e87648170000000000000000000000' } // u128
);

expect(sanitizeNumbers(struct, sanitizeOptions)).toStrictEqual({
type: '6',
value: '100000000000',
});
});

it('handles unknown struct bytes correctly for u64', () => {
const struct = new Struct(
polkadotRegistryV9190,
{ type: 'Text', value: 'Bytes' },
{ type: '8', value: '0xc084666557010000' } // u64
);

expect(sanitizeNumbers(struct, sanitizeOptions)).toStrictEqual({
type: '8',
value: '1474875000000',
});
});

it('handles unknown struct bytes correctly for u32', () => {
const struct = new Struct(
polkadotRegistryV9190,
{ type: 'Text', value: 'Bytes' },
{ type: '4', value: '0x00400000' } // u32
);

expect(sanitizeNumbers(struct, sanitizeOptions)).toStrictEqual({
type: '4',
value: '16384',
});
});

it('handles unknown struct bytes correctly for u16', () => {
const struct = new Struct(
polkadotRegistryV9190,
{ type: 'Text', value: 'Bytes' },
{ type: '75', value: '0x0200' } // u16
);

expect(sanitizeNumbers(struct, sanitizeOptions)).toStrictEqual({
type: '75',
value: '2',
});
});

it('handles unknown struct bytes correctly for u8', () => {
const struct = new Struct(
polkadotRegistryV9190,
{ type: 'Text', value: 'Bytes' },
{ type: '2', value: '0x05' } // u8
);

expect(sanitizeNumbers(struct, sanitizeOptions)).toStrictEqual({
type: '2',
value: '5',
});
});
});
});

0 comments on commit ce48c14

Please sign in to comment.