Skip to content

Commit

Permalink
Problem: Transaction history should be relevant to particular chain
Browse files Browse the repository at this point in the history
Solution: Persist tracked transaction per each chain in localStorage with key *chain-<ID>-trackedTransactions*. After network switch reload transaction history for actual chain
  • Loading branch information
gagarin55 committed Sep 8, 2017
1 parent d6a8cea commit cf3cef9
Show file tree
Hide file tree
Showing 22 changed files with 390 additions and 252 deletions.
18 changes: 9 additions & 9 deletions electron/ledger.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ class LedgerApi {
connect() {
return new Promise((resolve, reject) => {
if (this.conn !== null) {
resolve(this)
resolve(this);
} else {
LedgerComm.create_async(5000, false).then((conn) => {
log.info("Connected to Ledger");
log.info('Connected to Ledger');
this.conn = new LedgerEth(conn);
resolve(this);
}).catch((err) => {
log.warn("Failed to connect to Ledger", err.message);
log.warn('Failed to connect to Ledger', err.message);
reject(err);
});
}
Expand All @@ -32,23 +32,23 @@ class LedgerApi {
this.conn.comm.close_async();
}
this.conn = null;
resolve({})
})
resolve({});
});
}

getStatus() {
return new Promise((resolve, reject) => {
this.conn.getAppConfiguration_async().then(resolve).fail(reject);
})
});
}

getAddress(hdpath) {
return new Promise((resolve, reject) => {
this.conn.getAddress_async(hdpath).then(resolve).fail(reject);
})
});
}
}

