diff --git a/js/src/views/Status/containers/StatusPage/index.js b/js/src/views/Status/containers/StatusPage/index.js
index e36bc949c..0e141a16d 100644
--- a/js/src/views/Status/containers/StatusPage/index.js
+++ b/js/src/views/Status/containers/StatusPage/index.js
@@ -14,4 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see
.
-export default from './StatusPage';
+export default from './statusPage';
diff --git a/js/src/views/Status/status.css b/js/src/views/Status/containers/StatusPage/statusPage.css
similarity index 93%
rename from js/src/views/Status/status.css
rename to js/src/views/Status/containers/StatusPage/statusPage.css
index 0ed554ae6..bda975813 100644
--- a/js/src/views/Status/status.css
+++ b/js/src/views/Status/containers/StatusPage/statusPage.css
@@ -14,5 +14,9 @@
/* You should have received a copy of the GNU General Public License
/* along with Parity. If not, see
.
*/
-.container {
+
+.body {
+ &>div {
+ margin-bottom: 0.25em;
+ }
}
diff --git a/js/src/views/Status/containers/StatusPage/StatusPage.js b/js/src/views/Status/containers/StatusPage/statusPage.js
similarity index 95%
rename from js/src/views/Status/containers/StatusPage/StatusPage.js
rename to js/src/views/Status/containers/StatusPage/statusPage.js
index c7ab56c5e..286e2c20e 100644
--- a/js/src/views/Status/containers/StatusPage/StatusPage.js
+++ b/js/src/views/Status/containers/StatusPage/statusPage.js
@@ -23,6 +23,8 @@ import { clearStatusLogs, toggleStatusLogs, toggleStatusRefresh } from '~/redux/
import Debug from '../../components/Debug';
import Status from '../../components/Status';
+import styles from './statusPage.css';
+
class StatusPage extends Component {
static propTypes = {
nodeStatus: PropTypes.object.isRequired,
@@ -39,7 +41,7 @@ class StatusPage extends Component {
render () {
return (
-
+
diff --git a/js/src/views/Status/status.js b/js/src/views/Status/status.js
index ff13f1a07..805c96850 100644
--- a/js/src/views/Status/status.js
+++ b/js/src/views/Status/status.js
@@ -16,22 +16,16 @@
import React, { Component } from 'react';
-import { Actionbar, Page } from '~/ui';
+import { Page } from '~/ui';
import StatusPage from './containers/StatusPage';
-import styles from './status.css';
-
export default class Status extends Component {
render () {
return (
-
+
+
+
);
}
}
diff --git a/js/test/npmLibrary.js b/js/test/npmParity.js
similarity index 92%
rename from js/test/npmLibrary.js
rename to js/test/npmParity.js
index 63d8f9515..6e125e9e2 100644
--- a/js/test/npmLibrary.js
+++ b/js/test/npmParity.js
@@ -15,8 +15,8 @@
// along with Parity. If not, see
.
try {
- var Api = require('../.npmjs/library.js').Api;
- var Abi = require('../.npmjs/library.js').Abi;
+ var Api = require('../.npmjs/parity/library.js').Api;
+ var Abi = require('../.npmjs/parity/library.js').Abi;
if (typeof Api !== 'function') {
throw new Error('No Api');
diff --git a/js/webpack/app.js b/js/webpack/app.js
index 5998cf30b..a7b086b96 100644
--- a/js/webpack/app.js
+++ b/js/webpack/app.js
@@ -20,6 +20,7 @@ const path = require('path');
const WebpackErrorNotificationPlugin = require('webpack-error-notification');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
const Shared = require('./shared');
const DAPPS = require('../src/dapps');
@@ -41,7 +42,7 @@ module.exports = {
output: {
publicPath: '/',
path: path.join(__dirname, '../', DEST),
- filename: '[name].[hash].js'
+ filename: '[name].[hash:10].js'
},
module: {
@@ -85,13 +86,20 @@ module.exports = {
{
test: /\.css$/,
include: [ /src/ ],
+ // exclude: [ /src\/dapps/ ],
+ loader: isProd ? ExtractTextPlugin.extract([
+ // 'style-loader',
+ 'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
+ 'postcss-loader'
+ ]) : undefined,
// use: [ 'happypack/loader?id=css' ]
- use: [
+ use: isProd ? undefined : [
'style-loader',
'css-loader?modules&sourceMap&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
'postcss-loader'
]
},
+
{
test: /\.css$/,
exclude: [ /src/ ],
@@ -99,11 +107,15 @@ module.exports = {
},
{
test: /\.(png|jpg)$/,
- use: [ 'file-loader?name=[name].[hash].[ext]' ]
+ use: [ 'file-loader?&name=assets/[name].[hash:10].[ext]' ]
},
{
- test: /\.(woff(2)|ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
- use: [ 'file-loader' ]
+ test: /\.(woff(2)|ttf|eot|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
+ use: [ 'file-loader?name=fonts/[name][hash:10].[ext]' ]
+ },
+ {
+ test: /\.svg(\?v=[0-9]\.[0-9]\.[0-9])?$/,
+ use: [ 'file-loader?name=assets/[name].[hash:10].[ext]' ]
}
],
noParse: [
@@ -153,13 +165,20 @@ module.exports = {
if (!isProd) {
plugins.push(
new webpack.optimize.CommonsChunkPlugin({
- filename: 'commons.[hash].js',
+ filename: 'commons.[hash:10].js',
name: 'commons',
minChunks: Infinity
})
);
}
+ if (isProd) {
+ plugins.push(new ExtractTextPlugin({
+ filename: 'styles/[name].[hash:10].css',
+ allChunks: true
+ }));
+ }
+
return plugins;
}())
};
diff --git a/js/webpack/npm.js b/js/webpack/npm.js
index 7353efe55..a1bbaeda9 100644
--- a/js/webpack/npm.js
+++ b/js/webpack/npm.js
@@ -23,14 +23,27 @@ const Shared = require('./shared');
const ENV = process.env.NODE_ENV || 'development';
const isProd = ENV === 'production';
+const LIBRARY = process.env.LIBRARY;
+if (!LIBRARY) {
+ process.exit(-1);
+}
+const SRC = LIBRARY.toLowerCase();
+const OUTPUT_PATH = path.join(__dirname, '../.npmjs', SRC);
+
+const TEST_CONTEXT = SRC === 'parity'
+ ? '../npm/parity/test/'
+ : `../src/3rdparty/${SRC}/`;
+
+console.log(`Building ${LIBRARY} from library.${SRC}.js to .npmjs/${SRC}`);
+
module.exports = {
context: path.join(__dirname, '../src'),
target: 'node',
- entry: 'library.js',
+ entry: `library.${SRC}.js`,
output: {
- path: path.join(__dirname, '../.npmjs'),
+ path: OUTPUT_PATH,
filename: 'library.js',
- library: 'Parity',
+ library: LIBRARY,
libraryTarget: 'umd',
umdNamedDefine: true
},
@@ -66,19 +79,52 @@ module.exports = {
plugins: Shared.getPlugins().concat([
new CopyWebpackPlugin([
{
- from: '../parity.package.json',
+ from: `../npm/${SRC}/package.json`,
to: 'package.json',
transform: function (content, path) {
const json = JSON.parse(content.toString());
json.version = packageJson.version;
+
+ // Add tests dependencies to Dev Deps
+ json.devDependencies.chai = packageJson.devDependencies.chai;
+ json.devDependencies.mocha = packageJson.devDependencies.mocha;
+ json.devDependencies.nock = packageJson.devDependencies.nock;
+
+ // Add test script
+ json.scripts.test = 'mocha \'test/*.spec.js\'';
+
return new Buffer(JSON.stringify(json, null, ' '), 'utf-8');
}
},
{
from: '../LICENSE'
},
+
+ // Copy the base test config
{
- from: '../parity.md',
+ from: '../npm/test',
+ to: 'test'
+ },
+
+ // Copy the actual tests
+ {
+ context: TEST_CONTEXT,
+ from: '**/*.spec.js',
+ to: 'test',
+ transform: function (content, path) {
+ let output = content.toString();
+
+ // Don't skip tests
+ output = output.replace(/describe\.skip/, 'describe');
+
+ // Require parent library
+ output = output.replace('require(\'./\')', 'require(\'../\')');
+
+ return new Buffer(output, 'utf-8');
+ }
+ },
+ {
+ from: `../npm/${SRC}/README.md`,
to: 'README.md'
}
], { copyUnmodified: true })
diff --git a/js/webpack/shared.js b/js/webpack/shared.js
index 8b6807b2a..3c593fd87 100644
--- a/js/webpack/shared.js
+++ b/js/webpack/shared.js
@@ -36,6 +36,29 @@ function getBabelrc () {
// [ "es2015", { "modules": false } ]
babelrc.presets[es2015Index] = [ 'es2015', { modules: false } ];
babelrc['babelrc'] = false;
+
+ const BABEL_PRESET_ENV = process.env.BABEL_PRESET_ENV;
+ const npmStart = process.env.npm_lifecycle_event === 'start';
+ const npmStartApp = process.env.npm_lifecycle_event === 'start:app';
+
+ if (BABEL_PRESET_ENV && (npmStart || npmStartApp)) {
+ console.log('using babel-preset-env');
+
+ babelrc.presets = [
+ // 'es2017',
+ 'stage-0', 'react',
+ [
+ 'env',
+ {
+ targets: { browsers: ['last 2 Chrome versions'] },
+ modules: false,
+ loose: true,
+ useBuiltIns: true
+ }
+ ]
+ ];
+ }
+
return babelrc;
}
diff --git a/parity/user_defaults.rs b/parity/user_defaults.rs
index a1078b634..652abfea1 100644
--- a/parity/user_defaults.rs
+++ b/parity/user_defaults.rs
@@ -128,7 +128,13 @@ impl Default for UserDefaults {
impl UserDefaults {
pub fn load
(path: P) -> Result where P: AsRef {
match File::open(path) {
- Ok(file) => from_reader(file).map_err(|e| e.to_string()),
+ Ok(file) => match from_reader(file) {
+ Ok(defaults) => Ok(defaults),
+ Err(e) => {
+ warn!("Error loading user defaults file: {:?}", e);
+ Ok(UserDefaults::default())
+ },
+ },
_ => Ok(UserDefaults::default()),
}
}
diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs
index 66f46ba01..f13a3d037 100644
--- a/rpc/src/v1/impls/signer.rs
+++ b/rpc/src/v1/impls/signer.rs
@@ -89,11 +89,13 @@ impl Signer for SignerClient where C: MiningBlockC
signer.peek(&id).map(|confirmation| {
let mut payload = confirmation.payload.clone();
// Modify payload
- match (&mut payload, modification.gas_price) {
- (&mut ConfirmationPayload::SendTransaction(ref mut request), Some(gas_price)) => {
+ if let ConfirmationPayload::SendTransaction(ref mut request) = payload {
+ if let Some(gas_price) = modification.gas_price {
request.gas_price = gas_price.into();
- },
- _ => {},
+ }
+ if let Some(gas) = modification.gas {
+ request.gas = gas.into();
+ }
}
// Execute
let result = dispatch::execute(&*client, &*miner, &*accounts, payload, Some(pass));
diff --git a/rpc/src/v1/tests/mocked/signer.rs b/rpc/src/v1/tests/mocked/signer.rs
index ea89e5876..c87abb7eb 100644
--- a/rpc/src/v1/tests/mocked/signer.rs
+++ b/rpc/src/v1/tests/mocked/signer.rs
@@ -183,7 +183,7 @@ fn should_confirm_transaction_and_dispatch() {
let t = Transaction {
nonce: U256::zero(),
gas_price: U256::from(0x1000),
- gas: U256::from(10_000_000),
+ gas: U256::from(0x50505),
action: Action::Call(recipient),
value: U256::from(0x1),
data: vec![]
@@ -198,7 +198,7 @@ fn should_confirm_transaction_and_dispatch() {
let request = r#"{
"jsonrpc":"2.0",
"method":"signer_confirmRequest",
- "params":["0x1", {"gasPrice":"0x1000"}, "test"],
+ "params":["0x1", {"gasPrice":"0x1000","gas":"0x50505"}, "test"],
"id":1
}"#;
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
diff --git a/rpc/src/v1/types/confirmations.rs b/rpc/src/v1/types/confirmations.rs
index d8cfa14d6..f69018422 100644
--- a/rpc/src/v1/types/confirmations.rs
+++ b/rpc/src/v1/types/confirmations.rs
@@ -142,6 +142,8 @@ pub struct TransactionModification {
/// Modified gas price
#[serde(rename="gasPrice")]
pub gas_price: Option,
+ /// Modified gas
+ pub gas: Option,
}
/// Represents two possible return values.
@@ -275,18 +277,26 @@ mod tests {
let s1 = r#"{
"gasPrice":"0xba43b7400"
}"#;
- let s2 = r#"{}"#;
+ let s2 = r#"{"gas": "0x1233"}"#;
+ let s3 = r#"{}"#;
// when
let res1: TransactionModification = serde_json::from_str(s1).unwrap();
let res2: TransactionModification = serde_json::from_str(s2).unwrap();
+ let res3: TransactionModification = serde_json::from_str(s3).unwrap();
// then
assert_eq!(res1, TransactionModification {
gas_price: Some(U256::from_str("0ba43b7400").unwrap()),
+ gas: None,
});
assert_eq!(res2, TransactionModification {
gas_price: None,
+ gas: Some(U256::from_str("1233").unwrap()),
+ });
+ assert_eq!(res3, TransactionModification {
+ gas_price: None,
+ gas: None,
});
}
}
diff --git a/sync/src/chain.rs b/sync/src/chain.rs
index ecd95c68a..876144004 100644
--- a/sync/src/chain.rs
+++ b/sync/src/chain.rs
@@ -1685,7 +1685,7 @@ impl ChainSync {
pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) {
if packet_id != STATUS_PACKET && !self.peers.contains_key(&peer) {
- debug!(target:"sync", "Unexpected packet from unregistered peer: {}:{}", peer, io.peer_info(peer));
+ debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer));
return;
}
let rlp = UntrustedRlp::new(data);
diff --git a/sync/src/sync_io.rs b/sync/src/sync_io.rs
index 8dc8c65c0..e9e2d3396 100644
--- a/sync/src/sync_io.rs
+++ b/sync/src/sync_io.rs
@@ -131,6 +131,10 @@ impl<'s, 'h> SyncIo for NetSyncIo<'s, 'h> {
fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 {
self.network.protocol_version(*protocol, peer_id).unwrap_or(0)
}
+
+ fn peer_info(&self, peer_id: PeerId) -> String {
+ self.network.peer_client_version(peer_id)
+ }
}
diff --git a/util/network/src/host.rs b/util/network/src/host.rs
index f75158e4a..975fb87b8 100644
--- a/util/network/src/host.rs
+++ b/util/network/src/host.rs
@@ -22,7 +22,7 @@ use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
use std::ops::*;
use std::cmp::min;
use std::path::{Path, PathBuf};
-use std::io::{Read, Write};
+use std::io::{Read, Write, ErrorKind};
use std::fs;
use ethkey::{KeyPair, Secret, Random, Generator};
use mio::*;
@@ -381,8 +381,6 @@ pub struct Host {
impl Host {
/// Create a new instance
pub fn new(mut config: NetworkConfiguration, stats: Arc) -> Result {
- trace!(target: "host", "Creating new Host object");
-
let mut listen_address = match config.listen_address {
None => SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), DEFAULT_PORT)),
Some(addr) => addr,
@@ -405,6 +403,7 @@ impl Host {
// Setup the server socket
let tcp_listener = try!(TcpListener::bind(&listen_address));
listen_address = SocketAddr::new(listen_address.ip(), try!(tcp_listener.local_addr()).port());
+ debug!(target: "network", "Listening at {:?}", listen_address);
let udp_port = config.udp_port.unwrap_or(listen_address.port());
let local_endpoint = NodeEndpoint { address: listen_address, udp_port: udp_port };
@@ -707,7 +706,10 @@ impl Host {
}
};
match TcpStream::connect(&address) {
- Ok(socket) => socket,
+ Ok(socket) => {
+ trace!(target: "network", "Connecting to {:?}", address);
+ socket
+ },
Err(e) => {
debug!(target: "network", "Can't connect to address {:?}: {:?}", address, e);
return;
@@ -749,7 +751,9 @@ impl Host {
let socket = match self.tcp_listener.lock().accept() {
Ok((sock, _addr)) => sock,
Err(e) => {
- debug!(target: "network", "Error accepting connection: {:?}", e);
+ if e.kind() != ErrorKind::WouldBlock {
+ debug!(target: "network", "Error accepting connection: {:?}", e);
+ }
break
},
};
diff --git a/util/network/src/session.rs b/util/network/src/session.rs
index 9c8bed9da..3aab05d9a 100644
--- a/util/network/src/session.rs
+++ b/util/network/src/session.rs
@@ -435,16 +435,16 @@ impl Session {
// map to protocol
let protocol = self.info.capabilities[i].protocol;
- let pid = packet_id - self.info.capabilities[i].id_offset;
+ let protocol_packet_id = packet_id - self.info.capabilities[i].id_offset;
match *self.protocol_states.entry(protocol).or_insert_with(|| ProtocolState::Pending(Vec::new())) {
ProtocolState::Connected => {
- trace!(target: "network", "Packet {} mapped to {:?}:{}, i={}, capabilities={:?}", packet_id, protocol, pid, i, self.info.capabilities);
- Ok(SessionData::Packet { data: packet.data, protocol: protocol, packet_id: pid } )
+ trace!(target: "network", "Packet {} mapped to {:?}:{}, i={}, capabilities={:?}", packet_id, protocol, protocol_packet_id, i, self.info.capabilities);
+ Ok(SessionData::Packet { data: packet.data, protocol: protocol, packet_id: protocol_packet_id } )
}
ProtocolState::Pending(ref mut pending) => {
trace!(target: "network", "Packet {} deferred until protocol connection event completion", packet_id);
- pending.push((packet.data, packet_id));
+ pending.push((packet.data, protocol_packet_id));
Ok(SessionData::Continue)
}
diff --git a/util/table/src/lib.rs b/util/table/src/lib.rs
index a13beab11..f65c1e171 100644
--- a/util/table/src/lib.rs
+++ b/util/table/src/lib.rs
@@ -18,6 +18,7 @@
use std::hash::Hash;
use std::collections::HashMap;
+use std::collections::hash_map::Keys;
/// Structure to hold double-indexed values
///
@@ -41,6 +42,11 @@ impl Table
}
}
+ /// Returns keys iterator for this Table.
+ pub fn keys(&self) -> Keys> {
+ self.map.keys()
+ }
+
/// Removes all elements from this Table
pub fn clear(&mut self) {
self.map.clear();