Merge branch 'master' into ui-2

This commit is contained in:
Jaco Greeff 2017-04-21 11:19:40 +02:00
commit 2ffb6496f4
6 changed files with 90 additions and 38 deletions

View File

@ -46,7 +46,7 @@ pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address,
From::from(stream.as_raw().sha3())
},
CreateContractAddress::FromCodeHash => {
let mut buffer = [0u8; 20 + 32];
let mut buffer = [0xffu8; 20 + 32];
&mut buffer[20..].copy_from_slice(&code_hash[..]);
From::from((&buffer[..]).sha3())
},

View File

@ -127,7 +127,7 @@ impl From<ethjson::state::Transaction> for SignedTransaction {
};
match secret {
Some(s) => tx.sign(&s, None),
None => tx.null_sign(),
None => tx.null_sign(1),
}
}
}
@ -210,13 +210,13 @@ impl Transaction {
}
/// Add EIP-86 compatible empty signature.
pub fn null_sign(self) -> SignedTransaction {
pub fn null_sign(self, network_id: u64) -> SignedTransaction {
SignedTransaction {
transaction: UnverifiedTransaction {
unsigned: self,
r: U256::zero(),
s: U256::zero(),
v: 0,
v: network_id,
hash: 0.into(),
}.compute_hash(),
sender: UNSIGNED_SENDER,

View File

@ -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 BalancesProvider from './balances';
import { showSnackbar } from './snackbarActions';
import { DEFAULT_NETCHAIN } from './statusReducer';
export default class ChainMiddleware {
@ -24,20 +22,34 @@ export default class ChainMiddleware {
if (action.type === 'statusCollection') {
const { collection } = action;
if (collection && collection.netChain) {
const newChain = collection.netChain;
if (collection) {
const { nodeStatus } = store.getState();
const { netChain, nodeKind } = nodeStatus;
const newChain = collection.netChain;
const newNodeKind = collection.nodeKind;
let reloadChain = false;
let reloadType = false;
if (newChain !== nodeStatus.netChain && nodeStatus.netChain !== DEFAULT_NETCHAIN) {
store.dispatch(showSnackbar(`Switched to ${newChain}. The UI will reload now...`));
// force reload when chain has changed and is not initial value
if (newChain) {
const hasChainChanged = newChain !== netChain;
const isInitialChain = netChain === DEFAULT_NETCHAIN;
reloadChain = !isInitialChain && hasChainChanged;
}
// force reload when nodeKind (availability or capability) has changed
if (newNodeKind && nodeKind) {
const hasAvailabilityChanged = nodeKind.availability !== newNodeKind.availability;
const hasCapabilityChanged = nodeKind.capability !== newNodeKind.capability;
reloadType = hasAvailabilityChanged || hasCapabilityChanged;
}
if (reloadChain || reloadType) {
setTimeout(() => {
window.location.reload();
}, 0);
// Fetch the new balances without notifying the user of any change
BalancesProvider.get(store).fetchAllBalances({
changedNetwork: true
});
}
}
}

View File

@ -24,11 +24,22 @@ import { createWsApi } from '~/../test/e2e/ethapi';
let middleware;
let next;
let store;
let clock;
const api = createWsApi();
Contracts.create(api);
function stubGlobals () {
clock = sinon.useFakeTimers();
sinon.spy(window.location, 'reload');
}
function restoreGlobals () {
window.location.reload.restore();
clock.restore();
}
function createMiddleware (collection = {}) {
middleware = new ChainMiddleware().toMiddleware();
next = sinon.stub();
@ -46,10 +57,22 @@ function createMiddleware (collection = {}) {
}
function callMiddleware (action) {
return middleware(store)(next)(action);
const result = middleware(store)(next)(action);
clock.tick(100);
return result;
}
describe('reduxs/providers/ChainMiddleware', () => {
beforeEach(() => {
stubGlobals();
});
afterEach(() => {
restoreGlobals();
});
describe('next action', () => {
beforeEach(() => {
createMiddleware();
@ -69,25 +92,25 @@ describe('reduxs/providers/ChainMiddleware', () => {
});
describe('chain switching', () => {
it('does not dispatch when moving from the initial/unknown chain', () => {
it('does not reload when moving from the initial/unknown chain', () => {
createMiddleware();
callMiddleware({ type: 'statusCollection', collection: { netChain: 'homestead' } });
expect(store.dispatch).not.to.have.been.called;
expect(window.location.reload).not.to.have.been.called;
});
it('does not dispatch when moving to the same chain', () => {
it('does not reload when moving to the same chain', () => {
createMiddleware({ netChain: 'homestead' });
callMiddleware({ type: 'statusCollection', collection: { netChain: 'homestead' } });
expect(store.dispatch).not.to.have.been.called;
expect(window.location.reload).not.to.have.been.called;
});
it('does dispatch when moving between chains', () => {
it('does reload when moving between chains', () => {
createMiddleware({ netChain: 'homestead' });
callMiddleware({ type: 'statusCollection', collection: { netChain: 'ropsten' } });
expect(store.dispatch).to.have.been.called;
expect(window.location.reload).to.have.been.called;
});
});
});

View File

@ -156,7 +156,8 @@ export default class Status {
}
_pollTraceMode = () => {
return this._api.trace.block()
return this._api.trace
.block()
.then(blockTraces => {
// Assumes not in Trace Mode if no transactions
// in latest block...
@ -168,14 +169,12 @@ export default class Status {
getApiStatus = () => {
const { isConnected, isConnecting, needsToken, secureToken } = this._api;
const apiStatus = {
return {
isConnected,
isConnecting,
needsToken,
secureToken
};
return apiStatus;
}
_pollStatus = () => {
@ -194,7 +193,10 @@ export default class Status {
return Promise.resolve();
}
const statusPromises = [ this._api.eth.syncing(), this._api.parity.netPeers() ];
const statusPromises = [
this._api.eth.syncing(),
this._api.parity.netPeers()
];
return Promise
.all(statusPromises)
@ -225,7 +227,10 @@ export default class Status {
return Promise.resolve();
}
const nextTimeout = (timeout = 30000) => {
const { nodeKindFull } = this._store.getState().nodeStatus;
const defaultTimeout = (nodeKindFull === false ? 240 : 30) * 1000;
const nextTimeout = (timeout = defaultTimeout) => {
if (this._timeoutIds.longStatus) {
clearTimeout(this._timeoutIds.longStatus);
}
@ -233,24 +238,34 @@ export default class Status {
this._timeoutIds.longStatus = setTimeout(() => this._pollLongStatus(), timeout);
};
const statusPromises = [
this._api.parity.nodeKind(),
this._api.parity.netPeers(),
this._api.web3.clientVersion(),
this._api.net.version(),
this._api.parity.netChain()
];
if (nodeKindFull) {
statusPromises.push(this._upgradeStore.checkUpgrade());
}
return Promise
.all([
this._api.parity.netPeers(),
this._api.web3.clientVersion(),
this._api.net.version(),
this._api.parity.netChain(),
this._upgradeStore.checkUpgrade()
])
.then(([
netPeers, clientVersion, netVersion, netChain, upgradeStatus
]) => {
.all(statusPromises)
.then(([nodeKind, netPeers, clientVersion, netVersion, netChain]) => {
const isTest = [
'2', // morden
'3', // ropsten
'42' // kovan
].includes(netVersion);
const nodeKindFull = nodeKind &&
nodeKind.availability === 'personal' &&
nodeKind.capability === 'full';
const longStatus = {
nodeKind,
nodeKindFull,
netPeers,
clientVersion,
netChain,

View File

@ -31,6 +31,8 @@ const initialState = {
peers: []
},
netVersion: '0',
nodeKind: null,
nodeKindFull: null,
syncing: true,
isConnected: false,
isConnecting: false,