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:
Jaco Greeff
2019-12-09 08:37:47 +01:00
committed by GitHub
parent 21c57b60a1
commit 6bf0d5eea9
5 changed files with 95 additions and 15 deletions
@@ -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(