Merge remote-tracking branch 'origin/master' into check-updates
This commit is contained in:
commit
bf9ed2d444
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1265,7 +1265,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "parity-ui-precompiled"
|
||||
version = "1.4.0"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git#587684374a12bf715151dd987a552a3d61e42972"
|
||||
source = "git+https://github.com/ethcore/js-precompiled.git#f46188126257e03c775e76a3cea82b5f70549400"
|
||||
dependencies = [
|
||||
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -21,8 +21,8 @@
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"generic": {
|
||||
"fields": 1,
|
||||
"rlp": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
|
||||
"fields": 2,
|
||||
"rlp": "0x200"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
|
@ -11,9 +11,9 @@
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
|
||||
"generic": {
|
||||
"fields": 0,
|
||||
"rlp": "0x0"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
|
@ -254,8 +254,8 @@ impl Engine for AuthorityRound {
|
||||
|
||||
/// Check if the signature belongs to the correct proposer.
|
||||
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||
let header_step = try!(header_step(header));
|
||||
// Give one step slack if step is lagging, double vote is still not possible.
|
||||
let header_step = try!(header_step(header));
|
||||
// Give one step slack if step is lagging, double vote is still not possible.
|
||||
if header_step <= self.step() + 1 {
|
||||
let proposer_signature = try!(header_signature(header));
|
||||
let ok_sig = try!(verify_address(self.step_proposer(header_step), &proposer_signature, &header.bare_hash()));
|
||||
@ -417,13 +417,13 @@ mod tests {
|
||||
let engine = Spec::new_test_round().engine;
|
||||
|
||||
let signature = tap.sign(addr, Some("0".into()), header.bare_hash()).unwrap();
|
||||
let mut step = UNIX_EPOCH.elapsed().unwrap().as_secs();
|
||||
let time = UNIX_EPOCH.elapsed().unwrap().as_secs();
|
||||
// Two authorities.
|
||||
let mut step = time - time % 2;
|
||||
header.set_seal(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||
let first_ok = engine.verify_block_seal(&header).is_ok();
|
||||
assert!(engine.verify_block_seal(&header).is_err());
|
||||
step = step + 1;
|
||||
header.set_seal(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
|
||||
let second_ok = engine.verify_block_seal(&header).is_ok();
|
||||
|
||||
assert!(first_ok ^ second_ok);
|
||||
assert!(engine.verify_block_seal(&header).is_ok());
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "parity.js",
|
||||
"version": "0.2.58",
|
||||
"version": "0.2.61",
|
||||
"main": "release/index.js",
|
||||
"jsnext:main": "src/index.js",
|
||||
"author": "Parity Team <admin@parity.io>",
|
||||
|
@ -14,9 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { stringify } from 'querystring';
|
||||
import React from 'react';
|
||||
|
||||
export default (
|
||||
export const termsOfService = (
|
||||
<ul>
|
||||
<li>This privacy notice relates to your use of the Parity SMS verification service. We take your privacy seriously and deal in an honest, direct and transparent way when it comes to your data.</li>
|
||||
<li>We collect your phone number when you use this service. This is temporarily kept in memory, and then encrypted and stored in our EU servers. We only retain the cryptographic hash of the number to prevent duplicated accounts. You consent to this use.</li>
|
||||
@ -25,3 +26,18 @@ export default (
|
||||
<li><i>Parity Technology Limited</i> is registered in England and Wales under company number <code>09760015</code> and complies with the Data Protection Act 1998 (UK). You may contact us via email at <a href={ 'mailto:admin@parity.io' }>admin@parity.io</a>. Our general privacy policy can be found here: <a href={ 'https://ethcore.io/legal.html' }>https://ethcore.io/legal.html</a>.</li>
|
||||
</ul>
|
||||
);
|
||||
|
||||
export const postToServer = (query) => {
|
||||
query = stringify(query);
|
||||
return fetch('https://sms-verification.parity.io/?' + query, {
|
||||
method: 'POST', mode: 'cors', cache: 'no-store'
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json().then((data) => {
|
||||
if (res.ok) {
|
||||
return data.message;
|
||||
}
|
||||
throw new Error(data.message || 'unknown error');
|
||||
});
|
||||
});
|
||||
};
|
@ -14,8 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { stringify } from 'querystring';
|
||||
|
||||
export const checkIfVerified = (contract, account) => {
|
||||
return contract.instance.certified.call({}, [account]);
|
||||
};
|
||||
@ -35,18 +33,3 @@ export const checkIfRequested = (contract, account) => {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const postToServer = (query) => {
|
||||
query = stringify(query);
|
||||
return fetch('https://sms-verification.parity.io/?' + query, {
|
||||
method: 'POST', mode: 'cors', cache: 'no-store'
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json().then((data) => {
|
||||
if (res.ok) {
|
||||
return data.message;
|
||||
}
|
||||
throw new Error(data.message || 'unknown error');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ export default class Lookup extends Component {
|
||||
label='Lookup'
|
||||
primary
|
||||
icon={ <SearchIcon /> }
|
||||
onClick={ this.onLookupClick }
|
||||
onTouchTap={ this.onLookupClick }
|
||||
/>
|
||||
</div>
|
||||
<CardText>{ output }</CardText>
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { sha3 } from '../parity.js';
|
||||
import { sha3, api } from '../parity.js';
|
||||
|
||||
const alreadyQueued = (queue, action, name) =>
|
||||
!!queue.find((entry) => entry.action === action && entry.name === name);
|
||||
@ -43,14 +43,23 @@ export const reserve = (name) => (dispatch, getState) => {
|
||||
const values = [ sha3(name) ];
|
||||
|
||||
dispatch(reserveStart(name));
|
||||
|
||||
reserve.estimateGas(options, values)
|
||||
.then((gas) => {
|
||||
options.gas = gas.mul(1.2).toFixed(0);
|
||||
return reserve.postTransaction(options, values);
|
||||
})
|
||||
.then((data) => {
|
||||
.then((requestId) => {
|
||||
return api.pollMethod('parity_checkRequest', requestId);
|
||||
})
|
||||
.then((txhash) => {
|
||||
dispatch(reserveSuccess(name));
|
||||
}).catch((err) => {
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err && err.type === 'REQUEST_REJECTED') {
|
||||
return dispatch(reserveFail(name));
|
||||
}
|
||||
|
||||
console.error(`could not reserve ${name}`);
|
||||
if (err) console.error(err.stack);
|
||||
dispatch(reserveFail(name));
|
||||
@ -81,9 +90,17 @@ export const drop = (name) => (dispatch, getState) => {
|
||||
options.gas = gas.mul(1.2).toFixed(0);
|
||||
return drop.postTransaction(options, values);
|
||||
})
|
||||
.then((data) => {
|
||||
.then((requestId) => {
|
||||
return api.pollMethod('parity_checkRequest', requestId);
|
||||
})
|
||||
.then((txhash) => {
|
||||
dispatch(dropSuccess(name));
|
||||
}).catch((err) => {
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err && err.type === 'REQUEST_REJECTED') {
|
||||
dispatch(reserveFail(name));
|
||||
}
|
||||
|
||||
console.error(`could not drop ${name}`);
|
||||
if (err) console.error(err.stack);
|
||||
dispatch(reserveFail(name));
|
||||
|
@ -86,6 +86,22 @@ export default class Names extends Component {
|
||||
name: ''
|
||||
};
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const nextQueue = nextProps.queue;
|
||||
const prevQueue = this.props.queue;
|
||||
|
||||
if (nextQueue.length > prevQueue.length) {
|
||||
const newQueued = nextQueue[nextQueue.length - 1];
|
||||
const newName = newQueued.name;
|
||||
|
||||
if (newName !== this.state.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ name: '' });
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { action, name } = this.state;
|
||||
const { fee, pending, queue } = this.props;
|
||||
@ -120,7 +136,7 @@ export default class Names extends Component {
|
||||
label={ action === 'reserve' ? 'Reserve' : 'Drop' }
|
||||
primary
|
||||
icon={ <CheckIcon /> }
|
||||
onClick={ this.onSubmitClick }
|
||||
onTouchTap={ this.onSubmitClick }
|
||||
/>
|
||||
{ queue.length > 0
|
||||
? (<div>{ useSignerText }{ renderQueue(queue) }</div>)
|
||||
|
@ -52,7 +52,7 @@ export default class Records extends Component {
|
||||
label='Save'
|
||||
primary
|
||||
icon={ <SaveIcon /> }
|
||||
onClick={ this.onSaveClick }
|
||||
onTouchTap={ this.onSaveClick }
|
||||
/>
|
||||
</CardText>
|
||||
</Card>
|
||||
|
@ -174,7 +174,7 @@ export default class LoadContract extends Component {
|
||||
const secondaryText = description || `Saved ${moment(timestamp).fromNow()}`;
|
||||
const remove = removable
|
||||
? (
|
||||
<IconButton onClick={ onDelete }>
|
||||
<IconButton onTouchTap={ onDelete }>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
)
|
||||
|
@ -25,7 +25,7 @@ import ErrorIcon from 'material-ui/svg-icons/navigation/close';
|
||||
import { fromWei } from '../../../api/util/wei';
|
||||
import { Form, Input } from '../../../ui';
|
||||
|
||||
import terms from '../terms-of-service';
|
||||
import { termsOfService } from '../../../3rdparty/sms-verification';
|
||||
import styles from './gatherData.css';
|
||||
|
||||
export default class GatherData extends Component {
|
||||
@ -66,7 +66,7 @@ export default class GatherData extends Component {
|
||||
disabled={ isVerified }
|
||||
onCheck={ this.consentOnChange }
|
||||
/>
|
||||
<div className={ styles.terms }>{ terms }</div>
|
||||
<div className={ styles.terms }>{ termsOfService }</div>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
@ -123,8 +123,7 @@ export default class GatherData extends Component {
|
||||
<p className={ styles.message }>You already requested verification.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (hasRequested === false) {
|
||||
} else if (hasRequested === false) {
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
<SuccessIcon />
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import ActionDoneAll from 'material-ui/svg-icons/action/done-all';
|
||||
import ContentClear from 'material-ui/svg-icons/content/clear';
|
||||
import DoneIcon from 'material-ui/svg-icons/action/done-all';
|
||||
import CancelIcon from 'material-ui/svg-icons/content/clear';
|
||||
|
||||
import { Button, IdentityIcon, Modal } from '../../ui';
|
||||
|
||||
@ -77,7 +77,7 @@ export default class SMSVerification extends Component {
|
||||
const cancel = (
|
||||
<Button
|
||||
key='cancel' label='Cancel'
|
||||
icon={ <ContentClear /> }
|
||||
icon={ <CancelIcon /> }
|
||||
onClick={ onClose }
|
||||
/>
|
||||
);
|
||||
@ -92,7 +92,7 @@ export default class SMSVerification extends Component {
|
||||
<Button
|
||||
key='done' label='Done'
|
||||
disabled={ !isStepValid }
|
||||
icon={ <ActionDoneAll /> }
|
||||
icon={ <DoneIcon /> }
|
||||
onClick={ onClose }
|
||||
/>
|
||||
</div>
|
||||
@ -140,37 +140,47 @@ export default class SMSVerification extends Component {
|
||||
setNumber, setConsentGiven, setCode
|
||||
} = this.props.store;
|
||||
|
||||
if (phase === 5) {
|
||||
return (<Done />);
|
||||
}
|
||||
if (phase === 4) {
|
||||
return (<SendConfirmation step={ step } tx={ confirmationTx } />);
|
||||
}
|
||||
if (phase === 3) {
|
||||
return (
|
||||
<QueryCode
|
||||
number={ number } fee={ fee } isCodeValid={ isCodeValid }
|
||||
setCode={ setCode }
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (phase === 2) {
|
||||
return (<SendRequest step={ step } tx={ requestTx } />);
|
||||
}
|
||||
if (phase === 1) {
|
||||
const { setNumber, setConsentGiven } = this.props.store;
|
||||
return (
|
||||
<GatherData
|
||||
fee={ fee } isNumberValid={ isNumberValid }
|
||||
isVerified={ isVerified } hasRequested={ hasRequested }
|
||||
setNumber={ setNumber } setConsentGiven={ setConsentGiven }
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (phase === 0) {
|
||||
return (<p>Preparing awesomeness!</p>);
|
||||
}
|
||||
switch (phase) {
|
||||
case 0:
|
||||
return (
|
||||
<p>Loading SMS Verification.</p>
|
||||
);
|
||||
|
||||
return null;
|
||||
case 1:
|
||||
const { setNumber, setConsentGiven } = this.props.store;
|
||||
return (
|
||||
<GatherData
|
||||
fee={ fee } isNumberValid={ isNumberValid }
|
||||
isVerified={ isVerified } hasRequested={ hasRequested }
|
||||
setNumber={ setNumber } setConsentGiven={ setConsentGiven }
|
||||
/>
|
||||
);
|
||||
|
||||
case 2:
|
||||
return (
|
||||
<SendRequest step={ step } tx={ requestTx } />
|
||||
);
|
||||
|
||||
case 3:
|
||||
return (
|
||||
<QueryCode
|
||||
number={ number } fee={ fee } isCodeValid={ isCodeValid }
|
||||
setCode={ setCode }
|
||||
/>
|
||||
);
|
||||
|
||||
case 4:
|
||||
return (
|
||||
<SendConfirmation step={ step } tx={ confirmationTx } />
|
||||
);
|
||||
|
||||
case 5:
|
||||
return (
|
||||
<Done />
|
||||
);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ import { sha3 } from '../../api/util/sha3';
|
||||
|
||||
import Contracts from '../../contracts';
|
||||
|
||||
import { checkIfVerified, checkIfRequested, postToServer } from '../../contracts/sms-verification';
|
||||
import { checkIfVerified, checkIfRequested } from '../../contracts/sms-verification';
|
||||
import { postToServer } from '../../3rdparty/sms-verification';
|
||||
import checkIfTxFailed from '../../util/check-if-tx-failed';
|
||||
import waitForConfirmations from '../../util/wait-for-block-confirmations';
|
||||
|
||||
@ -87,7 +88,7 @@ export default class VerificationStore {
|
||||
this.account = account;
|
||||
|
||||
this.step = LOADING;
|
||||
Contracts.create(api).registry.getContract('smsVerification')
|
||||
Contracts.create(api).registry.getContract('smsverification')
|
||||
.then((contract) => {
|
||||
this.contract = contract;
|
||||
this.load();
|
||||
|
@ -155,24 +155,20 @@ export default class Status {
|
||||
|
||||
const { refreshStatus } = this._store.getState().nodeStatus;
|
||||
|
||||
const statusPromises = [ this._api.eth.syncing() ];
|
||||
const statusPromises = [ this._api.eth.syncing(), this._api.parity.netPeers() ];
|
||||
|
||||
if (refreshStatus) {
|
||||
statusPromises.push(this._api.eth.hashrate());
|
||||
statusPromises.push(this._api.parity.netPeers());
|
||||
}
|
||||
|
||||
Promise
|
||||
.all(statusPromises)
|
||||
.then((statusResults) => {
|
||||
const status = statusResults.length === 1
|
||||
? {
|
||||
syncing: statusResults[0]
|
||||
}
|
||||
.then(([ syncing, netPeers, ...statusResults ]) => {
|
||||
const status = statusResults.length === 0
|
||||
? { syncing, netPeers }
|
||||
: {
|
||||
syncing: statusResults[0],
|
||||
hashrate: statusResults[1],
|
||||
netPeers: statusResults[2]
|
||||
syncing, netPeers,
|
||||
hashrate: statusResults[0]
|
||||
};
|
||||
|
||||
if (!isEqual(status, this._status)) {
|
||||
|
@ -96,7 +96,7 @@ export default class TypedInput extends Component {
|
||||
<IconButton
|
||||
iconStyle={ iconStyle }
|
||||
style={ style }
|
||||
onClick={ this.onAddField }
|
||||
onTouchTap={ this.onAddField }
|
||||
>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
@ -104,7 +104,7 @@ export default class TypedInput extends Component {
|
||||
<IconButton
|
||||
iconStyle={ iconStyle }
|
||||
style={ style }
|
||||
onClick={ this.onRemoveField }
|
||||
onTouchTap={ this.onRemoveField }
|
||||
>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
|
@ -67,7 +67,7 @@ export default class Dapps extends Component {
|
||||
label='edit'
|
||||
key='edit'
|
||||
icon={ <EyeIcon /> }
|
||||
onClick={ this.store.openModal }
|
||||
onTouchTap={ this.store.openModal }
|
||||
/>
|
||||
] }
|
||||
/>
|
||||
|
@ -74,7 +74,7 @@ class TransactionPendingFormConfirm extends Component {
|
||||
data-effect='solid'
|
||||
>
|
||||
<RaisedButton
|
||||
onClick={ this.onConfirm }
|
||||
onTouchTap={ this.onConfirm }
|
||||
className={ styles.confirmButton }
|
||||
fullWidth
|
||||
primary
|
||||
|
@ -37,7 +37,7 @@ export default class TransactionPendingFormReject extends Component {
|
||||
<strong>This cannot be undone</strong>
|
||||
</div>
|
||||
<RaisedButton
|
||||
onClick={ onReject }
|
||||
onTouchTap={ onReject }
|
||||
className={ styles.rejectButton }
|
||||
fullWidth
|
||||
label={ 'Reject Transaction' }
|
||||
|
@ -57,7 +57,7 @@ export default class CallsToolbar extends Component {
|
||||
<div className={ styles.callActions } { ...this._test('button-container') }>
|
||||
<IconButton
|
||||
className={ styles.callAction }
|
||||
onClick={ this.setCall }
|
||||
onTouchTap={ this.setCall }
|
||||
tooltip='Set'
|
||||
tooltipPosition='top-left'
|
||||
{ ...this._test('button-setCall') }
|
||||
@ -66,7 +66,7 @@ export default class CallsToolbar extends Component {
|
||||
</IconButton>
|
||||
<IconButton
|
||||
className={ styles.callAction }
|
||||
onClick={ this.makeCall }
|
||||
onTouchTap={ this.makeCall }
|
||||
tooltip='Fire again'
|
||||
tooltipPosition='top-left'
|
||||
{ ...this._test('button-makeCall') }
|
||||
|
@ -45,7 +45,7 @@ export default class ScrollTopButton extends Component {
|
||||
return (
|
||||
<IconButton
|
||||
className={ `${styles.scrollButton} ${hiddenClass}` }
|
||||
onClick={ this._scrollToTop }>
|
||||
onTouchTap={ this._scrollToTop }>
|
||||
<ArrowUpwardIcon />
|
||||
</IconButton>
|
||||
);
|
||||
|
@ -102,7 +102,7 @@ fn import(i: ImportAccounts) -> Result<String, String> {
|
||||
let from = DiskDirectory::at(path);
|
||||
imported += try!(import_accounts(&from, &to).map_err(|_| "Importing accounts failed.")).len();
|
||||
}
|
||||
Ok(format!("{}", imported))
|
||||
Ok(format!("{} account(s) imported", imported))
|
||||
}
|
||||
|
||||
fn import_geth(i: ImportFromGethAccounts) -> Result<String, String> {
|
||||
|
@ -40,7 +40,7 @@ Operating Options:
|
||||
(default: {flag_mode_alarm}).
|
||||
--chain CHAIN Specify the blockchain type. CHAIN may be either a
|
||||
JSON chain specification file or olympic, frontier,
|
||||
homestead, mainnet, morden, classic, expanse,
|
||||
homestead, mainnet, morden, ropsten, classic, expanse,
|
||||
testnet or dev (default: {flag_chain}).
|
||||
-d --db-path PATH Specify the database & configuration directory path
|
||||
(default: {flag_db_path}).
|
||||
|
@ -313,7 +313,7 @@ impl Configuration {
|
||||
|
||||
fn chain(&self) -> String {
|
||||
if self.args.flag_testnet {
|
||||
"morden".to_owned()
|
||||
"ropsten".to_owned()
|
||||
} else {
|
||||
self.args.flag_chain.clone()
|
||||
}
|
||||
@ -905,7 +905,7 @@ mod tests {
|
||||
// then
|
||||
assert_eq!(conf.network_settings(), NetworkSettings {
|
||||
name: "testname".to_owned(),
|
||||
chain: "morden".to_owned(),
|
||||
chain: "ropsten".to_owned(),
|
||||
network_port: 30303,
|
||||
rpc_enabled: true,
|
||||
rpc_interface: "local".to_owned(),
|
||||
|
Loading…
Reference in New Issue
Block a user