Handle double-encoded Bytes in fallback/constants (#2113)

* Handle double-encoded Bytes in fallback/constants

* Fix import, bypass for tests
This commit is contained in:
Jaco Greeff
2020-03-28 20:55:39 +01:00
committed by GitHub
parent 146360a454
commit a4ea4d648a
3 changed files with 32 additions and 22 deletions
@@ -2,25 +2,34 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Constants } from '../../types';
import { Metadata, TypeRegistry } from '@polkadot/types';
import rpcMetadata from '../../../Metadata/static';
import rpcMetadataV10 from '../../../Metadata/v10/static';
import fromMetadata from '../fromMetadata';
// Use the pre-generated metadata
const registry = new TypeRegistry();
const metadata = new Metadata(registry, rpcMetadata);
const consts = fromMetadata(registry, metadata);
function init (meta: string): [Constants, TypeRegistry] {
const registry = new TypeRegistry();
const metadata = new Metadata(registry, meta);
return [fromMetadata(registry, metadata), registry];
}
describe('fromMetadata', (): void => {
it('should return constants with the correct type and value', (): void => {
const [consts, registry] = init(rpcMetadata);
expect(consts.democracy.cooloffPeriod).toBeInstanceOf(registry.createClass('BlockNumber'));
// 3 second blocks, 28 days
expect(consts.democracy.cooloffPeriod.toNumber()).toEqual(28 * 24 * 60 * (60 / 3));
});
// removed from session
it.skip('correctly handles bytes', (): void => {
it('correctly handles bytes', (): void => {
const [consts] = init(rpcMetadataV10);
// 0x34 removes as the length prefix removed
expect(consts.session.dedupKeyPrefix.toHex()).toEqual('0x3a73657373696f6e3a6b657973');
});
@@ -6,12 +6,10 @@ import { Registry } from '@polkadot/types/types';
import { Constants, ConstantCodec, ModuleConstants } from '../../types';
import { createTypeUnsafe } from '@polkadot/types/create';
import { stringCamelCase } from '@polkadot/util';
import { hexToU8a, stringCamelCase } from '@polkadot/util';
import Metadata from '../../../Metadata';
const AS_STRIPPED = ['Bytes'];
/** @internal */
export default function fromMetadata (registry: Registry, metadata: Metadata): Constants {
return metadata.asLatest.modules.reduce((result: Constants, moduleMetadata): Constants => {
@@ -23,19 +21,10 @@ export default function fromMetadata (registry: Registry, metadata: Metadata): C
// For access, we change the index names, i.e. Democracy.EnactmentPeriod -> democracy.enactmentPeriod
result[stringCamelCase(name.toString())] = moduleMetadata.constants.reduce((newModule: ModuleConstants, meta): ModuleConstants => {
// in the case of Bytes, the data has a length prefix encoded when received,
// leading to double-encoding unless removed
// convert to the natural type as received
const type = meta.type.toString();
const codec: ConstantCodec = createTypeUnsafe(registry, type, [
AS_STRIPPED.includes(type)
? meta.value.toU8a(true)
: meta.value
]);
const codec: ConstantCodec = createTypeUnsafe(registry, type, [hexToU8a(meta.value.toHex())]);
// This is not a perfect idea, however as it stands with number-only constants on the metadata
// does not have any effect. However, this could become problematic in cases where items are
// exposed that contain their own metadata. As of now, the compatibility with current, e.g.
// storage is the driving factor, one consistent way of handling interfaces
codec.meta = meta;
newModule[stringCamelCase(meta.name.toString())] = codec;
+15 -3
View File
@@ -12,7 +12,7 @@ import { combineLatest, from, Observable, Observer, of, throwError } from 'rxjs'
import { catchError, map, publishReplay, refCount, switchMap } from 'rxjs/operators';
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
import { Option, StorageKey, Vec, createClass, createTypeUnsafe } from '@polkadot/types';
import { assert, isFunction, isNull, isNumber, isUndefined, logger, u8aToU8a } from '@polkadot/util';
import { assert, hexToU8a, isFunction, isNull, isNumber, isUndefined, logger, u8aToU8a } from '@polkadot/util';
import { drr } from './rxjs';
@@ -370,7 +370,13 @@ export default class Rpc implements RpcInterface {
);
}
return createTypeUnsafe(this.registry, type, [isEmpty ? meta.fallback : input], true);
return createTypeUnsafe(this.registry, type, [
isEmpty
? meta.fallback
? hexToU8a(meta.fallback.toHex())
: undefined
: input
], true);
}
private formatStorageSet (keys: Vec<StorageKey>, changes: [string, string | null][]): Codec[] {
@@ -428,6 +434,12 @@ export default class Rpc implements RpcInterface {
);
}
return createTypeUnsafe(this.registry, type, [isEmpty ? meta.fallback : input], true);
return createTypeUnsafe(this.registry, type, [
isEmpty
? meta.fallback
? hexToU8a(meta.fallback.toHex())
: undefined
: input
], true);
}
}