module.exports = {
LedgerApi: LedgerApi
};
LedgerApi,
};
2 changes: 1 addition & 1 deletion electron/menus/win-linux.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = function(window) {
module.exports = function (window) {
return [{
label: '&Emerald',
submenu: [{
Expand Down
2 changes: 1 addition & 1 deletion electron/userNotify.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class UserNotify {

constructor(webContents) {
this.webContents = webContents;
webContents.on('close', () => { this.webContents = null });
webContents.on('close', () => { this.webContents = null; });
}

info(msg) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/accounts/AccountShow/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class AccountRender extends React.Component {
</div>
</div>
<div style={styles.right}>
<AccountBalance balance={account.get('balance') || new Wei(0) } withAvatar={true} />
<AccountBalance balance={account.get('balance') || Wei.ZERO } withAvatar={true} />
</div>
</Row>

Expand Down Expand Up @@ -171,7 +171,7 @@ const AccountShow = connect(
}
let transactions = Immutable.List([]);
if (account.get('id')) {
transactions = state.accounts.get('trackedTransactions').filter((t) =>
transactions = state.wallet.history.get('trackedTransactions').filter((t) =>
(account.get('id') === t.get('to') || account.get('id') === t.get('from'))
);
}
Expand Down
14 changes: 4 additions & 10 deletions src/components/layout/Header/status/networkSelector.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { useRpc, saveSettings } from 'store/launcherActions';
import { MenuItem, DropDownMenu } from 'material-ui';
import { Networks, findNetwork } from 'lib/networks';

Expand All @@ -20,14 +19,14 @@ const styles = {
class NetworkSelectorRender extends React.Component {

render() {
const { chain, geth, switchNetwork } = this.props;
const { chain, geth, onNetworkChange } = this.props;
const isCurrentNetwork = (net) => (net.chain.id === chain.get('id')
&& (net.geth.url === geth.get('url')));
const currentNetwork = findNetwork(geth.get('url'), chain.get('id')) || {};

const networkClick = (net) => {
if (!isCurrentNetwork(net)) {
switchNetwork(net);
onNetworkChange(net);
}
};

Expand All @@ -52,7 +51,7 @@ class NetworkSelectorRender extends React.Component {


NetworkSelectorRender.propTypes = {
switchNetwork: PropTypes.func.isRequired,
onNetworkChange: PropTypes.func,
geth: PropTypes.object,
chain: PropTypes.object,
};
Expand All @@ -62,12 +61,7 @@ const NetworkSelector = connect(
chain: state.launcher.get('chain'),
geth: state.launcher.get('geth'),
}),
(dispatch, ownProps) => ({
switchNetwork: (net) => {
dispatch(useRpc({ geth: net.geth, chain: net.chain }));
dispatch(saveSettings({ chain: net.chain, geth: net.geth }));
},
})
(dispatch, ownProps) => ({})
)(NetworkSelectorRender);

export default NetworkSelector;
16 changes: 12 additions & 4 deletions src/components/layout/Header/status/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { connect } from 'react-redux';
import LinearProgress from 'material-ui/LinearProgress';
import NetworkSelector from './networkSelector';
import { separateThousands } from 'lib/convert';
import { useRpc, saveSettings } from '../../../../store/launcherActions';
import { init as initWalletHistory } from '../../../../store/wallet/history/historyActions';


const Render = ({ block, progress, peerCount, showDetails, connecting }) => {
const Render = ({ block, progress, peerCount, showDetails, connecting, switchNetwork }) => {
const styles = {
details: {
color: '#47B04B',
Expand Down Expand Up @@ -42,7 +43,7 @@ const Render = ({ block, progress, peerCount, showDetails, connecting }) => {
<div>
<div style={styles.block}>
{details}
<NetworkSelector />
<NetworkSelector onNetworkChange={ switchNetwork }/>
</div>
{showDetails && <div><LinearProgress mode="determinate" color="green" value={progress} /></div>}
</div>
Expand All @@ -55,6 +56,7 @@ Render.propTypes = {
peerCount: PropTypes.number,
showDetails: PropTypes.bool.isRequired,
connecting: PropTypes.bool.isRequired,
switchNetwork: PropTypes.func,
};

const Status = connect(
Expand All @@ -78,7 +80,13 @@ const Status = connect(
}
return props;
},
(dispatch, ownProps) => ({})
(dispatch, ownProps) => ({
switchNetwork: (net) => {
dispatch(useRpc({ geth: net.geth, chain: net.chain }));
dispatch(saveSettings({ chain: net.chain, geth: net.geth }));
dispatch(initWalletHistory(net.chain.id));
},
})
)(Render);

export default Status;
4 changes: 2 additions & 2 deletions src/components/layout/Header/total.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ const Total = connect(

// Sum of balances of all known accounts.
const total = state.accounts.get('accounts', Immutable.List())
.map((account) => (account.get('balance') ? account.get('balance') : new Wei(0)))
.reduce((t, v) => t.plus(v), new Wei(0));
.map((account) => (account.get('balance') ? account.get('balance') : Wei.ZERO))
.reduce((t, v) => t.plus(v), Wei.ZERO);
const totalEther = total.getEther();

let fiat = {};
Expand Down
2 changes: 1 addition & 1 deletion src/components/tx/CreateTx/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const CreateTx = connect(
data.password,
data.to,
toHex(data.gas),
toHex(data.gasPrice.val),
toHex(data.gasPrice.value()),
toHex(etherToWei(data.value)))
);
});
Expand Down
2 changes: 1 addition & 1 deletion src/components/tx/TxDetails/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ const TransactionShow = connect(
const rates = state.accounts.get('rates');
const currentCurrency = state.accounts.get('localeCurrency');

const Tx = state.accounts.get('trackedTransactions').find(
const Tx = state.wallet.history.get('trackedTransactions').find(
(tx) => tx.get('hash') === ownProps.hash
);
if (!Tx) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/tx/TxHistory/List/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import IconButton from 'material-ui/IconButton';
import { Wei } from 'emerald-js';

import { gotoScreen } from '../../../../store/screenActions';
import { refreshTransaction } from '../../../../store/accountActions';
import { refreshTransaction } from '../../../../store/wallet/history/historyActions';
import { link, tables } from '../../../../lib/styles';
import AddressAvatar from '../../../../elements/AddressAvatar/addressAvatar';
import AccountBalance from '../../../accounts/AccountBalance';
Expand Down
14 changes: 5 additions & 9 deletions src/components/tx/TxHistory/history.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { connect } from 'react-redux';
import { List } from 'immutable';

import Card from '../../../elements/Card';
import { gotoScreen } from '../../../store/screenActions';

import Header from './Header';
import TxList from './List';

import classes from './history.scss';

const Render = ({ transactions }) => {
const TransactionsHistory = ({ transactions }) => {
return (
<Card>
<div className={ classes.container }>
Expand All @@ -23,20 +21,18 @@ const Render = ({ transactions }) => {
);
};

Render.propTypes = {
TransactionsHistory.propTypes = {
transactions: PropTypes.object.isRequired,
};

const TransactionsHistory = connect(
export default connect(
(state, ownProps) => {
const transactionsAccounts = state.accounts.get('trackedTransactions', new List());
const transactionsAccounts = state.wallet.history.get('trackedTransactions', new List());
const txs = ownProps.transactions || transactionsAccounts;
return {
transactions: txs.reverse(),
};
},
(dispatch, ownProps) => ({
})
)(Render);

export default TransactionsHistory;
)(TransactionsHistory);
4 changes: 2 additions & 2 deletions src/lib/convert.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import BigNumber from 'bignumber.js';
import Immutable from 'immutable';
import { fromTokens, mweiToWei, etherToWei, estimateGasFromTrace } from './convert';
import { transformToFullName, functionToData, dataToParams, getFunctionSignature, separateThousands } from './convert';
import { fromTokens, mweiToWei, etherToWei, estimateGasFromTrace, transformToFullName, functionToData,
dataToParams, getFunctionSignature, separateThousands } from './convert';

describe('Number formatting', () => {
it('format number with separated thousands', () => {
Expand Down
69 changes: 3 additions & 66 deletions src/store/accountActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { loadTokenBalanceOf } from './tokenActions';
import { gotoScreen, catchError } from './screenActions';
import Wallet from '../lib/wallet';

import { trackTx, processPending } from './wallet/history/historyActions';

const { toNumber, toHex } = convert;
const currentChain = (state) => state.launcher.getIn(['chain', 'name']);

Expand Down Expand Up @@ -274,22 +276,6 @@ export function importWallet(wallet, name, description) {
};
}


function loadStoredTransactions() {
return (dispatch) => {
if (localStorage) {
const storedTxs = localStorage.getItem('trackedTransactions');
if (storedTxs !== null) {
const storedTxsJSON = JSON.parse(storedTxs);
dispatch({
type: 'ACCOUNT/LOAD_STORED_TXS',
transactions: storedTxsJSON,
});
}
}
};
}

export function loadSettings() {
return (dispatch) => {
if (localStorage) {
Expand All @@ -312,11 +298,7 @@ export function loadPendingTransactions() {
const txes = result.transactions.filter((t) =>
(addrs.includes(t.to) || addrs.includes(t.from))
);
dispatch({
type: 'ACCOUNT/PENDING_TX',
txList: txes,
});
dispatch(loadStoredTransactions());
dispatch(processPending(txes));
for (const tx of txes) {
const disp = {
type: 'ACCOUNT/PENDING_BALANCE',
Expand All @@ -336,51 +318,6 @@ export function loadPendingTransactions() {
});
}

export function refreshTransaction(hash) {
return (dispatch) =>
api.geth.getTransactionByHash(hash).then((result) => {
if (!result) {
log.info(`No tx for hash ${hash}`);
dispatch({
type: 'ACCOUNT/TRACKED_TX_NOTFOUND',
hash,
});
} else if (typeof result === 'object') {
dispatch({
type: 'ACCOUNT/UPDATE_TX',
tx: result,
});
/** TODO: Check for input data **/
if ((result.creates !== undefined) && (isAddress(result.creates) === undefined)) {
dispatch({
type: 'CONTRACT/UPDATE_CONTRACT',
tx: result,
address: result.creates,
});
}
}
});
}

/**
* Refresh only tx with totalRetries <= 10
*/
export function refreshTrackedTransactions() {
return (dispatch, getState) => {
getState().accounts.get('trackedTransactions')
.filter((tx) => tx.get('totalRetries', 0) <= 10)
.map((tx) => dispatch(refreshTransaction(tx.get('hash')))
);
};
}

export function trackTx(tx) {
return {
type: 'ACCOUNT/TRACK_TX',
tx,
};
}

export function getGasPrice() {
return (dispatch) => {
api.geth.gasPrice().then((result) => {
Expand Down
Loading

0 comments on commit cf3cef9

Please sign in to comment.