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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user