From 62f528fc996dbcc82224ef8f442b933e7892e1f3 Mon Sep 17 00:00:00 2001 From: Daniel Kmak Date: Fri, 30 Mar 2018 13:38:52 +0200 Subject: [PATCH] [FEATURE] Add Schedule Gas Limit field --- .../transaction/actionCreators/fields.ts | 11 ++- .../actions/transaction/actionTypes/fields.ts | 14 +++- common/actions/transaction/constants.ts | 1 + .../components/AdvancedGas.tsx | 46 +++++++----- .../components/SchedulingFeeSummary.tsx | 16 ++-- .../Fields/ScheduleGasLimitField.tsx | 60 +++++++++++++++ .../components/ScheduleFields.scss} | 0 .../components/ScheduleFields.tsx | 75 +++++++++++++++++++ .../ScheduleTransaction/components/index.ts | 2 + .../current/currentSchedulingToggle.ts | 27 +++++++ .../sagas/transaction/current/index.ts | 4 +- .../components/Fields/Fields.tsx | 67 +---------------- common/libs/scheduling.ts | 7 +- common/reducers/transaction/fields/fields.ts | 6 ++ common/reducers/transaction/fields/typings.ts | 4 +- common/selectors/transaction/current.ts | 11 ++- common/selectors/transaction/fields.ts | 2 + common/selectors/transaction/transaction.ts | 14 ++-- .../transaction/fields/fields.spec.ts | 3 +- spec/selectors/transaction/fields.spec.ts | 4 + spec/selectors/transaction/helpers.spec.ts | 7 +- 21 files changed, 275 insertions(+), 106 deletions(-) create mode 100644 common/containers/Tabs/ScheduleTransaction/components/Fields/ScheduleGasLimitField.tsx rename common/containers/Tabs/{SendTransaction/components/Fields/Fields.scss => ScheduleTransaction/components/ScheduleFields.scss} (100%) create mode 100644 common/containers/Tabs/ScheduleTransaction/components/ScheduleFields.tsx create mode 100644 common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/currentSchedulingToggle.ts diff --git a/common/actions/transaction/actionCreators/fields.ts b/common/actions/transaction/actionCreators/fields.ts index 551cbb85..cc73f5cd 100644 --- a/common/actions/transaction/actionCreators/fields.ts +++ b/common/actions/transaction/actionCreators/fields.ts @@ -17,7 +17,8 @@ import { SetScheduleTimestampFieldAction, SetScheduleTypeAction, SetSchedulingToggleAction, - SetScheduleGasPriceFieldAction + SetScheduleGasPriceFieldAction, + SetScheduleGasLimitFieldAction } from '../actionTypes'; import { TypeKeys } from 'actions/transaction/constants'; @@ -139,6 +140,12 @@ const setScheduleGasPriceField = (payload: SetScheduleGasPriceFieldAction['paylo payload }); +type TSetScheduleGasLimitField = typeof setScheduleGasLimitField; +const setScheduleGasLimitField = (payload: SetScheduleGasLimitFieldAction['payload']) => ({ + type: TypeKeys.SCHEDULE_GAS_LIMIT_FIELD_SET, + payload +}); + type TReset = typeof reset; const reset = (payload: ResetAction['payload'] = { include: {}, exclude: {} }): ResetAction => ({ type: TypeKeys.RESET, @@ -164,6 +171,7 @@ export { TSetScheduleType, TSetSchedulingToggle, TSetScheduleGasPriceField, + TSetScheduleGasLimitField, TReset, inputGasLimit, inputGasPrice, @@ -183,5 +191,6 @@ export { setScheduleType, setSchedulingToggle, setScheduleGasPriceField, + setScheduleGasLimitField, reset }; diff --git a/common/actions/transaction/actionTypes/fields.ts b/common/actions/transaction/actionTypes/fields.ts index 0a20d451..c29dc36c 100644 --- a/common/actions/transaction/actionTypes/fields.ts +++ b/common/actions/transaction/actionTypes/fields.ts @@ -139,6 +139,14 @@ interface SetScheduleGasPriceFieldAction { }; } +interface SetScheduleGasLimitFieldAction { + type: TypeKeys.SCHEDULE_GAS_LIMIT_FIELD_SET; + payload: { + raw: string; + value: Wei | null; + }; +} + type InputFieldAction = InputNonceAction | InputGasLimitAction | InputDataAction; type FieldAction = @@ -154,7 +162,8 @@ type FieldAction = | SetScheduleTimestampFieldAction | SetScheduleTypeAction | SetSchedulingToggleAction - | SetScheduleGasPriceFieldAction; + | SetScheduleGasPriceFieldAction + | SetScheduleGasLimitFieldAction; export { InputGasLimitAction, @@ -178,5 +187,6 @@ export { SetScheduleTimestampFieldAction, SetScheduleTypeAction, SetSchedulingToggleAction, - SetScheduleGasPriceFieldAction + SetScheduleGasPriceFieldAction, + SetScheduleGasLimitFieldAction }; diff --git a/common/actions/transaction/constants.ts b/common/actions/transaction/constants.ts index 50b9fb88..cc6a5052 100644 --- a/common/actions/transaction/constants.ts +++ b/common/actions/transaction/constants.ts @@ -50,6 +50,7 @@ export enum TypeKeys { WINDOW_SIZE_FIELD_SET = 'WINDOW_SIZE_FIELD_SET', WINDOW_START_FIELD_SET = 'WINDOW_START_FIELD_SET', SCHEDULE_GAS_PRICE_FIELD_SET = 'SCHEDULE_GAS_PRICE_SET', + SCHEDULE_GAS_LIMIT_FIELD_SET = 'SCHEDULE_GAS_LIMIT_SET', SCHEDULE_TIMESTAMP_FIELD_SET = 'SCHEDULE_TIMESTAMP_FIELD_SET', SCHEDULE_TIMEZONE_SET = 'SCHEDULE_TIMEZONE_SET', SCHEDULE_TYPE_SET = 'SCHEDULE_TYPE_SET', diff --git a/common/components/TXMetaDataPanel/components/AdvancedGas.tsx b/common/components/TXMetaDataPanel/components/AdvancedGas.tsx index 1fb90d58..e677af7f 100644 --- a/common/components/TXMetaDataPanel/components/AdvancedGas.tsx +++ b/common/components/TXMetaDataPanel/components/AdvancedGas.tsx @@ -59,21 +59,23 @@ class AdvancedGas extends React.Component { }; public render() { - const { autoGasLimitEnabled, gasPrice, validGasPrice } = this.props; + const { autoGasLimitEnabled, gasPrice, scheduling, validGasPrice } = this.props; const { gasPriceField, gasLimitField, nonceField, dataField } = this.state.options; return (
-
- -
+ {!scheduling && ( +
+ +
+ )}
{gasPriceField && ( @@ -97,7 +99,10 @@ class AdvancedGas extends React.Component { {gasLimitField && (
- +
)} {nonceField && ( @@ -107,11 +112,12 @@ class AdvancedGas extends React.Component { )}
- {dataField && ( -
- -
- )} + {dataField && + !scheduling && ( +
+ +
+ )} {this.renderFee()}
@@ -132,7 +138,7 @@ class AdvancedGas extends React.Component { ( + render={({ gasPriceWei, scheduleGasLimit, fee, usd }) => (
{ + {timeBounty && timeBounty.value && timeBounty.value.toString()} + {gasPriceWei}{' '} * {EAC_SCHEDULING_CONFIG.SCHEDULING_GAS_LIMIT.toString()} +{' '} {scheduleGasPrice && scheduleGasPrice.value && scheduleGasPrice.value.toString()}{' '} - * ({EAC_SCHEDULING_CONFIG.FUTURE_EXECUTION_COST.toString()} + {gasLimit}) = {fee}{' '} - {usd && ~= ${usd} USD} + * ({EAC_SCHEDULING_CONFIG.FUTURE_EXECUTION_COST.toString()} + {scheduleGasLimit}) + = {fee} {usd && ~= ${usd} USD}
)} diff --git a/common/components/TXMetaDataPanel/components/SchedulingFeeSummary.tsx b/common/components/TXMetaDataPanel/components/SchedulingFeeSummary.tsx index fb287a1f..e2ec5d66 100644 --- a/common/components/TXMetaDataPanel/components/SchedulingFeeSummary.tsx +++ b/common/components/TXMetaDataPanel/components/SchedulingFeeSummary.tsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import { AppState } from 'reducers'; import { getNetworkConfig, getOffline } from 'selectors/config'; import { getIsEstimating } from 'selectors/gas'; -import { getGasLimit, getTimeBounty } from 'selectors/transaction'; +import { getTimeBounty, getScheduleGasLimit } from 'selectors/transaction'; import { UnitDisplay, Spinner } from 'components/ui'; import { NetworkConfig } from 'types/network'; import './FeeSummary.scss'; @@ -14,13 +14,13 @@ import { gasPriceToBase } from 'libs/units'; interface RenderData { gasPriceWei: string; gasPriceGwei: string; - gasLimit: string; + scheduleGasLimit: string; fee: React.ReactElement; usd: React.ReactElement | null; } interface ReduxStateProps { - gasLimit: AppState['transaction']['fields']['gasLimit']; + scheduleGasLimit: AppState['transaction']['fields']['scheduleGasLimit']; rates: AppState['rates']['rates']; network: NetworkConfig; isOffline: AppState['config']['meta']['offline']; @@ -41,7 +41,7 @@ class SchedulingFeeSummary extends React.Component { public render() { const { gasPrice, - gasLimit, + scheduleGasLimit, rates, network, isOffline, @@ -60,10 +60,10 @@ class SchedulingFeeSummary extends React.Component { const feeBig = gasPrice.value && - gasLimit.value && + scheduleGasLimit.value && timeBounty.value && calcEACTotalCost( - gasLimit.value, + scheduleGasLimit.value, gasPrice.value, scheduleGasPrice.value || gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK), timeBounty.value @@ -99,7 +99,7 @@ class SchedulingFeeSummary extends React.Component { gasPriceGwei: gasPrice.raw, fee, usd, - gasLimit: gasLimit.raw + scheduleGasLimit: scheduleGasLimit.raw })} ); @@ -108,7 +108,7 @@ class SchedulingFeeSummary extends React.Component { function mapStateToProps(state: AppState): ReduxStateProps { return { - gasLimit: getGasLimit(state), + scheduleGasLimit: getScheduleGasLimit(state), rates: state.rates.rates, network: getNetworkConfig(state), isOffline: getOffline(state), diff --git a/common/containers/Tabs/ScheduleTransaction/components/Fields/ScheduleGasLimitField.tsx b/common/containers/Tabs/ScheduleTransaction/components/Fields/ScheduleGasLimitField.tsx new file mode 100644 index 00000000..7cba3e0f --- /dev/null +++ b/common/containers/Tabs/ScheduleTransaction/components/Fields/ScheduleGasLimitField.tsx @@ -0,0 +1,60 @@ +import { connect } from 'react-redux'; +import React from 'react'; +import { AppState } from 'reducers'; +import { setScheduleGasLimitField, TSetScheduleGasLimitField } from 'actions/transaction'; +import { translateRaw } from 'translations'; +import { Input } from 'components/ui'; +import { getScheduleGasLimit, isValidScheduleGasLimit } from 'selectors/transaction'; +import { Wei } from 'libs/units'; +import { EAC_SCHEDULING_CONFIG } from 'libs/scheduling'; + +interface OwnProps { + scheduleGasLimit: any; + validScheduleGasLimit: boolean; +} + +interface DispatchProps { + setScheduleGasLimitField: TSetScheduleGasLimitField; +} + +type Props = OwnProps & DispatchProps; + +class ScheduleGasLimitFieldClass extends React.Component { + public render() { + const { scheduleGasLimit, validScheduleGasLimit } = this.props; + + return ( +
+ +
+ ); + } + + private handleGasLimitChange = (ev: React.FormEvent) => { + const { value } = ev.currentTarget; + + this.props.setScheduleGasLimitField({ + raw: value, + value: Wei(value) + }); + }; +} + +export const ScheduleGasLimitField = connect( + (state: AppState) => ({ + scheduleGasLimit: getScheduleGasLimit(state), + validScheduleGasLimit: isValidScheduleGasLimit(state) + }), + { + setScheduleGasLimitField + } +)(ScheduleGasLimitFieldClass); diff --git a/common/containers/Tabs/SendTransaction/components/Fields/Fields.scss b/common/containers/Tabs/ScheduleTransaction/components/ScheduleFields.scss similarity index 100% rename from common/containers/Tabs/SendTransaction/components/Fields/Fields.scss rename to common/containers/Tabs/ScheduleTransaction/components/ScheduleFields.scss diff --git a/common/containers/Tabs/ScheduleTransaction/components/ScheduleFields.tsx b/common/containers/Tabs/ScheduleTransaction/components/ScheduleFields.tsx new file mode 100644 index 00000000..c6b71ae4 --- /dev/null +++ b/common/containers/Tabs/ScheduleTransaction/components/ScheduleFields.tsx @@ -0,0 +1,75 @@ +import { connect } from 'react-redux'; +import React from 'react'; +import { AppState } from 'reducers'; +import { getCurrentScheduleType, ICurrentScheduleType } from 'selectors/transaction'; +import { + WindowSizeField, + TimeBountyField, + WindowStartField, + ScheduleGasPriceField, + ScheduleGasLimitField +} from '.'; +import { ScheduleTimezoneDropDown, ScheduleTimestampField, ScheduleType } from 'components'; +import './ScheduleFields.scss'; + +interface Props { + schedulingType: ICurrentScheduleType; +} + +class ScheduleFieldsClass extends React.Component { + public render() { + const { schedulingType } = this.props; + + return ( +
+
Scheduled Transaction Settings
+
+ +
+
+ +
+ + {schedulingType.value === 'time' && ( + <> +
+ +
+
+ +
+ + )} + + {schedulingType.value === 'block' && ( + <> +
+ +
+ + )} + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ ); + } +} + +export const ScheduleFields = connect((state: AppState) => ({ + schedulingType: getCurrentScheduleType(state) +}))(ScheduleFieldsClass); diff --git a/common/containers/Tabs/ScheduleTransaction/components/index.ts b/common/containers/Tabs/ScheduleTransaction/components/index.ts index 07a08d84..50570991 100644 --- a/common/containers/Tabs/ScheduleTransaction/components/index.ts +++ b/common/containers/Tabs/ScheduleTransaction/components/index.ts @@ -3,3 +3,5 @@ export * from './Fields/TimeBounty/TimeBountyField'; export * from './Fields/WindowSize/WindowSizeField'; export * from './Fields/SchedulingToggle/SchedulingToggle'; export * from './Fields/ScheduleGasPriceField'; +export * from './Fields/ScheduleGasLimitField'; +export * from './ScheduleFields'; diff --git a/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/currentSchedulingToggle.ts b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/currentSchedulingToggle.ts new file mode 100644 index 00000000..30a552ca --- /dev/null +++ b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/currentSchedulingToggle.ts @@ -0,0 +1,27 @@ +import { setGasLimitField } from 'actions/transaction/actionCreators/fields'; +import { call, put, takeLatest } from 'redux-saga/effects'; +import { SagaIterator } from 'redux-saga'; +import { TypeKeys } from 'actions/transaction/constants'; +import { SetGasLimitFieldAction, SetSchedulingToggleAction } from 'actions/transaction'; +import { EAC_SCHEDULING_CONFIG } from 'libs/scheduling'; +import BN from 'bn.js'; + +export function* setGasLimitForScheduling({ + payload: { value: useScheduling } +}: SetSchedulingToggleAction): SagaIterator { + const gasLimit = useScheduling ? EAC_SCHEDULING_CONFIG.SCHEDULING_GAS_LIMIT : new BN('21000'); + + yield call(setGasLimit, { + raw: gasLimit.toString(), + value: gasLimit + }); +} + +export function* setGasLimit(payload: SetGasLimitFieldAction['payload']) { + yield put(setGasLimitField(payload)); +} + +export const currentSchedulingToggle = takeLatest( + [TypeKeys.SCHEDULING_TOGGLE_SET], + setGasLimitForScheduling +); diff --git a/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/index.ts b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/index.ts index c5b71d7a..a2ad1dc9 100644 --- a/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/index.ts +++ b/common/containers/Tabs/ScheduleTransaction/sagas/transaction/current/index.ts @@ -2,10 +2,12 @@ import { currentWindowSize } from './currentWindowSize'; import { currentWindowStart } from './currentWindowStart'; import { currentScheduleTimestamp } from './currentScheduleTimestamp'; import { currentTimeBounty } from './currentTimeBounty'; +import { currentSchedulingToggle } from './currentSchedulingToggle'; export const schedulingCurrentSagas = [ currentWindowSize, currentWindowStart, currentScheduleTimestamp, - currentTimeBounty + currentTimeBounty, + currentSchedulingToggle ]; diff --git a/common/containers/Tabs/SendTransaction/components/Fields/Fields.tsx b/common/containers/Tabs/SendTransaction/components/Fields/Fields.tsx index 7097fc01..a3a2b673 100644 --- a/common/containers/Tabs/SendTransaction/components/Fields/Fields.tsx +++ b/common/containers/Tabs/SendTransaction/components/Fields/Fields.tsx @@ -8,14 +8,8 @@ import { CurrentCustomMessage, GenerateTransaction, SendButton, - WindowStartField, - ScheduleTimestampField, - ScheduleTimezoneDropDown, - TimeBountyField, - ScheduleType, - WindowSizeField, SchedulingToggle, - ScheduleGasPriceField + ScheduleFields } from 'components'; import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs'; import translate from 'translations'; @@ -25,13 +19,7 @@ import { NonStandardTransaction } from './components'; import { getOffline, getNetworkConfig } from 'selectors/config'; import { SendScheduleTransactionButton } from 'containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton'; import { GenerateScheduleTransactionButton } from 'containers/Tabs/ScheduleTransaction/components/GenerateScheduleTransactionButton'; -import { - getCurrentScheduleType, - ICurrentScheduleType, - getCurrentSchedulingToggle, - ICurrentSchedulingToggle -} from 'selectors/transaction'; -import './Fields.scss'; +import { getCurrentSchedulingToggle, ICurrentSchedulingToggle } from 'selectors/transaction'; const QueryWarning: React.SFC<{}> = () => ( { public render() { - const { shouldDisplay, schedulingAvailable, useScheduling, schedulingType } = this.props; + const { shouldDisplay, schedulingAvailable, useScheduling } = this.props; return ( { )} - {useScheduling && ( -
-
- Scheduled Transaction Settings -
-
- -
-
- -
- - {schedulingType.value === 'time' && ( - <> -
- -
-
- -
- - )} - - {schedulingType.value === 'block' && ( - <> -
- -
- - )} - -
- -
-
- -
-
- -
-
- -
-
-
- )} + {useScheduling && }
@@ -162,6 +104,5 @@ export const Fields = connect((state: AppState) => ({ schedulingAvailable: getNetworkConfig(state).name === 'Kovan', shouldDisplay: !isAnyOfflineWithWeb3(state), offline: getOffline(state), - schedulingType: getCurrentScheduleType(state), useScheduling: getCurrentSchedulingToggle(state).value }))(FieldsClass); diff --git a/common/libs/scheduling.ts b/common/libs/scheduling.ts index 1eb6f0ac..5cb49e17 100644 --- a/common/libs/scheduling.ts +++ b/common/libs/scheduling.ts @@ -6,6 +6,7 @@ const TIME_BOUNTY_MIN = new BN('1'); export const EAC_SCHEDULING_CONFIG = { DAPP_ADDRESS: 'https://app.chronologic.network', + SCHEDULE_GAS_LIMIT_FALLBACK: new BN('21000'), SCHEDULE_GAS_PRICE_FALLBACK: 20, // Gwei FEE: new BN('2242000000000000'), // $2 FEE_MULTIPLIER: new BN('2'), @@ -61,7 +62,7 @@ export const calcEACTotalCost = ( export const getScheduleData = ( toAddress: string, callData = '', - callGas: number, + callGas: BN | null, callValue: BN | null, windowSize: number | null, windowStart: any, @@ -71,12 +72,14 @@ export const getScheduleData = ( ) => { if ( !callValue || + !callGas || !callGasPrice || !windowStart || !windowSize || !timeBounty || timeBounty.lt(new BN(0)) || - callGasPrice.lt(new BN(0)) + callGasPrice.lt(new BN(0)) || + windowSize < 0 ) { return; } diff --git a/common/reducers/transaction/fields/fields.ts b/common/reducers/transaction/fields/fields.ts index 65debf23..fdd83b3d 100644 --- a/common/reducers/transaction/fields/fields.ts +++ b/common/reducers/transaction/fields/fields.ts @@ -33,6 +33,10 @@ const INITIAL_STATE: State = { raw: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD, value: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD }, + scheduleGasLimit: { + raw: EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_LIMIT_FALLBACK.toString(), + value: EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_LIMIT_FALLBACK + }, scheduleGasPrice: { raw: EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK.toString(), value: gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK) @@ -98,6 +102,8 @@ export const fields = ( return updateField('scheduleType')(state, action); case TK.SCHEDULING_TOGGLE_SET: return updateField('schedulingToggle')(state, action); + case TK.SCHEDULE_GAS_LIMIT_FIELD_SET: + return updateField('scheduleGasLimit')(state, action); case TK.SCHEDULE_GAS_PRICE_FIELD_SET: return updateField('scheduleGasPrice')(state, action); case TK.TOKEN_TO_ETHER_SWAP: diff --git a/common/reducers/transaction/fields/typings.ts b/common/reducers/transaction/fields/typings.ts index da5c3ef8..a3d5da97 100644 --- a/common/reducers/transaction/fields/typings.ts +++ b/common/reducers/transaction/fields/typings.ts @@ -8,7 +8,8 @@ import { SetScheduleTimestampFieldAction, SetScheduleTypeAction, SetSchedulingToggleAction, - SetScheduleGasPriceFieldAction + SetScheduleGasPriceFieldAction, + SetScheduleGasLimitFieldAction } from 'actions/transaction'; import { Wei } from 'libs/units'; @@ -25,5 +26,6 @@ export interface State { windowStart: SetWindowStartFieldAction['payload']; scheduleTimestamp: SetScheduleTimestampFieldAction['payload']; scheduleType: SetScheduleTypeAction['payload']; + scheduleGasLimit: SetScheduleGasLimitFieldAction['payload']; scheduleGasPrice: SetScheduleGasPriceFieldAction['payload']; } diff --git a/common/selectors/transaction/current.ts b/common/selectors/transaction/current.ts index 0bf8140f..0929e87b 100644 --- a/common/selectors/transaction/current.ts +++ b/common/selectors/transaction/current.ts @@ -3,7 +3,12 @@ import { getUnit, getTokenTo, getTokenValue } from './meta'; import { AppState } from 'reducers'; import { TokenValue, Wei, Address } from 'libs/units'; import { gasPriceValidator, gasLimitValidator } from 'libs/validators'; -import { getDataExists, getGasPrice, getGasLimit } from 'selectors/transaction'; +import { + getDataExists, + getGasPrice, + getGasLimit, + getScheduleGasLimit +} from 'selectors/transaction'; import { isNetworkUnit } from 'selectors/config'; import { getAddressMessage, AddressMessage } from 'config'; @@ -47,6 +52,9 @@ const isValidGasLimit = (state: AppState): boolean => gasLimitValidator(getGasLi const isValidScheduleGasPrice = (state: AppState): boolean => gasPriceValidator(getScheduleGasPrice(state).raw); +const isValidScheduleGasLimit = (state: AppState): boolean => + gasLimitValidator(getScheduleGasLimit(state).raw); + function getCurrentToAddressMessage(state: AppState): AddressMessage | undefined { const to = getCurrentTo(state); return getAddressMessage(to.raw); @@ -61,6 +69,7 @@ export { isValidCurrentTo, isValidGasPrice, isValidGasLimit, + isValidScheduleGasLimit, isValidScheduleGasPrice, getCurrentToAddressMessage }; diff --git a/common/selectors/transaction/fields.ts b/common/selectors/transaction/fields.ts index 2e65aa42..8846c918 100644 --- a/common/selectors/transaction/fields.ts +++ b/common/selectors/transaction/fields.ts @@ -16,6 +16,7 @@ const getWindowStart = (state: AppState) => getFields(state).windowStart; const getScheduleTimestamp = (state: AppState) => getFields(state).scheduleTimestamp; const getScheduleType = (state: AppState) => getFields(state).scheduleType; const getSchedulingToggle = (state: AppState) => getFields(state).schedulingToggle; +const getScheduleGasLimit = (state: AppState) => getFields(state).scheduleGasLimit; const getScheduleGasPrice = (state: AppState) => getFields(state).scheduleGasPrice; const getDataExists = (state: AppState) => { @@ -49,5 +50,6 @@ export { getScheduleTimestamp, getScheduleType, getSchedulingToggle, + getScheduleGasLimit, getScheduleGasPrice }; diff --git a/common/selectors/transaction/transaction.ts b/common/selectors/transaction/transaction.ts index b95ebd00..6ccca338 100644 --- a/common/selectors/transaction/transaction.ts +++ b/common/selectors/transaction/transaction.ts @@ -27,7 +27,9 @@ import { getValidGasCost, isEtherTransaction, getScheduleGasPrice, - isValidScheduleGasPrice + isValidScheduleGasPrice, + isValidScheduleGasLimit, + getScheduleGasLimit } from 'selectors/transaction'; import { Wei, Address, gasPriceToBase } from 'libs/units'; import { getTransactionFields } from 'libs/transaction/utils/ether'; @@ -80,7 +82,6 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => { const scheduleType = getScheduleType(state); const windowStart = getWindowStart(state); const windowSize = getWindowSize(state); - const gasLimit = getGasLimit(state); const nonce = getNonce(state); const gasPrice = getGasPrice(state); const timeBounty = getTimeBounty(state); @@ -89,17 +90,20 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => { const scheduleTimestampValid = isScheduleTimestampValid(transactionFields); const scheduleGasPrice = getScheduleGasPrice(state); const scheduleGasPriceValid = isValidScheduleGasPrice(state); + const scheduleGasLimit = getScheduleGasLimit(state); + const scheduleGasLimitValid = isValidScheduleGasLimit(state); const isFullTransaction = isFullTx(state, transactionFields, currentTo, currentValue, dataExists, validGasCost, unit) && (windowStartValid || scheduleTimestampValid) && windowSizeValid && - scheduleGasPriceValid; + scheduleGasPriceValid && + scheduleGasLimitValid; const transactionData = getScheduleData( currentTo.raw, callData.raw, - parseInt(gasLimit.raw, 10), + scheduleGasLimit.value, currentValue.value, windowSize.value, windowStart.value, @@ -109,7 +113,7 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => { ); const endowment = calcEACEndowment( - gasLimit.value || new BN(21000), + scheduleGasLimit.value || EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_LIMIT_FALLBACK, currentValue.value || new BN(0), scheduleGasPrice.value || gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK), timeBounty.value diff --git a/spec/reducers/transaction/fields/fields.spec.ts b/spec/reducers/transaction/fields/fields.spec.ts index 80b0aced..dd4c5952 100644 --- a/spec/reducers/transaction/fields/fields.spec.ts +++ b/spec/reducers/transaction/fields/fields.spec.ts @@ -28,7 +28,8 @@ describe('fields reducer', () => { scheduleGasPrice: { raw: EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK.toString(), value: gasPriceToBase(EAC_SCHEDULING_CONFIG.SCHEDULE_GAS_PRICE_FALLBACK) - } + }, + scheduleGasLimit: { raw: '21000', value: new BN(21000) } }; const testPayload = { raw: 'test', value: null }; diff --git a/spec/selectors/transaction/fields.spec.ts b/spec/selectors/transaction/fields.spec.ts index 9d0e3104..d3815dbd 100644 --- a/spec/selectors/transaction/fields.spec.ts +++ b/spec/selectors/transaction/fields.spec.ts @@ -67,6 +67,10 @@ describe('fields selector', () => { scheduleGasPrice: { raw: '1500', value: Wei('1500') + }, + scheduleGasLimit: { + raw: '21000', + value: Wei('21000') } }; diff --git a/spec/selectors/transaction/helpers.spec.ts b/spec/selectors/transaction/helpers.spec.ts index 72cfced1..c9425c00 100644 --- a/spec/selectors/transaction/helpers.spec.ts +++ b/spec/selectors/transaction/helpers.spec.ts @@ -71,6 +71,10 @@ describe('helpers selector', () => { scheduleGasPrice: { raw: '1500', value: Wei('1500') + }, + scheduleGasLimit: { + raw: '21000', + value: Wei('21000') } } }; @@ -89,7 +93,8 @@ describe('helpers selector', () => { windowStart: null, scheduleTimestamp: null, scheduleType: 'time', - scheduleGasPrice: Wei('1500') + scheduleGasPrice: Wei('1500'), + scheduleGasLimit: Wei('21000') }; expect(reduceToValues(state.transaction.fields)).toEqual(values); });