-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically choose next validator from propose queue #40
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,12 +13,16 @@ import { transferCtrl } from './transfer-ctrl' | |
import { customDeployCtrl } from './custom-deploy-ctrl' | ||
import { newRevAddress } from '@tgrospic/rnode-grpc-js' | ||
|
||
import { makeRNodeWeb } from '../../rnode-web' | ||
|
||
/* | ||
This will display the test page to select local, testnet, and mainnet validators | ||
and make REV transfers and check balance. | ||
*/ | ||
|
||
const {rnodeHttp} = makeRNodeWeb({fetch}) | ||
const repoUrl = 'https://github.com/tgrospic/rnode-client-js' | ||
const randomOffset = Math.floor(Math.random() * (2 - 1 + 1)) + 1 //Random number between 1 and 2, for load balancing | ||
|
||
const mainCtrl = (st, effects) => { | ||
const { appCheckBalance, appTransfer, appSendDeploy, appPropose, log, warn } = effects | ||
|
@@ -47,13 +51,14 @@ const mainCtrl = (st, effects) => { | |
.set(account) | ||
|
||
// State lenses for each control | ||
const selSt = st.o('sel') | ||
const addressSt = st.o('address') | ||
const balanceSt = st.o('balance') | ||
const transferSt = st.o('transfer') | ||
const customDeploySt = st.o('customDeploy') | ||
|
||
const {nets, netsDev, netsTestMain, sel, wallet, devMode} = st.view() | ||
const selSt = st.o('sel') | ||
const addressSt = st.o('address') | ||
const balanceSt = st.o('balance') | ||
const transferSt = st.o('transfer') | ||
const customDeploySt = st.o('customDeploy') | ||
const autoSelectIntervalSt = st.o('autoSelectInterval') | ||
|
||
const {nets, netsDev, netsTestMain, sel, wallet, devMode, autoSelectDisabled} = st.view() | ||
const valNodeUrls = getNodeUrls(sel.valNode) | ||
const readNodeUrls = getNodeUrls(sel.readNode) | ||
|
||
|
@@ -68,6 +73,42 @@ const mainCtrl = (st, effects) => { | |
st.update(s => ({...s, nets, sel, devMode: enabled})) | ||
} | ||
|
||
const FetchNextValidator = async () => { | ||
const {autoSelectDisabled} = st.view() | ||
if (autoSelectDisabled) { | ||
//Disables transfer/deploy buttons once during toggle | ||
transferSt.update(s => ({...s, fetching: true})) | ||
customDeploySt.update(s => ({...s, fetching: true})) | ||
} | ||
const { nextToPropose } = await rnodeHttp("https://status.rchain.coop", 'validators') | ||
|
||
const net = nets[1] //Select Mainnet | ||
|
||
const next = net.hosts.filter(obj => { | ||
return obj.domain === nextToPropose.host | ||
})[0]; | ||
const nextId = net.hosts.indexOf(next); | ||
|
||
const sel = {valNode: net.hosts[(nextId + randomOffset) % net.hosts.length], readNode: net.readOnlys[0]} | ||
|
||
st.update(s => ({...s, sel})) | ||
transferSt.update(s => ({...s, fetching: false})) | ||
customDeploySt.update(s => ({...s, fetching: false})) | ||
} | ||
|
||
const onAutoSelectToggle = ({disabled}) => { | ||
if (!disabled) { | ||
const interval = setInterval(FetchNextValidator, 5 * 1000) | ||
autoSelectIntervalSt.set({interval: interval}) | ||
FetchNextValidator() //Trigger immediately | ||
} else { | ||
const {interval} = autoSelectIntervalSt.view({}) | ||
clearInterval(interval) | ||
} | ||
|
||
st.update(s => ({...s, autoSelectDisabled: disabled})) | ||
} | ||
|
||
// TEMP: Hard Fork 1 info | ||
const startMs = new Date('2021-07-18 15:00').getTime() | ||
const endMs = new Date('2021-07-25 01:00').getTime() | ||
|
@@ -94,7 +135,7 @@ const mainCtrl = (st, effects) => { | |
|
||
// Selector control | ||
m('hr'), | ||
selectorCtrl(selSt, {nets, onDevMode}), | ||
selectorCtrl(selSt, {nets, onDevMode, onAutoSelectToggle}), | ||
|
||
// REV wallet control | ||
addressCtrl(addressSt, {wallet, node: valNodeUrls, onAddAccount: onSaveAccount}), | ||
|
@@ -128,6 +169,7 @@ const prepareNets = nets => | |
})) | ||
|
||
const devMode = false | ||
const autoSelectDisabled = true | ||
const netsDev = prepareNets([localNet]) | ||
const netsTestMain = prepareNets([testNet, mainNet]) | ||
const nets = devMode ? netsDev : netsTestMain | ||
|
@@ -146,6 +188,7 @@ const initialState = { | |
wallet: [], // [{name: 'My REV account', ...newRevAddress()}], | ||
// Dev mode (show local networks) | ||
devMode, | ||
autoSelectDisabled: autoSelectDisabled | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use |
||
} | ||
|
||
export const startApp = (element, effects) => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ import * as R from 'ramda' | |
import m from 'mithril' | ||
import { getNodeUrls } from '../../rchain-networks' | ||
|
||
export const selectorCtrl = (st, {nets, onDevMode}) => { | ||
export const selectorCtrl = (st, {nets, onDevMode, onAutoSelectToggle}) => { | ||
const findValidatorByIndex = index => | ||
nets.flatMap(({hosts}) => hosts)[index] | ||
|
||
|
@@ -13,6 +13,8 @@ export const selectorCtrl = (st, {nets, onDevMode}) => { | |
const onSelIdx = ev => { | ||
const sel = findValidatorByIndex(ev.target.selectedIndex) | ||
const read = sel.name === valNode.name ? readNode : findReadOnlyByIndex(0, sel.name) | ||
const isMainnet = sel.name === 'mainnet' | ||
sel.name !== valNode.name ? onAutoSelectToggle({disabled: !isMainnet}) : undefined | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not assignment so no need to explicitly set undefined value. sel.name !== valNode.name && onAutoSelectToggle({disabled: !isMainnet}) |
||
st.set({valNode: sel, readNode: read}) | ||
} | ||
|
||
|
@@ -26,6 +28,11 @@ export const selectorCtrl = (st, {nets, onDevMode}) => { | |
onDevMode({enabled: checked}) | ||
} | ||
|
||
const onAutoSelectInput = ev => { | ||
const checked = ev.target?.checked || false | ||
onAutoSelectToggle({disabled: checked}) | ||
} | ||
|
||
const getDdlText = ({name, domain, grpc, https, http}) => { | ||
const httpInfo = !!https ? `:${https}` : !!http ? `:${http}` : ' ' | ||
const isLocal = name === 'localnet' | ||
|
@@ -36,7 +43,7 @@ export const selectorCtrl = (st, {nets, onDevMode}) => { | |
R.eqBy(({domain, gprc, https, http}) => ({domain, gprc, https, http}), v1, v2) | ||
|
||
// Control state | ||
const {valNode, readNode, devMode} = st.view({}) | ||
const {valNode, readNode, devMode, autoSelectDisabled} = st.view({}) | ||
|
||
const isLocal = valNode.name === 'localnet' | ||
const isTestnet = valNode.name === 'testnet' | ||
|
@@ -45,6 +52,7 @@ export const selectorCtrl = (st, {nets, onDevMode}) => { | |
const readUrls = getNodeUrls(readNode) | ||
// Dev mode tooltip text | ||
const devModeText = `Development mode for locally accessible nodes` | ||
const autoSelectText = `Disable automatic selection of validator` | ||
|
||
return m('.ctrl.selector-ctrl', | ||
// Validator selector | ||
|
@@ -66,6 +74,11 @@ export const selectorCtrl = (st, {nets, onDevMode}) => { | |
), | ||
), | ||
|
||
isMainnet && [ | ||
m('label', {title: autoSelectText}, | ||
m('input[type=checkbox]', {checked: autoSelectDisabled, oninput: onAutoSelectInput}), 'Disable Auto Select') | ||
], | ||
|
||
// Validator info | ||
m(''), | ||
m('span', 'Direct links'), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UI controls should not have direct dependency to http requests so this functions should be in
rnode-web.js
file and imported together with other effects.