Prevent invalid gas price states (#996)

* Slider using value instead of raw to prevent errors. Dont show empty gas price as invalid. Clamp slider values to min / max on mount.

* Remove gas price from local storage.
This commit is contained in:
William O'Beirne 2018-02-05 18:14:23 -05:00 committed by Daniel Ternyak
parent 942eb6b341
commit 39da226cd1
4 changed files with 30 additions and 27 deletions

View File

@ -96,7 +96,11 @@ class TXMetaDataPanel extends React.Component<Props, State> {
options={advancedGasOptions}
/>
) : (
<SimpleGas gasPrice={gasPrice} inputGasPrice={this.handleGasPriceInput} />
<SimpleGas
gasPrice={gasPrice}
inputGasPrice={this.handleGasPriceInput}
setGasPrice={this.props.inputGasPrice}
/>
)}
{!offline &&

View File

@ -74,7 +74,9 @@ class AdvancedGas extends React.Component<Props, State> {
<div className="AdvancedGas-gas-price">
<label>{translate('OFFLINE_Step2_Label_3')} (gwei)</label>
<input
className={classnames('form-control', { 'is-invalid': !validGasPrice })}
className={classnames('form-control', {
'is-invalid': !!gasPrice.raw && !validGasPrice
})}
type="number"
placeholder="40"
value={gasPrice.raw}

View File

@ -9,11 +9,13 @@ import { getGasLimitEstimationTimedOut } from 'selectors/transaction';
import { connect } from 'react-redux';
import { GasLimitField } from 'components/GasLimitField';
import { getIsWeb3Node } from 'selectors/config';
import { Wei, fromWei } from 'libs/units';
const SliderWithTooltip = Slider.createSliderWithTooltip(Slider);
interface OwnProps {
gasPrice: AppState['transaction']['fields']['gasPrice'];
inputGasPrice(rawGas: string);
setGasPrice(rawGas: string);
}
interface StateProps {
@ -24,6 +26,10 @@ interface StateProps {
type Props = OwnProps & StateProps;
class SimpleGas extends React.Component<Props> {
public componentDidMount() {
this.fixGasPrice(this.props.gasPrice);
}
public render() {
const { gasPrice, gasLimitEstimationTimedOut, isWeb3Node } = this.props;
@ -53,7 +59,7 @@ class SimpleGas extends React.Component<Props> {
onChange={this.handleSlider}
min={gasPriceDefaults.gasPriceMinGwei}
max={gasPriceDefaults.gasPriceMaxGwei}
value={parseFloat(gasPrice.raw)}
value={this.getGasPriceGwei(gasPrice.value)}
tipFormatter={gas => `${gas} Gwei`}
/>
<div className="SimpleGas-slider-labels">
@ -78,7 +84,22 @@ class SimpleGas extends React.Component<Props> {
private handleSlider = (gasGwei: number) => {
this.props.inputGasPrice(gasGwei.toString());
};
private fixGasPrice(gasPrice: AppState['transaction']['fields']['gasPrice']) {
// If the gas price is above or below our minimum, bring it in line
const gasPriceGwei = this.getGasPriceGwei(gasPrice.value);
if (gasPriceGwei > gasPriceDefaults.gasPriceMaxGwei) {
this.props.setGasPrice(gasPriceDefaults.gasPriceMaxGwei.toString());
} else if (gasPriceGwei < gasPriceDefaults.gasPriceMinGwei) {
this.props.setGasPrice(gasPriceDefaults.gasPriceMinGwei.toString());
}
}
private getGasPriceGwei(gasPriceValue: Wei) {
return parseFloat(fromWei(gasPriceValue, 'gwei'));
}
}
export default connect((state: AppState) => ({
gasLimitEstimationTimedOut: getGasLimitEstimationTimedOut(state),
isWeb3Node: getIsWeb3Node(state)

View File

@ -5,10 +5,6 @@ import {
State as CustomTokenState,
INITIAL_STATE as customTokensInitialState
} from 'reducers/customTokens';
import {
INITIAL_STATE as transactionInitialState,
State as TransactionState
} from 'reducers/transaction';
import { State as SwapState, INITIAL_STATE as swapInitialState } from 'reducers/swap';
import { applyMiddleware, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
@ -21,7 +17,6 @@ import { getNodeConfigFromId } from 'utils/node';
import { getNetworkConfigFromId } from 'utils/network';
import { dedupeCustomTokens } from 'utils/tokens';
import sagas from './sagas';
import { gasPricetoBase } from 'libs/units';
const configureStore = () => {
const logger = createLogger({
@ -60,7 +55,6 @@ const configureStore = () => {
}
: { ...swapInitialState };
const savedTransactionState = loadStatePropertyOrEmptyObject<TransactionState>('transaction');
const savedConfigState = loadStatePropertyOrEmptyObject<ConfigState>('config');
// If they have a saved node, make sure we assign that too. The node selected
@ -94,19 +88,6 @@ const configureStore = () => {
...configInitialState,
...savedConfigState
},
transaction: {
...transactionInitialState,
fields: {
...transactionInitialState.fields,
gasPrice:
savedTransactionState && savedTransactionState.fields.gasPrice
? {
raw: savedTransactionState.fields.gasPrice.raw,
value: gasPricetoBase(+savedTransactionState.fields.gasPrice.raw)
}
: transactionInitialState.fields.gasPrice
}
},
customTokens,
// ONLY LOAD SWAP STATE FROM LOCAL STORAGE IF STEP WAS 3
swap: swapState
@ -134,11 +115,6 @@ const configureStore = () => {
customNodes: state.config.customNodes,
customNetworks: state.config.customNetworks
},
transaction: {
fields: {
gasPrice: state.transaction.fields.gasPrice
}
},
swap: {
...state.swap,
options: {