Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/web/controls/custom-deploy-ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const customDeployCtrl = (st, {wallet = [], node, onSendDeploy, onPropose
}

// Control state
const {selRevAddr, code, phloLimit, status, dataError, proposeStatus, proposeError}
const {selRevAddr, code, phloLimit, status, dataError, proposeStatus, proposeError, fetching}
= initSelected(st.view({}), wallet)

const tokenName = node.tokenName
Expand All @@ -99,7 +99,7 @@ export const customDeployCtrl = (st, {wallet = [], node, onSendDeploy, onPropose
const labelPhloLimit = `Phlo limit (in tiny ${tokenName} x10^${node.tokenDecimal})`
const isWalletEmpty = R.isNil(wallet) || R.isEmpty(wallet)
const showPropose = node.network === 'localnet'
const canDeploy = (code || '').trim() !== '' && !!selRevAddr
const canDeploy = (code || '').trim() !== '' && !!selRevAddr && !fetching
const phloLimitPreview = showTokenDecimal(phloLimit, node.tokenDecimal)

return m('.ctrl.custom-deploy-ctrl',
Expand Down
59 changes: 51 additions & 8 deletions src/web/controls/main-ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand All @@ -68,6 +73,42 @@ const mainCtrl = (st, effects) => {
st.update(s => ({...s, nets, sel, devMode: enabled}))
}

const FetchNextValidator = async () => {
Copy link
Owner

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.

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()
Expand All @@ -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}),
Expand Down Expand Up @@ -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
Expand All @@ -146,6 +188,7 @@ const initialState = {
wallet: [], // [{name: 'My REV account', ...newRevAddress()}],
// Dev mode (show local networks)
devMode,
autoSelectDisabled: autoSelectDisabled
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use autoSelect as a positive meaning of the boolean field with the default false as disabled.

}

export const startApp = (element, effects) => {
Expand Down
17 changes: 15 additions & 2 deletions src/web/controls/selector-ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand All @@ -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
Copy link
Owner

Choose a reason for hiding this comment

The 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})
}

Expand All @@ -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'
Expand All @@ -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'
Expand All @@ -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
Expand All @@ -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'),
Expand Down
4 changes: 2 additions & 2 deletions src/web/controls/transfer-ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ export const transferCtrl = (st, {wallet, node, onTransfer, warn}) => {
}

// Control state
const {account, toAccount, amount, status, error} = initSelected(st.view({}), wallet)
const {account, toAccount, amount, status, error, fetching} = initSelected(st.view({}), wallet)

const {tokenName, tokenDecimal} = node
const labelSource = `Source ${tokenName} address`
const labelDestination = `Destination ${tokenName} address`
const labelAmount = `Amount (in tiny ${tokenName} x10^${tokenDecimal})`
const isWalletEmpty = R.isNil(wallet) || R.isEmpty(wallet)
const canTransfer = account && toAccount && amount && (account || ethDetected)
const canTransfer = account && toAccount && amount && (account || ethDetected) && !fetching
const amountPreview = showTokenDecimal(amount, tokenDecimal)

return m('.ctrl.transfer-ctrl',
Expand Down