DoubleMap hashing over full value (#1650)
* DoubleMap hashing over full value * Expand Bytes tests * Expand * Hashing test with soublemaps * Small extra test comments
This commit is contained in:
@@ -15,6 +15,12 @@ const consts = fromMetadata(registry, metadata);
|
||||
describe('fromMetadata', (): void => {
|
||||
it('should return constants with the correct type and value', (): void => {
|
||||
expect(consts.democracy.cooloffPeriod).toBeInstanceOf(ClassOf(registry, 'BlockNumber'));
|
||||
expect(consts.democracy.cooloffPeriod.toHex()).toEqual('0x000c4e00');
|
||||
// 3 second blocks, 28 days
|
||||
expect(consts.democracy.cooloffPeriod.toNumber()).toEqual(28 * 24 * 60 * (60 / 3));
|
||||
});
|
||||
|
||||
it('correctly handles bytes', (): void => {
|
||||
// 0x34 removes as the length prefix removed
|
||||
expect(consts.session.dedupKeyPrefix.toHex()).toEqual('0x3a73657373696f6e3a6b657973');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,6 +10,8 @@ import { stringCamelCase } from '@polkadot/util';
|
||||
|
||||
import Metadata from '../../../Metadata';
|
||||
|
||||
const AS_STRIPPED = ['Bytes'];
|
||||
|
||||
/**
|
||||
* Retrieve the parameter types (module constants) from the runtime metadata.
|
||||
*
|
||||
@@ -25,13 +27,20 @@ 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 => {
|
||||
const codec = createTypeUnsafe(registry, meta.type.toString(), [meta.value]);
|
||||
// we convert to Data for the raw data-only bytes - in the case of Bytes, the data has
|
||||
// a length prefix encoded when received, leading to double-encoding unless removed
|
||||
const type = meta.type.toString();
|
||||
const codec: ConstantCodec = createTypeUnsafe(registry, type, [
|
||||
AS_STRIPPED.includes(type)
|
||||
? meta.value.toU8a(true)
|
||||
: meta.value
|
||||
]);
|
||||
|
||||
// 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 as ConstantCodec).meta = meta;
|
||||
codec.meta = meta;
|
||||
newModule[stringCamelCase(meta.name.toString())] = codec;
|
||||
|
||||
return newModule;
|
||||
|
||||
@@ -86,7 +86,7 @@ describe('createFunction', (): void => {
|
||||
key1: new Text(registry, 'AccountId'),
|
||||
key2: new Text(registry, 'AccountId'),
|
||||
value: new Text(registry, 'Balance'),
|
||||
key2Hasher: new Text(registry, 'twox_128')
|
||||
key2Hasher: new StorageHasher(registry, 'Twox128')
|
||||
}
|
||||
}
|
||||
} as any
|
||||
@@ -118,7 +118,7 @@ describe('createFunction', (): void => {
|
||||
key1: new Text(registry, 'Null'),
|
||||
key2: new Text(registry, 'Hash'),
|
||||
value: new Text(registry, 'Vec<(BlockNumber,EventIndex)>'),
|
||||
key2Hasher: new Text(registry, 'blake2_256')
|
||||
key2Hasher: new StorageHasher(registry, 'Blake2_256')
|
||||
}
|
||||
}
|
||||
} as any
|
||||
@@ -129,4 +129,43 @@ describe('createFunction', (): void => {
|
||||
// the value of the not Null type key does effect the result
|
||||
expect(u8aToHex(storageFn(['any', [1, 2, 3]]))).not.toEqual(u8aToHex(storageFn(['any', [1, 2, 3, 4]])));
|
||||
});
|
||||
|
||||
it('allows creating of known DoubleMap keys (with Bytes)', (): void => {
|
||||
const storageFn = createFunction(registry, {
|
||||
prefix: 'Session',
|
||||
section: 'session',
|
||||
method: 'NextKeys',
|
||||
meta: {
|
||||
type: {
|
||||
isDoubleMap: true,
|
||||
asDoubleMap: {
|
||||
hasher: new StorageHasher(registry, 'Twox64Concat'),
|
||||
key1: new Text(registry, 'Bytes'),
|
||||
key2: new Text(registry, 'AccountId'),
|
||||
value: new Text(registry, 'SessionKeys5'),
|
||||
key2Hasher: new StorageHasher(registry, 'Blake2_256')
|
||||
}
|
||||
}
|
||||
} as any
|
||||
}, { metaVersion: 9 });
|
||||
|
||||
expect(
|
||||
u8aToHex(
|
||||
storageFn([
|
||||
// hex, without length prefix
|
||||
'0x3a73657373696f6e3a6b657973',
|
||||
// address
|
||||
'DB2mp5nNhbFN86J9hxoAog8JALMhDXgwvWMxrRMLNUFMEY4'
|
||||
])
|
||||
)
|
||||
).toEqual(
|
||||
'0x' +
|
||||
'5901' + // length
|
||||
'cec5070d609dd3497f72bde07fc96ba0' + // twox 128
|
||||
'4c014e6bf8b8c2c011e7290b85696bb3' + // twox 128
|
||||
'9fe6329cc0b39e09' + // twox 64
|
||||
'343a73657373696f6e3a6b657973' + // twox 64 (concat, with length)
|
||||
'5eb36b60f0fc4b9177116eba3e5cd57fea6289a57f5f5b9ffeb0475c66e7a521' // blake2
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -78,8 +78,8 @@ function createKeyDoubleMap (registry: Registry, itemFn: CreateItemFn, stringKey
|
||||
|
||||
const [key1, key2] = args;
|
||||
const map = type.asDoubleMap;
|
||||
const val1 = createTypeUnsafe(registry, map.key1.toString(), [key1]).toU8a(true);
|
||||
const val2 = createTypeUnsafe(registry, map.key2.toString(), [key2]).toU8a(true);
|
||||
const val1 = createTypeUnsafe(registry, map.key1.toString(), [key1]).toU8a();
|
||||
const val2 = createTypeUnsafe(registry, map.key2.toString(), [key2]).toU8a();
|
||||
|
||||
// as per createKey, always add the length prefix (underlying it is Bytes)
|
||||
return Compact.addLengthPrefix(
|
||||
|
||||
Reference in New Issue
Block a user