From 63d68aaeefd207ef88c71fcbf384a132181c08c9 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 23 Dec 2016 16:47:50 +0400 Subject: [PATCH 01/43] Update deb-build.sh Add Depends: libssl --- scripts/deb-build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/deb-build.sh b/scripts/deb-build.sh index 9754f1b05bf..dd5b9ab2903 100644 --- a/scripts/deb-build.sh +++ b/scripts/deb-build.sh @@ -25,6 +25,7 @@ echo "Homepage: https://ethcore.io" >> $control echo "Vcs-Git: git://github.com/ethcore/parity.git" >> $control echo "Vcs-Browser: https://github.com/ethcore/parity" >> $control echo "Architecture: $1" >> $control +echo "Depends: libssl" >> $control echo "Description: Ethereum network client by Ethcore" >> $control #build .deb package From e006af1edda118ceb196a4a398adcf32f7c11625 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 23 Dec 2016 15:13:43 +0100 Subject: [PATCH 02/43] Fix default import (#3960) --- js/src/ui/IdentityIcon/identityIcon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/ui/IdentityIcon/identityIcon.js b/js/src/ui/IdentityIcon/identityIcon.js index 565c47a8486..25fd7d1545a 100644 --- a/js/src/ui/IdentityIcon/identityIcon.js +++ b/js/src/ui/IdentityIcon/identityIcon.js @@ -20,7 +20,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { createIdentityImg } from '~/api/util/identity'; -import ContractIcon from '../Icons'; +import { ContractIcon } from '../Icons'; import styles from './identityIcon.css'; From 74efb2223052e9ee79399979482b9692fe40b960 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 23 Dec 2016 15:24:03 +0100 Subject: [PATCH 03/43] Allow empty address (#3961) --- js/src/ui/IdentityName/identityName.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/ui/IdentityName/identityName.js b/js/src/ui/IdentityName/identityName.js index 85116425ed5..47c190f4404 100644 --- a/js/src/ui/IdentityName/identityName.js +++ b/js/src/ui/IdentityName/identityName.js @@ -43,7 +43,7 @@ class IdentityName extends Component { return null; } - const nullName = new BigNumber(address).eq(0) ? 'null' : null; + const nullName = new BigNumber(address || 0).eq(0) ? 'null' : null; const addressFallback = nullName || (shorten ? () : address); const fallback = unknown ? defaultName : addressFallback; const isUuid = account && account.name === account.uuid; From fc620d0d3ecec4853168a54b43d697eca38b9937 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 23 Dec 2016 15:31:19 +0100 Subject: [PATCH 04/43] Allow setting of minBlock on sending (#3921) * minBlock value formatting * Allow Contract execute to specify minBock * Transfer allows minBlock * Cleanups * Check errors, verify via testing * Display Submitted/Submission block in MethodDecoding --- js/src/api/format/input.js | 4 + js/src/api/format/input.spec.js | 6 +- js/src/api/format/output.js | 4 + js/src/api/format/output.spec.js | 6 +- .../AdvancedStep/advancedStep.js | 57 ++++++ .../ExecuteContract/AdvancedStep/index.js | 17 ++ .../DetailsStep/detailsStep.js | 68 +++++-- .../ExecuteContract/executeContract.css | 19 +- .../modals/ExecuteContract/executeContract.js | 171 +++++++++++++----- js/src/modals/Transfer/Extras/extras.js | 63 +++++-- js/src/modals/Transfer/store.js | 23 ++- js/src/modals/Transfer/transfer.css | 71 ++++---- js/src/modals/Transfer/transfer.js | 28 ++- js/src/ui/Form/AddressSelect/addressSelect.js | 66 ++++--- js/src/ui/Form/AutoComplete/autocomplete.js | 25 +-- js/src/ui/MethodDecoding/methodDecoding.js | 14 ++ 16 files changed, 459 insertions(+), 183 deletions(-) create mode 100644 js/src/modals/ExecuteContract/AdvancedStep/advancedStep.js create mode 100644 js/src/modals/ExecuteContract/AdvancedStep/index.js diff --git a/js/src/api/format/input.js b/js/src/api/format/input.js index 4cbcbdce442..4307fc91204 100644 --- a/js/src/api/format/input.js +++ b/js/src/api/format/input.js @@ -137,6 +137,10 @@ export function inOptions (options) { options[key] = inNumber16((new BigNumber(options[key])).round()); break; + case 'minBlock': + options[key] = options[key] ? inNumber16(options[key]) : null; + break; + case 'value': case 'nonce': options[key] = inNumber16(options[key]); diff --git a/js/src/api/format/input.spec.js b/js/src/api/format/input.spec.js index 27d200b938f..699ac93c2b9 100644 --- a/js/src/api/format/input.spec.js +++ b/js/src/api/format/input.spec.js @@ -204,7 +204,7 @@ describe('api/format/input', () => { }); }); - ['gas', 'gasPrice', 'value', 'nonce'].forEach((input) => { + ['gas', 'gasPrice', 'value', 'minBlock', 'nonce'].forEach((input) => { it(`formats ${input} number as hexnumber`, () => { const block = {}; block[input] = 0x123; @@ -214,6 +214,10 @@ describe('api/format/input', () => { }); }); + it('passes minBlock as null when specified as such', () => { + expect(inOptions({ minBlock: null })).to.deep.equal({ minBlock: null }); + }); + it('ignores and passes through unknown keys', () => { expect(inOptions({ someRandom: 'someRandom' })).to.deep.equal({ someRandom: 'someRandom' }); }); diff --git a/js/src/api/format/output.js b/js/src/api/format/output.js index e1887582a04..73e2f72209d 100644 --- a/js/src/api/format/output.js +++ b/js/src/api/format/output.js @@ -205,6 +205,10 @@ export function outTransaction (tx) { tx[key] = outNumber(tx[key]); break; + case 'minBlock': + tx[key] = tx[key] ? outNumber(tx[key]) : null; + break; + case 'creates': case 'from': case 'to': diff --git a/js/src/api/format/output.spec.js b/js/src/api/format/output.spec.js index ce50c69c18f..3fa2f218da4 100644 --- a/js/src/api/format/output.spec.js +++ b/js/src/api/format/output.spec.js @@ -283,7 +283,7 @@ describe('api/format/output', () => { }); }); - ['blockNumber', 'gasPrice', 'gas', 'nonce', 'transactionIndex', 'value'].forEach((input) => { + ['blockNumber', 'gasPrice', 'gas', 'minBlock', 'nonce', 'transactionIndex', 'value'].forEach((input) => { it(`formats ${input} number as hexnumber`, () => { const block = {}; block[input] = 0x123; @@ -294,6 +294,10 @@ describe('api/format/output', () => { }); }); + it('passes minBlock as null when null', () => { + expect(outTransaction({ minBlock: null })).to.deep.equal({ minBlock: null }); + }); + it('ignores and passes through unknown keys', () => { expect(outTransaction({ someRandom: 'someRandom' })).to.deep.equal({ someRandom: 'someRandom' }); }); diff --git a/js/src/modals/ExecuteContract/AdvancedStep/advancedStep.js b/js/src/modals/ExecuteContract/AdvancedStep/advancedStep.js new file mode 100644 index 00000000000..4142aa96156 --- /dev/null +++ b/js/src/modals/ExecuteContract/AdvancedStep/advancedStep.js @@ -0,0 +1,57 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import React, { Component, PropTypes } from 'react'; +import { FormattedMessage } from 'react-intl'; + +import { Input, GasPriceEditor } from '~/ui'; + +import styles from '../executeContract.css'; + +export default class AdvancedStep extends Component { + static propTypes = { + gasStore: PropTypes.object.isRequired, + minBlock: PropTypes.string, + minBlockError: PropTypes.string, + onMinBlockChange: PropTypes.func + }; + + render () { + const { gasStore, minBlock, minBlockError, onMinBlockChange } = this.props; + + return ( +
+ + } + label={ + + } + value={ minBlock } + onSubmit={ onMinBlockChange } /> +
+ +
+
+ ); + } +} diff --git a/js/src/modals/ExecuteContract/AdvancedStep/index.js b/js/src/modals/ExecuteContract/AdvancedStep/index.js new file mode 100644 index 00000000000..3a4cc1028cb --- /dev/null +++ b/js/src/modals/ExecuteContract/AdvancedStep/index.js @@ -0,0 +1,17 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default from './advancedStep'; diff --git a/js/src/modals/ExecuteContract/DetailsStep/detailsStep.js b/js/src/modals/ExecuteContract/DetailsStep/detailsStep.js index e2d18bf650f..818f216f63a 100644 --- a/js/src/modals/ExecuteContract/DetailsStep/detailsStep.js +++ b/js/src/modals/ExecuteContract/DetailsStep/detailsStep.js @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import React, { Component, PropTypes } from 'react'; import { Checkbox, MenuItem } from 'material-ui'; +import React, { Component, PropTypes } from 'react'; +import { FormattedMessage } from 'react-intl'; import { AddressSelect, Form, Input, Select, TypedInput } from '~/ui'; @@ -29,29 +30,28 @@ const CHECK_STYLE = { export default class DetailsStep extends Component { static propTypes = { + advancedOptions: PropTypes.bool, accounts: PropTypes.object.isRequired, - contract: PropTypes.object.isRequired, - onAmountChange: PropTypes.func.isRequired, - onFromAddressChange: PropTypes.func.isRequired, - onValueChange: PropTypes.func.isRequired, - values: PropTypes.array.isRequired, - valuesError: PropTypes.array.isRequired, - amount: PropTypes.string, amountError: PropTypes.string, balances: PropTypes.object, + contract: PropTypes.object.isRequired, fromAddress: PropTypes.string, fromAddressError: PropTypes.string, func: PropTypes.object, funcError: PropTypes.string, - gasEdit: PropTypes.bool, + onAdvancedClick: PropTypes.func, + onAmountChange: PropTypes.func.isRequired, + onFromAddressChange: PropTypes.func.isRequired, onFuncChange: PropTypes.func, - onGasEditClick: PropTypes.func, + onValueChange: PropTypes.func.isRequired, + values: PropTypes.array.isRequired, + valuesError: PropTypes.array.isRequired, warning: PropTypes.string } render () { - const { accounts, amount, amountError, balances, fromAddress, fromAddressError, gasEdit, onGasEditClick, onFromAddressChange, onAmountChange } = this.props; + const { accounts, advancedOptions, amount, amountError, balances, fromAddress, fromAddressError, onAdvancedClick, onAmountChange, onFromAddressChange } = this.props; return (
@@ -60,8 +60,16 @@ export default class DetailsStep extends Component { accounts={ accounts } balances={ balances } error={ fromAddressError } - hint='the account to transact with' - label='from account' + hint={ + + } + label={ + + } onChange={ onFromAddressChange } value={ fromAddress } /> { this.renderFunctionSelect() } @@ -70,16 +78,28 @@ export default class DetailsStep extends Component {
+ } + label={ + + } onSubmit={ onAmountChange } value={ amount } />
+ } + onCheck={ onAdvancedClick } style={ CHECK_STYLE } />
@@ -129,9 +149,17 @@ export default class DetailsStep extends Component { return ( + } + label={ + + } + value={ minBlock } + onChange={ this.onEditMinBlock } /> +
+ +
); } @@ -50,18 +71,28 @@ export default class Extras extends Component { } return ( -
- -
+ + } + label={ + + } + onChange={ this.onEditData } + value={ data } /> ); } onEditData = (event) => { this.props.onChange('data', event.target.value); } + + onEditMinBlock = (event) => { + this.props.onChange('minBlock', event.target.value); + } } diff --git a/js/src/modals/Transfer/store.js b/js/src/modals/Transfer/store.js index 679e03609c3..c65a25fab75 100644 --- a/js/src/modals/Transfer/store.js +++ b/js/src/modals/Transfer/store.js @@ -49,6 +49,9 @@ export default class TransferStore { @observable data = ''; @observable dataError = null; + @observable minBlock = '0'; + @observable minBlockError = null; + @observable recipient = ''; @observable recipientError = ERRORS.requireRecipient; @@ -84,7 +87,7 @@ export default class TransferStore { @computed get isValid () { const detailsValid = !this.recipientError && !this.valueError && !this.totalError && !this.senderError; - const extrasValid = !this.gasStore.errorGas && !this.gasStore.errorPrice && !this.totalError; + const extrasValid = !this.gasStore.errorGas && !this.gasStore.errorPrice && !this.minBlockError && !this.totalError; const verifyValid = !this.passwordError; switch (this.stage) { @@ -92,7 +95,9 @@ export default class TransferStore { return detailsValid; case 1: - return this.extras ? extrasValid : verifyValid; + return this.extras + ? extrasValid + : verifyValid; case 2: return verifyValid; @@ -155,6 +160,9 @@ export default class TransferStore { case 'gasPrice': return this._onUpdateGasPrice(value); + case 'minBlock': + return this._onUpdateMinBlock(value); + case 'recipient': return this._onUpdateRecipient(value); @@ -254,6 +262,14 @@ export default class TransferStore { this.recalculate(); } + @action _onUpdateMinBlock = (minBlock) => { + console.log('minBlock', minBlock); + transaction(() => { + this.minBlock = minBlock; + this.minBlockError = this._validatePositiveNumber(minBlock); + }); + } + @action _onUpdateGasPrice = (gasPrice) => { this.recalculate(); } @@ -412,6 +428,9 @@ export default class TransferStore { send () { const { options, values } = this._getTransferParams(); + + options.minBlock = new BigNumber(this.minBlock || 0).gt(0) ? this.minBlock : null; + return this._getTransferMethod().postTransaction(options, values); } diff --git a/js/src/modals/Transfer/transfer.css b/js/src/modals/Transfer/transfer.css index 6e3ae9aa210..4c6b2df825e 100644 --- a/js/src/modals/Transfer/transfer.css +++ b/js/src/modals/Transfer/transfer.css @@ -15,65 +15,68 @@ /* along with Parity. If not, see . */ -.info { - line-height: 1.618em; - width: 100%; -} - .columns { display: flex; - flex-wrap: wrap; position: relative; + flex-wrap: wrap; + + &>div { + flex: 0 1 50%; + position: relative; + width: 50%; + } +} + +.gaseditor { + margin-top: 1em; +} + +.info { + line-height: 1.618em; + width: 100%; } .row { display: flex; - flex-wrap: wrap; - position: relative; flex-direction: column; -} - -.columns>div { - flex: 0 1 50%; - width: 50%; + flex-wrap: wrap; position: relative; } .floatbutton { - text-align: right; float: right; margin-left: -100%; margin-top: 28px; -} - -.floatbutton>div { - margin-right: 0.5em; -} + text-align: right; -.tokenSelect { + &>div { + margin-right: 0.5em; + } } .token { height: 32px; padding: 4px 0; -} -.tokenSelect .token { - margin-top: 10px; -} + img { + height: 32px; + width: 32px; + margin: 0 16px 0 0; + z-index: 10; + } -.token img { - height: 32px; - width: 32px; - margin: 0 16px 0 0; - z-index: 10; + div { + height: 32px; + line-height: 32px; + display: inline-block; + vertical-align: top; + } } -.token div { - height: 32px; - line-height: 32px; - display: inline-block; - vertical-align: top; +.tokenSelect { + .token { + margin-top: 10px; + } } .tokenbalance { diff --git a/js/src/modals/Transfer/transfer.js b/js/src/modals/Transfer/transfer.js index 19c337e5a84..bbeb3fadbe7 100644 --- a/js/src/modals/Transfer/transfer.js +++ b/js/src/modals/Transfer/transfer.js @@ -20,13 +20,9 @@ import { bindActionCreators } from 'redux'; import { observer } from 'mobx-react'; import { pick } from 'lodash'; -import ActionDoneAll from 'material-ui/svg-icons/action/done-all'; -import ContentClear from 'material-ui/svg-icons/content/clear'; -import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back'; -import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward'; - -import { newError } from '~/ui/Errors/actions'; import { BusyStep, CompletedStep, Button, IdentityIcon, Modal, TxHash, Input } from '~/ui'; +import { newError } from '~/ui/Errors/actions'; +import { CancelIcon, DoneIcon, NextIcon, PrevIcon } from '~/ui/Icons'; import { nullableProptype } from '~/util/proptypes'; import Details from './Details'; @@ -188,17 +184,19 @@ class Transfer extends Component { return null; } - const { isEth, data, dataError, total, totalError } = this.store; + const { isEth, data, dataError, minBlock, minBlockError, total, totalError } = this.store; return ( + isEth={ isEth } + minBlock={ minBlock } + minBlockError={ minBlockError } + onChange={ this.store.onUpdateDetails } + total={ total } + totalError={ totalError } /> ); } @@ -208,20 +206,20 @@ class Transfer extends Component { const cancelBtn = (