added namespace field and signature using it for our own 'retrieve'
parent
6e2b2d44f8
commit
50ca1bcda9
@ -0,0 +1,92 @@
|
||||
import { isNumber } from 'lodash';
|
||||
import { createOrUpdateItem, getItemById } from '../../../data/channelsItem';
|
||||
|
||||
let hasSeenHardfork190: boolean | undefined;
|
||||
let hasSeenHardfork191: boolean | undefined;
|
||||
|
||||
/**
|
||||
* this is only intended for testing. Do not call this in production.
|
||||
*/
|
||||
export function resetHardForkCachedValues() {
|
||||
hasSeenHardfork190 = hasSeenHardfork191 = undefined;
|
||||
}
|
||||
|
||||
export async function getHasSeenHF190() {
|
||||
if (hasSeenHardfork190 === undefined) {
|
||||
// read values from db and cache them as it looks like we did not
|
||||
const oldHhasSeenHardfork190 = (await getItemById('hasSeenHardfork190'))?.value;
|
||||
|
||||
// values do not exist in the db yet. Let's store false for now in the db and update our cached value.
|
||||
if (oldHhasSeenHardfork190 === undefined) {
|
||||
await createOrUpdateItem({ id: 'hasSeenHardfork190', value: false });
|
||||
hasSeenHardfork190 = false;
|
||||
} else {
|
||||
hasSeenHardfork190 = oldHhasSeenHardfork190;
|
||||
}
|
||||
}
|
||||
return hasSeenHardfork190;
|
||||
}
|
||||
|
||||
export async function getHasSeenHF191() {
|
||||
if (hasSeenHardfork191 === undefined) {
|
||||
// read values from db and cache them as it looks like we did not
|
||||
const oldHhasSeenHardfork191 = (await getItemById('hasSeenHardfork191'))?.value;
|
||||
|
||||
// values do not exist in the db yet. Let's store false for now in the db and update our cached value.
|
||||
if (oldHhasSeenHardfork191 === undefined) {
|
||||
await createOrUpdateItem({ id: 'hasSeenHardfork191', value: false });
|
||||
hasSeenHardfork191 = false;
|
||||
} else {
|
||||
hasSeenHardfork191 = oldHhasSeenHardfork191;
|
||||
}
|
||||
}
|
||||
return hasSeenHardfork191;
|
||||
}
|
||||
|
||||
export async function handleHardforkResult(json: Record<string, any>) {
|
||||
if (hasSeenHardfork190 === undefined || hasSeenHardfork191 === undefined) {
|
||||
// read values from db and cache them as it looks like we did not
|
||||
const oldHhasSeenHardfork190 = (await getItemById('hasSeenHardfork190'))?.value;
|
||||
const oldHasSeenHardfork191 = (await getItemById('hasSeenHardfork191'))?.value;
|
||||
|
||||
// values do not exist in the db yet. Let's store false for now in the db and update our cached value.
|
||||
if (oldHhasSeenHardfork190 === undefined) {
|
||||
await createOrUpdateItem({ id: 'hasSeenHardfork190', value: false });
|
||||
hasSeenHardfork190 = false;
|
||||
} else {
|
||||
hasSeenHardfork190 = oldHhasSeenHardfork190;
|
||||
}
|
||||
if (oldHasSeenHardfork191 === undefined) {
|
||||
await createOrUpdateItem({ id: 'hasSeenHardfork191', value: false });
|
||||
hasSeenHardfork191 = false;
|
||||
} else {
|
||||
hasSeenHardfork191 = oldHasSeenHardfork191;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSeenHardfork191 && hasSeenHardfork190) {
|
||||
// no need to do any of this if we already know both forks happened
|
||||
window.log.info('hardfork 19.1 already happened. No need to go any further');
|
||||
return;
|
||||
}
|
||||
|
||||
// json.hf is an array of 2 number if it is set. Make sure this is the case before doing anything else
|
||||
if (
|
||||
json?.hf &&
|
||||
Array.isArray(json.hf) &&
|
||||
json.hf.length === 2 &&
|
||||
isNumber(json.hf[0]) &&
|
||||
isNumber(json.hf[1])
|
||||
) {
|
||||
if (!hasSeenHardfork190 && json.hf[0] >= 19 && json.hf[1] >= 0) {
|
||||
window.log.info('[HF]: We just detected HF 19.0 on "retrieve"');
|
||||
await createOrUpdateItem({ id: 'hasSeenHardfork190', value: true });
|
||||
hasSeenHardfork190 = true;
|
||||
}
|
||||
if (!hasSeenHardfork191 && json.hf[0] >= 19 && json.hf[1] >= 1) {
|
||||
window.log.info('[HF]: We just detected HF 19.1 on "retrieve"');
|
||||
await createOrUpdateItem({ id: 'hasSeenHardfork191', value: true });
|
||||
hasSeenHardfork191 = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,347 @@
|
||||
import { expect } from 'chai';
|
||||
import Sinon from 'sinon';
|
||||
import {
|
||||
getHasSeenHF190,
|
||||
getHasSeenHF191,
|
||||
handleHardforkResult,
|
||||
resetHardForkCachedValues,
|
||||
} from '../../../../session/apis/snode_api/hfHandling';
|
||||
import { TestUtils } from '../../../test-utils';
|
||||
|
||||
// tslint:disable-next-line: max-func-body-length
|
||||
describe('hardfork handling', () => {
|
||||
describe('getHasSeenHF190', () => {
|
||||
afterEach(() => {
|
||||
Sinon.restore();
|
||||
resetHardForkCachedValues();
|
||||
});
|
||||
|
||||
it('fetches from db if undefined, and write to db false if db value is undefined', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF190();
|
||||
expect(ret).to.be.eq(false, 'getHasSeenHF190 should return false');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.calledOnce).to.be.eq(true, 'createItem should have been called');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('fetches from db if undefined, and does not write to db if db value is not undefined', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({
|
||||
id: 'getHasSeenHF190',
|
||||
value: false,
|
||||
});
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF190();
|
||||
expect(ret).to.be.eq(false, 'getHasSeenHF190 should return false');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called');
|
||||
});
|
||||
|
||||
it('fetches from db if undefined, and does not write to db if db value is not undefined - 2', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({
|
||||
id: 'getHasSeenHF190',
|
||||
value: true,
|
||||
});
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF190();
|
||||
expect(ret).to.be.eq(true, 'getHasSeenHF190 should return false');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called');
|
||||
});
|
||||
|
||||
it('fetches from db only the value is not cached already', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({
|
||||
id: 'getHasSeenHF190',
|
||||
value: true,
|
||||
});
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF190();
|
||||
const ret2 = await getHasSeenHF190();
|
||||
expect(ret).to.be.eq(true, 'getHasSeenHF190 should return false');
|
||||
expect(ret2).to.be.eq(true, 'getHasSeenHF190 should return false - 2');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getHasSeenHF191', () => {
|
||||
afterEach(() => {
|
||||
Sinon.restore();
|
||||
resetHardForkCachedValues();
|
||||
});
|
||||
|
||||
it('fetches from db if undefined, and write to db false if db value is undefined', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF191();
|
||||
expect(ret).to.be.eq(false, 'getHasSeenHF191 should return false');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.calledOnce).to.be.eq(true, 'createItem should have been called');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('fetches from db if undefined, and does not write to db if db value is not undefined', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({
|
||||
id: 'getHasSeenHF191',
|
||||
value: false,
|
||||
});
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF191();
|
||||
expect(ret).to.be.eq(false, 'getHasSeenHF191 should return false');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called');
|
||||
});
|
||||
|
||||
it('fetches from db if undefined, and does not write to db if db value is not undefined - 2', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({
|
||||
id: 'getHasSeenHF191',
|
||||
value: true,
|
||||
});
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF191();
|
||||
expect(ret).to.be.eq(true, 'getHasSeenHF191 should return false');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called');
|
||||
});
|
||||
|
||||
it('fetches from db only the value is not cached already', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({
|
||||
id: 'getHasSeenHF191',
|
||||
value: true,
|
||||
});
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
const ret = await getHasSeenHF191();
|
||||
const ret2 = await getHasSeenHF191();
|
||||
expect(ret).to.be.eq(true, 'getHasSeenHF191 should return false');
|
||||
expect(ret2).to.be.eq(true, 'getHasSeenHF191 should return false - 2');
|
||||
|
||||
expect(getItemById.calledOnce).to.be.eq(true, 'getItemById should have been called');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called');
|
||||
});
|
||||
});
|
||||
|
||||
// tslint:disable-next-line: max-func-body-length
|
||||
describe('handleHardforkResult', () => {
|
||||
afterEach(() => {
|
||||
Sinon.restore();
|
||||
resetHardForkCachedValues();
|
||||
});
|
||||
|
||||
it('does not fail if null is given as json', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult(null as any);
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not fail on empty json object', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({});
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not fail with invalid array length of 3', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [1, 2, 3] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not fail with invalid array length of 3', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [1, 2, 3] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not fail with invalid array length of but not numbers', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: ['1', 2] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not fail with invalid array length of 1 ', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [1] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not write new data if hf major is <= 18 ', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [18, 9] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledTwice).to.be.eq(true, 'createItem should have been calledTwice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
});
|
||||
|
||||
it('does write new data if hf major is === 19 and minor === 0 ', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [19, 0] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.calledThrice).to.be.eq(true, 'createItem should have been calledThrice');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
|
||||
expect(createItem.args[2][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: true },
|
||||
'createItem should have been to set hasSeenHardfork191 to true in the db'
|
||||
);
|
||||
|
||||
getItemById.resetHistory();
|
||||
createItem.resetHistory();
|
||||
expect(await getHasSeenHF190()).to.be.eq(true, 'getHasSeenHF190 should have been true');
|
||||
expect(getItemById.notCalled).to.be.eq(true, 'getItemById should not have been called more');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called more');
|
||||
});
|
||||
|
||||
it('does write new data if hf major is === 19 and minor === 1 ', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves(undefined);
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [19, 1] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.callCount).to.be.eq(4, 'createItem should have been 4');
|
||||
expect(createItem.args[0][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: false },
|
||||
'createItem should have been to set hasSeenHardfork190 to false in the db'
|
||||
);
|
||||
expect(createItem.args[1][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: false },
|
||||
'createItem should have been to set hasSeenHardfork191 to false in the db'
|
||||
);
|
||||
|
||||
expect(createItem.args[2][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork190', value: true },
|
||||
'createItem should have been to set hasSeenHardfork190 to true in the db'
|
||||
);
|
||||
expect(createItem.args[3][0]).to.be.deep.eq(
|
||||
{ id: 'hasSeenHardfork191', value: true },
|
||||
'createItem should have been to set hasSeenHardfork191 to true in the db'
|
||||
);
|
||||
getItemById.resetHistory();
|
||||
createItem.resetHistory();
|
||||
expect(await getHasSeenHF190()).to.be.eq(true, 'getHasSeenHF190 should have been true');
|
||||
expect(await getHasSeenHF191()).to.be.eq(true, 'getHasSeenHF191 should have been true');
|
||||
expect(getItemById.notCalled).to.be.eq(true, 'getItemById should not have been called more');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called more');
|
||||
});
|
||||
|
||||
it('does not write new data if hf major is === 19 and minor === 1 but it is already known we have seen both forks ', async () => {
|
||||
const getItemById = TestUtils.stubDataItem('getItemById').resolves({ id: '', value: true });
|
||||
const createItem = TestUtils.stubDataItem('createOrUpdateItem').resolves();
|
||||
|
||||
await handleHardforkResult({ hf: [19, 1] });
|
||||
expect(getItemById.calledTwice).to.be.eq(true, 'getItemById should have been calledTwice');
|
||||
expect(createItem.callCount).to.be.eq(0, 'createItem should have been 0');
|
||||
|
||||
getItemById.resetHistory();
|
||||
createItem.resetHistory();
|
||||
expect(await getHasSeenHF190()).to.be.eq(true, 'getHasSeenHF190 should have been true');
|
||||
expect(await getHasSeenHF191()).to.be.eq(true, 'getHasSeenHF191 should have been true');
|
||||
expect(getItemById.notCalled).to.be.eq(true, 'getItemById should not have been called more');
|
||||
expect(createItem.notCalled).to.be.eq(true, 'createItem should not have been called more');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue