Force Node Change on Web3 Unset (#1207)
* add CONFIG_NODE_CHANGE_FORCE action * implement forceful node change on web3 * update comment * add test * make tsc happy * update test
This commit is contained in:
parent
1a711b5c20
commit
23546a1cf9
|
@ -48,6 +48,14 @@ export function changeNodeIntent(payload: string): interfaces.ChangeNodeIntentAc
|
|||
};
|
||||
}
|
||||
|
||||
export type TChangeNodeForce = typeof changeNodeForce;
|
||||
export function changeNodeForce(payload: string): interfaces.ChangeNodeForceAction {
|
||||
return {
|
||||
type: TypeKeys.CONFIG_NODE_CHANGE_FORCE,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export type TAddCustomNode = typeof addCustomNode;
|
||||
export function addCustomNode(
|
||||
payload: interfaces.AddCustomNodeAction['payload']
|
||||
|
|
|
@ -36,6 +36,11 @@ export interface ChangeNodeIntentAction {
|
|||
type: TypeKeys.CONFIG_NODE_CHANGE_INTENT;
|
||||
payload: string;
|
||||
}
|
||||
/*** Force Change Node ***/
|
||||
export interface ChangeNodeForceAction {
|
||||
type: TypeKeys.CONFIG_NODE_CHANGE_FORCE;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
/*** Add Custom Node ***/
|
||||
export interface AddCustomNodeAction {
|
||||
|
|
|
@ -10,6 +10,7 @@ export enum TypeKeys {
|
|||
CONFIG_NODE_WEB3_UNSET = 'CONFIG_NODE_WEB3_UNSET',
|
||||
CONFIG_NODE_CHANGE = 'CONFIG_NODE_CHANGE',
|
||||
CONFIG_NODE_CHANGE_INTENT = 'CONFIG_NODE_CHANGE_INTENT',
|
||||
CONFIG_NODE_CHANGE_FORCE = 'CONFIG_NODE_CHANGE_FORCE',
|
||||
|
||||
CONFIG_ADD_CUSTOM_NODE = 'CONFIG_ADD_CUSTOM_NODE',
|
||||
CONFIG_REMOVE_CUSTOM_NODE = 'CONFIG_REMOVE_CUSTOM_NODE',
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
changeNodeIntent,
|
||||
setLatestBlock,
|
||||
AddCustomNodeAction,
|
||||
ChangeNodeForceAction,
|
||||
ChangeNodeIntentAction
|
||||
} from 'actions/config';
|
||||
import { showNotification } from 'actions/notifications';
|
||||
|
@ -181,8 +182,30 @@ export function* handleNewNetwork() {
|
|||
yield put(resetWallet());
|
||||
}
|
||||
|
||||
export function* handleNodeChangeForce({ payload: staticNodeIdToSwitchTo }: ChangeNodeForceAction) {
|
||||
// does not perform node online check before changing nodes
|
||||
// necessary when switching back from Web3 provider so node
|
||||
// dropdown does not get stuck if node is offline
|
||||
|
||||
const isStaticNode: boolean = yield select(isStaticNodeId, staticNodeIdToSwitchTo);
|
||||
|
||||
if (!isStaticNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nodeConfig = yield select(getStaticNodeFromId, staticNodeIdToSwitchTo);
|
||||
|
||||
// force the node change
|
||||
yield put(changeNode({ networkId: nodeConfig.network, nodeId: staticNodeIdToSwitchTo }));
|
||||
|
||||
// also put the change through as usual so status check and
|
||||
// error messages occur if the node is unavailable
|
||||
yield put(changeNodeIntent(staticNodeIdToSwitchTo));
|
||||
}
|
||||
|
||||
export const node = [
|
||||
takeEvery(TypeKeys.CONFIG_NODE_CHANGE_INTENT, handleNodeChangeIntent),
|
||||
takeEvery(TypeKeys.CONFIG_NODE_CHANGE_FORCE, handleNodeChangeForce),
|
||||
takeLatest(TypeKeys.CONFIG_POLL_OFFLINE_STATUS, handlePollOfflineStatus),
|
||||
takeEvery(TypeKeys.CONFIG_LANGUAGE_CHANGE, reload),
|
||||
takeEvery(TypeKeys.CONFIG_ADD_CUSTOM_NODE, switchToNewNode)
|
||||
|
|
|
@ -2,7 +2,7 @@ import { TypeKeys as WalletTypeKeys } from 'actions/wallet/constants';
|
|||
import { Web3Wallet } from 'libs/wallet';
|
||||
import { SagaIterator } from 'redux-saga';
|
||||
import { select, put, takeEvery, call } from 'redux-saga/effects';
|
||||
import { changeNodeIntent, TypeKeys, web3SetNode } from 'actions/config';
|
||||
import { changeNodeForce, TypeKeys, web3SetNode } from 'actions/config';
|
||||
import { getNodeId, getStaticAltNodeIdToWeb3, getNetworkNameByChainId } from 'selectors/config';
|
||||
import { setupWeb3Node, Web3Service } from 'libs/nodes/web3';
|
||||
import { Web3NodeConfig } from 'types/node';
|
||||
|
@ -34,8 +34,8 @@ export function* unsetWeb3NodeOnWalletEvent(action): SagaIterator {
|
|||
}
|
||||
|
||||
const altNode = yield select(getStaticAltNodeIdToWeb3);
|
||||
// switch back to a node with the same network as MetaMask/Mist
|
||||
yield put(changeNodeIntent(altNode));
|
||||
// forcefully switch back to a node with the same network as MetaMask/Mist
|
||||
yield put(changeNodeForce(altNode));
|
||||
}
|
||||
|
||||
export function* unsetWeb3Node(): SagaIterator {
|
||||
|
@ -46,8 +46,8 @@ export function* unsetWeb3Node(): SagaIterator {
|
|||
}
|
||||
|
||||
const altNode = yield select(getStaticAltNodeIdToWeb3);
|
||||
// switch back to a node with the same network as MetaMask/Mist
|
||||
yield put(changeNodeIntent(altNode));
|
||||
// forcefully switch back to a node with the same network as MetaMask/Mist
|
||||
yield put(changeNodeForce(altNode));
|
||||
}
|
||||
|
||||
export const web3 = [
|
||||
|
|
|
@ -2,7 +2,13 @@ import { configuredStore } from 'store';
|
|||
import { delay } from 'redux-saga';
|
||||
import { call, cancel, fork, put, take, select } from 'redux-saga/effects';
|
||||
import { cloneableGenerator, createMockTask } from 'redux-saga/utils';
|
||||
import { toggleOffline, changeNode, changeNodeIntent, setLatestBlock } from 'actions/config';
|
||||
import {
|
||||
toggleOffline,
|
||||
changeNode,
|
||||
changeNodeIntent,
|
||||
changeNodeForce,
|
||||
setLatestBlock
|
||||
} from 'actions/config';
|
||||
import {
|
||||
handleNodeChangeIntent,
|
||||
handlePollOfflineStatus,
|
||||
|
@ -274,8 +280,8 @@ describe('unsetWeb3Node*', () => {
|
|||
expect(gen.next(node).value).toEqual(select(getStaticAltNodeIdToWeb3));
|
||||
});
|
||||
|
||||
it('should put changeNodeIntent', () => {
|
||||
expect(gen.next(alternativeNodeId).value).toEqual(put(changeNodeIntent(alternativeNodeId)));
|
||||
it('should put changeNodeForce', () => {
|
||||
expect(gen.next(alternativeNodeId).value).toEqual(put(changeNodeForce(alternativeNodeId)));
|
||||
});
|
||||
|
||||
it('should be done', () => {
|
||||
|
@ -304,8 +310,8 @@ describe('unsetWeb3NodeOnWalletEvent*', () => {
|
|||
expect(gen.next(mockNodeId).value).toEqual(select(getStaticAltNodeIdToWeb3));
|
||||
});
|
||||
|
||||
it('should put changeNodeIntent', () => {
|
||||
expect(gen.next(alternativeNodeId).value).toEqual(put(changeNodeIntent(alternativeNodeId)));
|
||||
it('should put changeNodeForce', () => {
|
||||
expect(gen.next(alternativeNodeId).value).toEqual(put(changeNodeForce(alternativeNodeId)));
|
||||
});
|
||||
|
||||
it('should be done', () => {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import { configuredStore } from 'store';
|
||||
import { cloneableGenerator } from 'redux-saga/utils';
|
||||
import { handleNodeChangeForce } from 'sagas/config/node';
|
||||
import { put, select } from 'redux-saga/effects';
|
||||
import { isStaticNodeId, getStaticNodeFromId } from 'selectors/config';
|
||||
import { changeNode, changeNodeIntent } from 'actions/config';
|
||||
|
||||
// init module
|
||||
configuredStore.getState();
|
||||
|
||||
describe('handleNodeChangeForce*', () => {
|
||||
const payload: any = 'nodeId';
|
||||
const action: any = { payload };
|
||||
const gen = cloneableGenerator(handleNodeChangeForce)(action);
|
||||
const nodeConfig: any = { network: 'network' };
|
||||
|
||||
it('should select isStaticNodeId', () => {
|
||||
expect(gen.next().value).toEqual(select(isStaticNodeId, payload));
|
||||
});
|
||||
|
||||
it('should return if not static node', () => {
|
||||
const clone = gen.clone();
|
||||
expect(clone.next(false).done).toEqual(true);
|
||||
});
|
||||
|
||||
it('should select getStaticNodeFromId', () => {
|
||||
expect(gen.next(true).value).toEqual(select(getStaticNodeFromId, payload));
|
||||
});
|
||||
|
||||
it('should force the node change', () => {
|
||||
expect(gen.next(nodeConfig).value).toEqual(
|
||||
put(
|
||||
changeNode({
|
||||
networkId: nodeConfig.network,
|
||||
nodeId: payload
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('should put a change node intent', () => {
|
||||
expect(gen.next().value).toEqual(put(changeNodeIntent(payload)));
|
||||
});
|
||||
|
||||
it('should be done', () => {
|
||||
expect(gen.next().done).toEqual(true);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue