Skip to content

Commit c8b29d1

Browse files
authored
REFACTOR hashing (pubkey#4316)
1 parent 07a60a6 commit c8b29d1

File tree

24 files changed

+117
-241
lines changed

24 files changed

+117
-241
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@
392392
"mingo": "6.2.7",
393393
"modifyjs": "0.3.1",
394394
"oblivious-set": "1.1.1",
395+
"ohash": "1.0.0",
395396
"pouchdb-selector-core": "8.0.0",
396397
"reconnecting-websocket": "4.4.0",
397398
"simple-peer": "9.11.1",
@@ -506,4 +507,4 @@
506507
"webpack-dev-server": "4.11.1",
507508
"wrtc": "0.4.7"
508509
}
509-
}
510+
}

src/plugin-helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
RxStorageWriteErrorConflict
2020
} from './types';
2121
import {
22-
fastUnsecureHash,
22+
defaultHashSha256,
2323
flatClone,
2424
getFromMapOrThrow,
2525
requestIdleCallbackIfAvailable
@@ -67,7 +67,7 @@ export function wrappedValidateStorageFactory(
6767
function initValidator(
6868
schema: RxJsonSchema<any>
6969
): ValidatorFunction {
70-
const hash = fastUnsecureHash(JSON.stringify(schema));
70+
const hash = defaultHashSha256(JSON.stringify(schema));
7171
if (!VALIDATOR_CACHE.has(hash)) {
7272
const validator = getValidator(schema);
7373
VALIDATOR_CACHE.set(hash, validator);

src/plugins/dev-mode/check-schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function checkFieldNameRegex(fieldName: string) {
3030
return;
3131
}
3232

33-
if (['properties', 'language'].includes(fieldName)) {
33+
if (['properties'].includes(fieldName)) {
3434
throw newRxError('SC23', {
3535
fieldName
3636
});

src/plugins/migration/data-migrator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ export async function createOldCollection(
263263
dataMigrator,
264264
newestCollection: dataMigrator.newestCollection,
265265
database,
266-
schema: createRxSchema(schemaObj, false),
266+
schema: createRxSchema(schemaObj, database.hashFunction, false),
267267
storageInstance
268268
};
269269

src/plugins/replication-couchdb/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import {
55
ensureNotFalsy,
66
errorToPlainJson,
7-
fastUnsecureHash,
87
flatClone,
98
getFromMapOrThrow,
109
lastOfArray
@@ -204,7 +203,7 @@ export function replicateCouchDB<RxDocType>(
204203
const replicationState = new RxCouchDBReplicationState<RxDocType>(
205204
options.url,
206205
options.fetch ? options.fetch : getDefaultFetch(),
207-
COUCHDB_NEW_REPLICATION_PLUGIN_IDENTITY_PREFIX + fastUnsecureHash(options.url),
206+
COUCHDB_NEW_REPLICATION_PLUGIN_IDENTITY_PREFIX + options.collection.database.hashFunction(options.url),
208207
collection,
209208
replicationPrimitivesPull,
210209
replicationPrimitivesPush,

src/plugins/replication-firestore/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
ensureNotFalsy,
33
errorToPlainJson,
4-
fastUnsecureHash,
54
flatClone,
65
lastOfArray
76
} from '../../plugins/utils';
@@ -304,7 +303,7 @@ export function replicateFirestore<RxDocType>(
304303

305304
const replicationState = new RxFirestoreReplicationState<RxDocType>(
306305
options.firestore,
307-
FIRESTORE_REPLICATION_PLUGIN_IDENTITY_PREFIX + fastUnsecureHash(options.firestore.projectId),
306+
FIRESTORE_REPLICATION_PLUGIN_IDENTITY_PREFIX + options.collection.database.hashFunction(options.firestore.projectId),
308307
collection,
309308
replicationPrimitivesPull,
310309
replicationPrimitivesPush,

src/plugins/replication-graphql/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
import {
66
ensureNotFalsy,
7-
fastUnsecureHash,
87
getProperty
98
} from '../../plugins/utils';
109

@@ -174,7 +173,7 @@ export function replicateGraphQL<RxDocType, CheckpointType>(
174173
const graphqlReplicationState = new RxGraphQLReplicationState(
175174
url,
176175
mutateableClientState,
177-
GRAPHQL_REPLICATION_PLUGIN_IDENTITY_PREFIX + fastUnsecureHash(url.http ? url.http : url.ws as any),
176+
GRAPHQL_REPLICATION_PLUGIN_IDENTITY_PREFIX + collection.database.hashFunction(url.http ? url.http : url.ws as any),
178177
collection,
179178
deletedField,
180179
replicationPrimitivesPull,

src/plugins/replication/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import { RxDBLeaderElectionPlugin } from '../leader-election';
3333
import {
3434
ensureNotFalsy,
3535
errorToPlainJson,
36-
fastUnsecureHash,
3736
flatClone,
3837
PROMISE_RESOLVE_FALSE,
3938
PROMISE_RESOLVE_TRUE,
@@ -426,7 +425,7 @@ export function replicateRxCollection<RxDocType, CheckpointType>(
426425
}: ReplicationOptions<RxDocType, CheckpointType>
427426
): RxReplicationState<RxDocType, CheckpointType> {
428427
addRxPlugin(RxDBLeaderElectionPlugin);
429-
const replicationIdentifierHash = fastUnsecureHash(
428+
const replicationIdentifierHash = collection.database.hashFunction(
430429
[
431430
collection.database.name,
432431
collection.name,

src/plugins/utils/utils-hash.ts

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,11 @@
1-
1+
import { sha256 } from 'ohash';
22
/**
3-
* This is a very fast hash method
4-
* but it is not cryptographically secure.
5-
* For each run it will append a number between 0 and 2147483647 (=biggest 32 bit int).
6-
* @link http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
7-
* @return a string as hash-result
8-
*/
9-
export function fastUnsecureHash(
10-
inputString: string,
11-
// used to test the polyfill
12-
doNotUseTextEncoder?: boolean
13-
): string {
14-
let hashValue = 0,
15-
i, chr, len;
16-
17-
/**
18-
* For better performance we first transform all
19-
* chars into their ascii numbers at once.
20-
*
21-
* This is what makes the murmurhash implementation such fast.
22-
* @link https://github.com/perezd/node-murmurhash/blob/master/murmurhash.js#L4
23-
*/
24-
let encoded: Uint8Array | number[];
25-
26-
/**
27-
* All modern browsers support the TextEncoder
28-
* @link https://caniuse.com/textencoder
29-
* But to make RxDB work in other JavaScript runtimes,
30-
* like when using it in flutter or QuickJS, we need to
31-
* make it work even when there is no TextEncoder.
32-
*
33-
* TODO is a text encoder really faster then using charCodeAt?
34-
*/
35-
if (typeof TextEncoder !== 'undefined' && !doNotUseTextEncoder) {
36-
encoded = new TextEncoder().encode(inputString);
37-
} else {
38-
encoded = [];
39-
for (let j = 0; j < inputString.length; j++) {
40-
encoded.push(inputString.charCodeAt(j));
41-
}
42-
}
43-
44-
for (i = 0, len = inputString.length; i < len; i++) {
45-
chr = encoded[i];
46-
hashValue = ((hashValue << 5) - hashValue) + chr;
47-
hashValue |= 0; // Convert to 32bit integer
48-
}
49-
if (hashValue < 0) {
50-
hashValue = hashValue * -1;
51-
}
52-
53-
/**
54-
* To make the output smaller
55-
* but still have it to represent the same value,
56-
* we use the biggest radix of 36 instead of just
57-
* transforming it into a hex string.
58-
*/
59-
return hashValue.toString(36);
60-
}
61-
62-
/**
63-
* Default hash method used to create revision hashes
64-
* that do not have to be cryptographically secure.
3+
* Default hash method used to hash
4+
* strings and do equal comparisons.
5+
*
656
* IMPORTANT: Changing the default hashing method
667
* requires a BREAKING change!
678
*/
68-
export function defaultHashFunction(input: string): string {
69-
return fastUnsecureHash(input);
9+
export function defaultHashSha256(input: string): string {
10+
return sha256(input);
7011
}

src/replication-protocol/checkpoint.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import type {
1010
import {
1111
createRevision,
1212
ensureNotFalsy,
13-
fastUnsecureHash,
1413
getDefaultRevision,
1514
getDefaultRxDocumentMeta,
1615
getFromObjectOrThrow,
@@ -143,7 +142,7 @@ export async function setCheckpoint<RxDocType, CheckpointType>(
143142
export function getCheckpointKey<RxDocType>(
144143
input: RxStorageInstanceReplicationInput<RxDocType>
145144
): string {
146-
const hash = fastUnsecureHash([
145+
const hash = input.hashFunction([
147146
input.identifier,
148147
input.forkInstance.databaseName,
149148
input.forkInstance.collectionName

0 commit comments

Comments
 (0)