From 1bb41eba85f1f6435ca7c39e7e214eccc385996c Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Mar 2019 12:57:48 +0100 Subject: [PATCH 01/50] Make it clear that settings apply only to list view Since the consensus view will be added users could mistake the settings as being applied there as well. --- packages/frontend/src/components/Settings/Settings.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend/src/components/Settings/Settings.tsx b/packages/frontend/src/components/Settings/Settings.tsx index 2edc77508..44720e93e 100644 --- a/packages/frontend/src/components/Settings/Settings.tsx +++ b/packages/frontend/src/components/Settings/Settings.tsx @@ -27,6 +27,7 @@ export class Settings extends React.Component { return (
+

List View

Visible Columns

{ Row.columns From 138b4afd05a3f12f33f50b0f6ee01c87ea8baf39 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Mar 2019 13:05:30 +0100 Subject: [PATCH 02/50] Add Jdenticon --- packages/frontend/public/Jdenticon.min.js | 19 ++++++++ packages/frontend/public/index.html | 1 + .../src/components/Consensus/Jdenticon.css | 9 ++++ .../src/components/Consensus/Jdenticon.tsx | 43 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 packages/frontend/public/Jdenticon.min.js create mode 100644 packages/frontend/src/components/Consensus/Jdenticon.css create mode 100644 packages/frontend/src/components/Consensus/Jdenticon.tsx diff --git a/packages/frontend/public/Jdenticon.min.js b/packages/frontend/public/Jdenticon.min.js new file mode 100644 index 000000000..d7bec5eab --- /dev/null +++ b/packages/frontend/public/Jdenticon.min.js @@ -0,0 +1,19 @@ +// Jdenticon 2.1.1 | jdenticon.com | MIT licensed | (c) 2014-2018 Daniel Mester Pirttijärvi +(function(q,y,z){var t=z(q,q.jQuery);"undefined"!==typeof module&&"exports"in module?module.exports=t:"function"===typeof define&&define.amd?define([],function(){return t}):q[y]=t})(this,"jdenticon",function(q,y){function z(a,b,c){for(var d=document.createElementNS("http://www.w3.org/2000/svg",b),f=2;f+1>>e&15).toString(16));return b.join("")}(function(a){for(var b= +1732584193,d=4023233417,f=2562383102,e=271733878,h=3285377520,k=[b,d,f,e,h],g=0;gl;l++){var A=u[l-3]^u[l-8]^u[l-14]^u[l-16];u[l]=A<<1|A>>>31}for(l=0;80>l;l++)A=(b<<5|b>>>27)+(20>l?(d&f^~d&e)+1518500249:40>l?(d^f^e)+1859775393:60>l?(d&f^d&e^f&e)+2400959708:(d^f^e)+3395469782)+h+u[l],h=e,e=f,f=d<<30|d>>>2,d=b,b=A|0;k[0]=b=k[0]+b|0;k[1]=d=k[1]+d|0;k[2]=f=k[2]+f|0;k[3]=e=k[3]+e|0;k[4]=h=k[4]+h|0}return k}(function(a){function b(a,b){for(var c=[],d=-1,e=0;e++d;)c[d]=0;return c}var d=encodeURI(a),f=[];a=0;var e,h=[];for(e=0;ea?"00":16>a?"0"+a.toString(16):256>a?a.toString(16):"ff"}function F(a,b,c){c=0>c?c+6:6c?a+(b-a)*c:3>c?b:4>c?a+(b-a)*(4-c):a))}function O(a){"undefined"!=typeof MutationObserver&&(new MutationObserver(function(b){for(var c=0;cf;f++){var q=r(b,8+f,1)%p.length;if(g([0,4])||g([2,3]))q=1;n.push(q)}k(0, +I.I,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]);k(1,I.I,4,5,[[0,0],[3,0],[3,3],[0,3]]);k(2,I.M,1,null,[[1,1],[2,1],[2,2],[1,2]]);a.finish()}function J(){function a(a,b){var d=c[a];d&&1a?0:1a.length){var b=a[1],c=a[2],d=a[3];a=a[4]||"";return"#"+b+b+c+c+d+d+a+a}if(7==a.length||8=c?c*(b+1):c+b-c*b;c=2*c-b;return"#"+F(c,b,6*a+2)+F(c,b,6*a)+F(c,b,6*a-2)},i:function(a,b,c){var d=[.55,.5,.5,.46,.6,.55,.55][6*a+.5|0];return m.N(a,b,.5>c?c*d*2:d+(c-.5)*(1-d)*2)}},I={M:[function(a,b){var c=.42*b;a.f([0,0,b,0,b,b-2*c,b-c,b,0,b])},function(a,b){var c=0|.5*b;a.b(b-c,0,c,0|.8*b,2)},function(a,b){var c=0|b/3;a.a(c,c,b-c,b-c)},function(a,b){var c=.1*b,d= +6>b?1:8>b?2:0|.25*b;c=1b?1:6>b?2:0|.35*b;c=8>b?c:0|c;a.a(0,0,b,b);a.a(d,d,b-d-c,b-d-c,!0)},function(a,b){var c=.12* +b,d=3*c;a.a(0,0,b,b);a.g(d,d,b-c-d,!0)},function(a,b){a.b(b/2,b/2,b/2,b/2,3)},function(a,b){var c=.25*b;a.a(0,0,b,b);a.l(c,c,b-c,b-c,!0)},function(a,b,c){var d=.4*b;c||a.g(d,d,1.2*b)}],I:[function(a,b){a.b(0,0,b,b,0)},function(a,b){a.b(0,b/2,b,b/2,0)},function(a,b){a.l(0,0,b,b)},function(a,b){var c=b/6;a.g(c,c,b-2*c)}]};L.prototype={f:function(a){for(var b="M"+p(a[0].x)+" "+p(a[0].y),c=1;c +
@@ -86,6 +91,10 @@ export class Chain extends React.Component { const { appState, pins } = this.props; + if (display === 'consensus') { + return ; + } + return ( display === 'list' ? diff --git a/packages/frontend/src/components/Consensus/Consensus.css b/packages/frontend/src/components/Consensus/Consensus.css new file mode 100644 index 000000000..b1876a36a --- /dev/null +++ b/packages/frontend/src/components/Consensus/Consensus.css @@ -0,0 +1,144 @@ +.ConsensusList { + opacity: 0; +} + +.ConsensusList table { + border-spacing: 0px; +} + +.flexContainerLargeRow { + opacity: 1.0 !important; + display: flex; + align-items: stretch; + flex-direction: row; +} + +.flexContainerLargeRow .firstInRow { + width: 100% +} + +.flexContainerLargeRow .firstInRow .emptylegend, +.flexContainerLargeRow .firstInRow .nameLegend { + width: 99%; + flex-grow: 1000000000; + align-self: stretch; +} + +.flexContainerSmallRow { + opacity: 1.0 !important; + display: flex; + align-items: stretch; + flex-direction: row; + flex-wrap: wrap; +} + +.flexContainerSmallRow div { + align-self: stretch; + flex: 1; +} + +.flexContainerSmallRow table .legend { + width: 100%; +} + +.ConsensusList { + margin-bottom: 2px; +} + +.allRows { + width: 100%; + min-width: 1350px; + min-height: 100%; + position: absolute; + top: 0px; + left: 0px; +} + +.SmallRow { + float: left; + clear: both; + font-size: 8px !important; + width: 100%; +} + +.SmallRow svg { + width: 14px; + height: 14px; +} + +.hatching svg { + width: 12px !important; + height: 12px !important; +} + +.SmallRow .hatching svg { + width: 10px !important; + height: 10px !important; +} + +.matrixXLegend .Tooltip-container { + height: auto !important; +} + +.legend { + text-align: center !important; +} + +.nameLegend { + border-right: none; + border-bottom: 1px dotted #555; +} + +.SmallRow .nameLegend { + display: none; +} + +.SmallRow .finalizedInfo .Tooltip-container { + float: none; + display: inline-block !important; + vertical-align: middle; +} + +.SmallRow .finalizedInfo { + min-height: 40px; + min-width: 40px; +} + +.SmallRow .explicit, +.SmallRow .implicit { + height: 12px; +} + +.SmallRow .finalizedInfo .explicit, +.SmallRow .finalizedInfo .implicit { + margin-right: 6px; +} + +.nodeAddress { + margin-top: 4px; +} + +.first_false .legend .nodeAddress, +.SmallRow .legend .nodeAddress, +th.finalizedInfo .Tooltip-container { + float: none !important; + text-align: center !important; +} + +.noStretchOnLastRow::after { + content: ''; + flex-grow: 1000000000; +} + +.flexContainerLargeRow .noStretchOnLastRow .firstInRow table { + width: auto !important; +} + +.flexContainerLargeRow .noStretchOnLastRow .firstInRow .emptylegend { + width: auto !important; +} + +.flexContainerLargeRow .noStretchOnLastRow .firstInRow { + width: auto !important; +} + diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx new file mode 100644 index 000000000..0d1a1dffe --- /dev/null +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -0,0 +1,216 @@ +import * as React from 'react'; +import { Types } from '@dotstats/common'; +import Measure, {BoundingRect, ContentRect} from 'react-measure'; + +import { ConsensusBlock } from './'; +import { State as AppState, Node } from '../../state'; + +import './Consensus.css'; + +export namespace Consensus { + export interface Props { + appState: Readonly; + } + + export interface State { + dimensions: BoundingRect; + } +} + +export class Consensus extends React.Component { + public state = { + // entire area available for rendering the visualization + dimensions: { width: -1, height: -1 } as BoundingRect, + + largeBlockWithLegend: { width: -1, height: -1 }, + largeBlock: { width: -1, height: -1 }, + countBlocksInLargeRow: 2, + largeRowsFlexClassAdded: false, + + smallBlock: { width: -1, height: -1 }, + smallBlocksRows: 1, + countBlocksInSmallRow: 1, + smallRowsFlexClassAdded: false, + }; + + public initialBlockSizeSet(): boolean { + return this.state.largeBlockWithLegend.width > -1 && this.state.largeBlockWithLegend.height > -1 && + this.state.largeBlock.width > -1 && this.state.largeBlock.height > -1; + } + + public initialSmallBlockSizeSet(): boolean { + return this.state.smallBlock.width > -1 && this.state.largeBlockWithLegend.height > -1; + } + + public calculateBoxCount(wasResized: boolean) { + // if the css class for flexing has already been added we don't calculate + // any box measurements then, because the box sizes would be skewed then. + if ((wasResized || this.state.largeRowsFlexClassAdded === false) && this.initialBlockSizeSet()) { + // we need to add +2 because of the last block which doesn't contain a border. + let countBlocks = (this.state.dimensions.width - this.state.largeBlockWithLegend.width + 2) / + (this.state.largeBlock.width + 2); + + // +1 because the firstRect was subtracted above and needs to be counted back in. + // default count is 2 because we need two blocks to measure properly (one with legend + // and one without. these measures are necessary to calculate the number of blocks + // which fit. + countBlocks = Math.floor(countBlocks + 1) < 1 ? 2 : Math.floor(countBlocks + 1); + + this.setState({largeRowsFlexClassAdded: true, countBlocksInLargeRow: countBlocks }); + } + + if ((wasResized || this.state.smallRowsFlexClassAdded === false) && this.initialSmallBlockSizeSet()) { + const howManyRows = 2; + + const heightLeft = this.state.dimensions.height - (this.state.largeBlock.height * howManyRows); + + let smallBlocksRows = heightLeft / this.state.smallBlock.height; + smallBlocksRows = smallBlocksRows < 1 ? 1 : Math.floor(smallBlocksRows); + + let countBlocksInSmallRow = this.state.dimensions.width / this.state.smallBlock.width; + countBlocksInSmallRow = countBlocksInSmallRow < 1 ? 1 : Math.floor(countBlocksInSmallRow); + + this.setState({ smallRowsFlexClassAdded: true, countBlocksInSmallRow, smallBlocksRows }); + } + } + + public shouldComponentUpdate(nextProps: Consensus.Props, nextState: Consensus.State): boolean { + if (this.props.appState.authorities.length === 0 && nextProps.appState.authorities.length === 0) { + return false; + } + + const authoritiesDidChange = JSON.stringify(this.props.appState.authorities) !== + JSON.stringify(nextProps.appState.authorities); + const authoritySetIdDidChange = this.props.appState.authoritySetId !== + nextProps.appState.authoritySetId; + + const newConsensusInfoAvailable = JSON.stringify(this.props.appState.consensusInfo) !== + JSON.stringify(nextProps.appState.consensusInfo); + + const windowSizeChanged = JSON.stringify(this.state.dimensions) !== + JSON.stringify(nextState.dimensions); + + return authoritiesDidChange || authoritySetIdDidChange || newConsensusInfoAvailable || + windowSizeChanged; + } + + public render() { + const handleOnResize = (contentRect: ContentRect) => { + this.setState({ dimensions: contentRect.bounds as BoundingRect }); + this.calculateBoxCount(true); + }; + + this.calculateBoxCount(false); + + const lastBlocks = Object.keys(this.props.appState.consensusInfo).reverse(); + + let from = 0; + let to = this.state.countBlocksInLargeRow; + const firstLargeRow = this.getLargeRow(lastBlocks.slice(from, to), true); + + from = to; + to = to + this.state.countBlocksInLargeRow; + const secondLargeRow = this.getLargeRow(lastBlocks.slice(from, to), false); + + from = to; + to = to + (this.state.smallBlocksRows * this.state.countBlocksInSmallRow); + const smallRow = this.getSmallRow(lastBlocks.slice(from, to)); + + return ( + + + {({ measureRef }) => ( +
+ {firstLargeRow} + {secondLargeRow} + {smallRow} +
+ )} +
+
+ ); + } + + private getAuthorities(): Node[] { + return this.props.appState.authorities.map(address => + this.props.appState.nodes.sorted() + .filter(node => node.address === address)[0]); + } + + private getLargeRow(blocks: string[], animateOnAppearing: boolean) { + const largeBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { + if (this.initialBlockSizeSet()) { + return; + } + if (isFirstBlock) { + this.setState({largeBlockWithLegend: {width: rect.width, height: rect.height} }); + } else { + this.setState({largeBlock: {width: rect.width, height: rect.height} }); + } + }; + + const stretchLastRowMajor = blocks.length < this.state.countBlocksInLargeRow ? + 'noStretchOnLastRow' : ''; + const flexClass = this.state.largeRowsFlexClassAdded ? 'flexContainerLargeRow' : ''; + + return
+ {blocks.map((height, i) => + )} +
; + } + + private getSmallRow(blocks: string[]) { + const smallBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { + if (this.initialSmallBlockSizeSet()) { + return; + } + const dimensionsChanged = this.state.smallBlock.height !== rect.height && + this.state.smallBlock.width !== rect.width; + if (dimensionsChanged) { + this.setState({ smallBlock: {width: rect.width, height: rect.height} }); + } + }; + const stretchLastRow = + blocks.length < this.state.countBlocksInSmallRow * this.state.smallBlocksRows ? + 'noStretchOnLastRow' : ''; + const classes = `ConsensusList SmallRow ${this.state.smallRowsFlexClassAdded ? 'flexContainerSmallRow' : ''} ${stretchLastRow}`; + + return
+ {blocks.map((height, i) => { + let lastInRow = (i+1) % this.state.countBlocksInSmallRow === 0 ? true : false; + if (lastInRow && i === 0) { + // should not be marked as last one in row if it's the very first in row + lastInRow = false; + } + + return ; + }) + } +
; + } +} diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.css b/packages/frontend/src/components/Consensus/ConsensusBlock.css new file mode 100644 index 000000000..628e7d316 --- /dev/null +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.css @@ -0,0 +1,210 @@ +.BlockConsensusMatrice { + background-color: #222; + font-family: monospace, sans-serif; + border-spacing: 0px; + border-right: 2px solid lightgrey; + border-bottom: 1px solid #999; +} + +.LargeRow .BlockConsensusMatrice:last-child { + border-right: none; +} + +.SmallRow .lastInRow { + clear: right; + width: 99%; + page-break-after: always; +} + +.BlockConsensusMatrice th { + font-weight: normal; + border-bottom: 1px dashed #999; +} + +.finalizedInfo, .legend { + border-bottom: 1px dotted #555555; +} + +.finalizedInfo { + white-space: nowrap; +} + +.finalizedInfo .Tooltip-container { + display: inline-block; + white-space: nowrap; + vertical-align: middle; +} + +.BlockConsensusMatrice .matrice { + width: 28px; + height: 28px; +} + +.BlockConsensusMatrice .matrice { + font-weight: normal; + border-right: 1px dotted #555555; + border-bottom: 1px dotted #555; +} + +.BlockConsensusMatrice tr .matrice:last-child { + border-right: none; +} + +.BlockConsensusMatrice .matrixXLegend { + text-align: center; + border-right: 1px dotted #555555; +} + +.BlockConsensusMatrice .matrixXLegend:last-child { + border-right: none; +} + +.matrice { + text-align: center !important; + min-width: 35px; +} + +.SmallRow .matrixXLegend, +.SmallRow .matrice { + min-width: 26px; + min-height: 26px; +} + +.finalizedInfo { + text-align: center !important; +} + +.SmallRow .finalizedInfo { + min-width: 40px; +} + +.finalizedInfo { + text-align: right; + border-right: 1px dashed #999; + min-width: 48px; +} + +.finalizedInfo .Tooltip-container { + float: none; +} + +.explicit { + fill: #E70E81; +} + +.nodeName { + float: left; + padding-right: 10px; + padding-top: 4px; +} + +.flexContainerLargeRow .firstInRow .nodeContent { + white-space: nowrap; +} + +.flexContainerLargeRow .firstInRow .nodeName { + display: inline-block !important; + float: none !important; + vertical-align: middle; + margin-bottom: 3px; +} + +.flexContainerLargeRow .firstInRow .nodeAddress { + display: inline-block !important; + float: none !important; + vertical-align: middle; + margin-right: 3px; +} + +.legend { + border-right: 1px solid #999; + white-space: nowrap; +} + +.first_false .nodeName { + display: none; +} + +.legend .nodeAddress { + float: right; +} + +.Row { + color: #999; + cursor: pointer; +} + +.Row th, .Row td { + text-align: left; + padding: 2px; +} + +.Row td { + position: relative; +} + +.Row .Row-truncate { + position: absolute; + left: 0; + right: 0; + top: 0; + padding: inherit; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.Row .Row-Tooltip { + position: initial; + padding: inherit; +} + +.Row:hover { + background-color: #161616; +} + +.nodeAddress svg { + cursor: pointer; +} + +.nodeAddress svg:hover { + transform: scale(2); +} + +.blockTransition-appear { + opacity: 0.01; +} + +.blockTransition-appear.blockTransition-appear-active { + opacity: 1; + transition: opacity 3s ease-in; +} + +.matrice .Icon ~ .Icon { + margin-left: -4px; +} + +.SmallRow .matrice .Prevote svg { + margin-left: 3px; + margin-bottom: -11px; +} + +.SmallRow .matrice .Precommit svg { + margin-left: -1px; + margin-top: -6px; + margin-bottom: 0px; +} + +.jdenticonPlaceholder { + width: 28px; +} + +.SmallRow .jdenticonPlaceholder { + width: 14px; + float: right; +} + +.even { + background-color: #333; +} + diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx new file mode 100644 index 000000000..a5f2ceb93 --- /dev/null +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -0,0 +1,254 @@ +import * as React from 'react'; +import { CSSTransitionGroup } from 'react-transition-group'; + +import Measure, {BoundingRect, ContentRect} from 'react-measure'; +import { Types } from '@dotstats/common'; +import Identicon from 'polkadot-identicon'; + +import { Node } from '../../state'; +import { Icon, Tooltip } from '../'; +import Jdenticon from './Jdenticon'; + +import checkIcon from '../../icons/check.svg'; +import finalizedIcon from '../../icons/finalized.svg'; +import hatchingIcon from '../../icons/hatching.svg'; + +import './ConsensusBlock.css'; + +export namespace ConsensusBlock { + export interface Props { + authorities: Node[]; + authoritySetId: Types.AuthoritySetId; + authoritySetBlockNumber: Types.BlockNumber; + height: Types.BlockNumber; + firstInRow: boolean; + lastInRow: boolean; + animateOnAppearing: boolean; + compact: boolean; + consensusView: Types.ConsensusView; + changeBlocks: (first: boolean, boundsRect: BoundingRect) => void; + } +} + +export class ConsensusBlock extends React.Component { + + public shouldComponentUpdate(nextProps: ConsensusBlock.Props): boolean { + if (this.props.authorities.length === 0 && nextProps.authorities.length === 0) { + return false; + } + + const newConsensusInfo = + JSON.stringify(nextProps.consensusView) !== JSON.stringify(this.props.consensusView); + const positionInfoChanged = this.props.firstInRow !== nextProps.firstInRow || + this.props.lastInRow !== nextProps.lastInRow; + + return newConsensusInfo || positionInfoChanged; + } + + public render() { + const finalizedByWhom = this.props.authorities.filter(node => this.isFinalized(node)); + const ratio = finalizedByWhom.length + '/' + this.props.authorities.length; + const tooltip = `${ratio} authorities finalized this block. Authority Set Id: ${this.props.authoritySetId}.`; + let titleFinal = {ratio}; + + const majorityFinalized = finalizedByWhom.length / this.props.authorities.length >= 2/3; + if (majorityFinalized && !this.props.compact) { + titleFinal = FINAL; + } else if (majorityFinalized && this.props.compact) { + const hash = this.getFinalizedHash(finalizedByWhom[0]); + titleFinal = + + + ; + } + + const handleOnResize = (contentRect: ContentRect) => { + this.props.changeBlocks(this.props.firstInRow, contentRect.bounds as BoundingRect); + }; + + return ({({ measureRef }) => ( +
+ + + + + {this.props.firstInRow && !this.props.compact ? + : ''} + + + {this.props.authorities.map(node => + )} + + + + {this.props.authorities.map((node, row) => + this.renderMatriceRow(node, this.props.authorities, row))} + +
  + + {this.displayBlockNumber()} + + + {titleFinal} + + {this.getNodeContent(node, false)} +
+
+
)} +
); + } + + private displayBlockNumber(): string { + const blockNumber = String(this.props.height); + return blockNumber.length > 2 ? + '…' + blockNumber.substr(blockNumber.length - 2, blockNumber.length) : blockNumber; + } + + private isFinalized(node: Node): boolean { + const { address } = node; + const consensus = this.props.consensusView; + + return consensus !== undefined && + address in consensus && + address in consensus[address] && + consensus[address][address].Finalized === true; + } + + private getFinalizedHash(node: Node): Types.BlockHash { + const { address } = node; + const consensus = this.props.consensusView; + + if (consensus !== undefined && + address in consensus && + address in consensus[address] && + consensus[address][address].Finalized === true) { + return consensus[address][address].FinalizedHash; + } + return '' as Types.BlockHash; + } + + private renderMatriceRow(node: Node, authorities: Node[], row: number): JSX.Element { + let finalizedInfo =  ; + let finalizedHash; + + if (this.isFinalized(node)) { + const matrice = this.props.consensusView[node.address][node.address]; + finalizedInfo = matrice.ImplicitFinalized ? + + + + : + + + + + finalizedHash = matrice.FinalizedHash ? + + + :
 
; + } + + const firstName = this.props.firstInRow ? {node.name} : ''; + + return + {firstName} + {this.getNodeContent(node, true)} + {finalizedInfo}{finalizedHash} + { + authorities.map((columnNode, column) => { + const evenOdd = ((row % 2) + column) % 2 === 0 ? 'even' : 'odd'; + return {this.getMatriceContent(node, columnNode)} + }) + } + ; + } + + private getNodeContent(node: Node, nodeName: boolean): JSX.Element { + return
+
+ + + +
+
; + } + + private format(consensusDetail: Types.ConsensusDetail): string { + const txt = []; + if (consensusDetail.Prevote) { + txt.push('Prevote on this chain in this block'); + } else if (consensusDetail.ImplicitPrevote) { + txt.push('Prevote on this chain in block ' + consensusDetail.ImplicitPointer); + } + if (consensusDetail.Precommit) { + txt.push('Precommit on this chain in this block'); + } else if (consensusDetail.ImplicitPrecommit) { + txt.push('Precommit on this chain in block ' + consensusDetail.ImplicitPointer); + } + if (consensusDetail.Finalized && consensusDetail.ImplicitFinalized) { + txt.push('Finalized this chain in block ' + consensusDetail.ImplicitPointer); + } else if (consensusDetail.Finalized && !consensusDetail.ImplicitFinalized) { + txt.push('Finalized this chain in this block'); + } + return txt.join(', '); // + JSON.stringify((consensusDetail)); + } + + private getMatriceContent(rowNode: Node, columnNode: Node) { + const consensusInfo = this.props.consensusView && + rowNode.address in this.props.consensusView && + columnNode.address in this.props.consensusView[rowNode.address] ? + this.props.consensusView[rowNode.address][columnNode.address] : null; + + let tooltipText = consensusInfo ? + rowNode.name + ' has seen this of ' + columnNode.name + ': ' + + this.format(consensusInfo) : 'No information available yet.'; + + if (rowNode.address === columnNode.address) { + tooltipText = 'Self-referential.'; + } + + const prevote = consensusInfo && consensusInfo.Prevote; + const implicitPrevote = consensusInfo && consensusInfo.ImplicitPrevote; + + const precommit = consensusInfo && consensusInfo.Precommit; + const implicitPrecommit = consensusInfo && consensusInfo.ImplicitPrecommit; + + if (rowNode.address !== columnNode.address) { + let statPrevote; + let statPrecommit; + + if (implicitPrevote) { + statPrevote = ; + } + if (implicitPrecommit) { + statPrecommit = ; + } + + if (prevote) { + statPrevote = ; + } + if (precommit) { + statPrecommit = ; + } + + const stat = [statPrevote, statPrecommit]; + return {stat} + } else { + return + + + } + } + +} diff --git a/packages/frontend/src/components/Consensus/index.ts b/packages/frontend/src/components/Consensus/index.ts new file mode 100644 index 000000000..fd170857a --- /dev/null +++ b/packages/frontend/src/components/Consensus/index.ts @@ -0,0 +1,2 @@ +export * from './Consensus'; +export * from './ConsensusBlock'; diff --git a/packages/frontend/src/components/index.ts b/packages/frontend/src/components/index.ts index 04f76831b..93000ba94 100644 --- a/packages/frontend/src/components/index.ts +++ b/packages/frontend/src/components/index.ts @@ -3,6 +3,7 @@ export * from './Chain'; export * from './List'; export * from './Map'; export * from './Settings'; +export * from './Consensus'; export * from './Icon'; export * from './Tile'; export * from './Ago'; diff --git a/packages/frontend/src/icons/finalized.svg b/packages/frontend/src/icons/finalized.svg new file mode 100644 index 000000000..6bd538508 --- /dev/null +++ b/packages/frontend/src/icons/finalized.svg @@ -0,0 +1,17 @@ + + + diff --git a/packages/frontend/src/icons/grandpa.svg b/packages/frontend/src/icons/grandpa.svg new file mode 100644 index 000000000..218bfebee --- /dev/null +++ b/packages/frontend/src/icons/grandpa.svg @@ -0,0 +1,74 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/packages/frontend/src/icons/hatching.svg b/packages/frontend/src/icons/hatching.svg new file mode 100644 index 000000000..3a69ac949 --- /dev/null +++ b/packages/frontend/src/icons/hatching.svg @@ -0,0 +1,120 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/packages/frontend/src/state.ts b/packages/frontend/src/state.ts index 042532c9a..028efaacd 100644 --- a/packages/frontend/src/state.ts +++ b/packages/frontend/src/state.ts @@ -19,6 +19,7 @@ export class Node { } public readonly id: Types.NodeId; + public readonly address: Types.Address; public readonly name: Types.NodeName; public readonly implementation: Types.NodeImplementation; public readonly version: Types.NodeVersion; @@ -41,6 +42,7 @@ export class Node { public propagationTime: Maybe; public finalized = 0 as Types.BlockNumber; + public consensusInfo: Types.ConsensusInfo; public finalizedHash = '' as Types.BlockHash; public lat: Maybe; @@ -58,12 +60,13 @@ export class Node { blockDetails: Types.BlockDetails, location: Maybe ) { - const [name, implementation, version, validator, networkId] = nodeDetails; + const [name, address, implementation, version, validator, networkId] = nodeDetails; this.pinned = pinned; this.id = id; this.name = name; + this.address = address; this.implementation = implementation; this.version = version; this.validator = validator; @@ -116,6 +119,10 @@ export class Node { this.finalizedHash = hash; } + public updateConsensusInfo(consensusInfo: Types.ConsensusInfo) { + this.consensusInfo = consensusInfo; + } + public updateLocation(location: Types.NodeLocation) { const [lat, lon, city] = location; @@ -182,6 +189,10 @@ export interface State { status: 'online' | 'offline' | 'upgrade-requested'; best: Types.BlockNumber; finalized: Types.BlockNumber; + consensusInfo: Types.ConsensusInfo; + authorities: Types.Address[]; + authoritySetId: Types.AuthoritySetId; + authoritySetBlockNumber: Types.BlockNumber; blockTimestamp: Types.Timestamp; blockAverage: Maybe; timeDiff: Types.Milliseconds; diff --git a/yarn.lock b/yarn.lock index f83192cb5..169c767ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,6 +18,20 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/runtime@^7.1.2": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.0.tgz#d523416573f19aa12784639e631257c7fc58c0aa" + integrity sha512-/eftZ45kD0OfOFHAmN02WP6N1NVphY+lBf8c2Q/P9VW3tj+N5NlBBAWfqOLOl96YDGMqpIBO5O/hQNx4A/lAng== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/runtime@^7.2.0": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.2.tgz#f5ab6897320f16decd855eed70b705908a313fe8" + integrity sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA== + dependencies: + regenerator-runtime "^0.13.2" + "@fnando/sparkline@maciejhirsz/sparkline": version "0.3.10" resolved "https://codeload.github.com/maciejhirsz/sparkline/tar.gz/2bdb002b171436be078a84f1e4e617a44ef1fb42" @@ -102,6 +116,13 @@ dependencies: "@types/react" "*" +"@types/react-measure@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/react-measure/-/react-measure-2.0.5.tgz#c1d304e3cab3a1c393342bf377b040628e6c29a8" + integrity sha512-T1Bpt8FlWbDhoInUaNrjTOiVRpRJmrRcqhFJxLGBq1VjaqBLHCvUPapgdKMWEIX4Oqsa1SSKjtNkNJGy6WAAZg== + dependencies: + "@types/react" "*" + "@types/react-svg@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/react-svg/-/react-svg-3.0.0.tgz#ebbd0a095339ba20d9ba1d8fb3441eef9aeb5d11" @@ -1760,6 +1781,11 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chain-function@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.1.tgz#c63045e5b4b663fb86f1c6e186adaf1de402a1cc" + integrity sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg== + chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2670,6 +2696,13 @@ dom-converter@~0.2: dependencies: utila "~0.4" +dom-helpers@^3.2.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -3642,6 +3675,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-node-dimensions@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz#fb7b4bb57060fb4247dd51c9d690dfbec56b0823" + integrity sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ== + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -5732,7 +5770,7 @@ longest@^1.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7276,6 +7314,15 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" +prop-types@^15.5.6: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + prop-types@^15.6.0, prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" @@ -7509,6 +7556,21 @@ react-is@^16.6.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa" integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g== +react-is@^16.8.1: + version "16.8.4" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2" + integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA== + +react-measure@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.2.4.tgz#cec3d96d3c39e22660e958e26d5498e4a342b9e4" + integrity sha512-gpZA4J8sKy1TzTfnOXiiTu01GV8B5OyfF9k7Owt38T6Xxlll19PBE13HKTtauEmDdJO5u4o3XcTiGqCw5wpfjw== + dependencies: + "@babel/runtime" "^7.2.0" + get-node-dimensions "^1.2.1" + prop-types "^15.6.2" + resize-observer-polyfill "^1.5.0" + react-scripts-ts@2.17.0: version "2.17.0" resolved "https://registry.yarnpkg.com/react-scripts-ts/-/react-scripts-ts-2.17.0.tgz#398bae19a30c9b39b3dfe0720ebb40c60c2f6574" @@ -7571,6 +7633,17 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.5.2: react-is "^16.7.0" scheduler "^0.12.0" +react-transition-group@1.x: + version "1.2.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6" + integrity sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q== + dependencies: + chain-function "^1.0.0" + dom-helpers "^3.2.0" + loose-envify "^1.3.1" + prop-types "^15.5.6" + warning "^3.0.0" + react@16.4.0: version "16.4.0" resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585" @@ -7737,6 +7810,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -7906,6 +7984,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resize-observer-polyfill@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -9479,6 +9562,13 @@ walker@~1.0.5: dependencies: makeerror "1.0.x" +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + dependencies: + loose-envify "^1.0.0" + watch@~0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" From 3c830af715c50c9525bf31bccd09b88266e7dbe9 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 4 Apr 2019 14:07:18 +0200 Subject: [PATCH 04/50] Remove fade-in animation --- .../declarations/react-transition-group.d.ts | 5 -- packages/frontend/package.json | 1 - .../src/components/Consensus/Consensus.css | 6 -- .../src/components/Consensus/Consensus.tsx | 10 ++- .../components/Consensus/ConsensusBlock.css | 9 --- .../components/Consensus/ConsensusBlock.tsx | 62 ++++++++----------- yarn.lock | 11 ---- 7 files changed, 30 insertions(+), 74 deletions(-) delete mode 100644 packages/frontend/declarations/react-transition-group.d.ts diff --git a/packages/frontend/declarations/react-transition-group.d.ts b/packages/frontend/declarations/react-transition-group.d.ts deleted file mode 100644 index 6c9742026..000000000 --- a/packages/frontend/declarations/react-transition-group.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* necessary for react transitions to work. - see https://stackoverflow.com/questions/54698733/types-react-transition-group-generic-type-reactelementp-t-requires-betwee. */ -declare module 'react-transition-group' { - export const CSSTransitionGroup: any -} diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 067f48ab3..1e674a330 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -27,7 +27,6 @@ "react-measure": "^2.2.4", "react-scripts-ts": "2.17.0", "react-svg": "^4.1.1", - "react-transition-group": "1.x", "stable": "^0.1.8" }, "scripts": { diff --git a/packages/frontend/src/components/Consensus/Consensus.css b/packages/frontend/src/components/Consensus/Consensus.css index b1876a36a..14e4eff3d 100644 --- a/packages/frontend/src/components/Consensus/Consensus.css +++ b/packages/frontend/src/components/Consensus/Consensus.css @@ -1,13 +1,8 @@ -.ConsensusList { - opacity: 0; -} - .ConsensusList table { border-spacing: 0px; } .flexContainerLargeRow { - opacity: 1.0 !important; display: flex; align-items: stretch; flex-direction: row; @@ -25,7 +20,6 @@ } .flexContainerSmallRow { - opacity: 1.0 !important; display: flex; align-items: stretch; flex-direction: row; diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index 0d1a1dffe..0265adb27 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -106,11 +106,11 @@ export class Consensus extends React.Component { let from = 0; let to = this.state.countBlocksInLargeRow; - const firstLargeRow = this.getLargeRow(lastBlocks.slice(from, to), true); + const firstLargeRow = this.getLargeRow(lastBlocks.slice(from, to), 0); from = to; to = to + this.state.countBlocksInLargeRow; - const secondLargeRow = this.getLargeRow(lastBlocks.slice(from, to), false); + const secondLargeRow = this.getLargeRow(lastBlocks.slice(from, to), 1); from = to; to = to + (this.state.smallBlocksRows * this.state.countBlocksInSmallRow); @@ -137,7 +137,7 @@ export class Consensus extends React.Component { .filter(node => node.address === address)[0]); } - private getLargeRow(blocks: string[], animateOnAppearing: boolean) { + private getLargeRow(blocks: string[], id: number) { const largeBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { if (this.initialBlockSizeSet()) { return; @@ -155,12 +155,11 @@ export class Consensus extends React.Component { return
+ key={`consensusList_${id}`}> {blocks.map((height, i) => { return void; @@ -70,40 +68,32 @@ export class ConsensusBlock extends React.Component {
- - - - - {this.props.firstInRow && !this.props.compact ? - : ''} - - - {this.props.authorities.map(node => - )} - - - - {this.props.authorities.map((node, row) => - this.renderMatriceRow(node, this.props.authorities, row))} - -
  - - {this.displayBlockNumber()} - - - {titleFinal} - - {this.getNodeContent(node, false)} -
-
+ + + + {this.props.firstInRow && !this.props.compact ? + : ''} + + + {this.props.authorities.map(node => + )} + + + + {this.props.authorities.map((node, row) => + this.renderMatriceRow(node, this.props.authorities, row))} + +
  + + {this.displayBlockNumber()} + + + {titleFinal} + + {this.getNodeContent(node, false)} +
)} ); } diff --git a/yarn.lock b/yarn.lock index 169c767ce..7c92cdd6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7633,17 +7633,6 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.5.2: react-is "^16.7.0" scheduler "^0.12.0" -react-transition-group@1.x: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6" - integrity sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q== - dependencies: - chain-function "^1.0.0" - dom-helpers "^3.2.0" - loose-envify "^1.3.1" - prop-types "^15.5.6" - warning "^3.0.0" - react@16.4.0: version "16.4.0" resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585" From c570cbc2e74cad401c94736ed09cf2b437058ab9 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 4 Apr 2019 14:10:19 +0200 Subject: [PATCH 05/50] Update packages and yarn.lock --- yarn.lock | 54 +++++++----------------------------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7c92cdd6f..2a59eec27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,17 +18,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/runtime@^7.1.2": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.0.tgz#d523416573f19aa12784639e631257c7fc58c0aa" - integrity sha512-/eftZ45kD0OfOFHAmN02WP6N1NVphY+lBf8c2Q/P9VW3tj+N5NlBBAWfqOLOl96YDGMqpIBO5O/hQNx4A/lAng== - dependencies: - regenerator-runtime "^0.13.2" - "@babel/runtime@^7.2.0": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.2.tgz#f5ab6897320f16decd855eed70b705908a313fe8" - integrity sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA== + version "7.4.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.3.tgz#79888e452034223ad9609187a0ad1fe0d2ad4bdc" + integrity sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA== dependencies: regenerator-runtime "^0.13.2" @@ -1781,11 +1774,6 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chain-function@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.1.tgz#c63045e5b4b663fb86f1c6e186adaf1de402a1cc" - integrity sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg== - chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2696,13 +2684,6 @@ dom-converter@~0.2: dependencies: utila "~0.4" -dom-helpers@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" - integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== - dependencies: - "@babel/runtime" "^7.1.2" - dom-serializer@0, dom-serializer@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -5770,7 +5751,7 @@ longest@^1.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7314,15 +7295,6 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prop-types@^15.5.6: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - prop-types@^15.6.0, prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" @@ -7556,15 +7528,10 @@ react-is@^16.6.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa" integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g== -react-is@^16.8.1: - version "16.8.4" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2" - integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA== - react-measure@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.2.4.tgz#cec3d96d3c39e22660e958e26d5498e4a342b9e4" - integrity sha512-gpZA4J8sKy1TzTfnOXiiTu01GV8B5OyfF9k7Owt38T6Xxlll19PBE13HKTtauEmDdJO5u4o3XcTiGqCw5wpfjw== + version "2.2.5" + resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.2.5.tgz#35f6be9a8c31d61a4cf847282f9d54c310eb1624" + integrity sha512-j1OE5U3AfX97Tk/LNkn2KSdE03hGgBOqUoQQ8QdxHoAudAvP1K1R7hvEH+S5zHILFh7ejGCKK3wWZOMDcHL3mA== dependencies: "@babel/runtime" "^7.2.0" get-node-dimensions "^1.2.1" @@ -9551,13 +9518,6 @@ walker@~1.0.5: dependencies: makeerror "1.0.x" -warning@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" - integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= - dependencies: - loose-envify "^1.0.0" - watch@~0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" From e4de35cbeccf12e5df5d99662b0e44b5a49b1678 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sat, 6 Apr 2019 18:48:21 +0200 Subject: [PATCH 06/50] Broadcast only delta of what changed --- packages/backend/src/Chain.ts | 17 ++++++++++++++++- packages/frontend/src/Connection.ts | 9 +++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 02ddfa79c..6b24e2952 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -12,6 +12,7 @@ const MAX_BLOCKS_IN_CHAIN_CACHE = 5; export default class Chain { private nodes = new Set(); private chainConsensusCache: Types.ConsensusInfo = {} as ConsensusInfo; + private lastBroadcastCache: Types.ConsensusInfo = {} as ConsensusInfo; private feeds = new FeedSet(); public readonly events = new EventEmitter(); @@ -189,7 +190,21 @@ export default class Chain { } } - this.feeds.broadcast(Feed.consensusInfo(this.chainConsensusCache)); + // broadcast only the cache blocks which changed + const delta: Types.ConsensusInfo = {} as ConsensusInfo; + for (let height in this.chainConsensusCache) { + const current = this.chainConsensusCache[height]; + const old = this.lastBroadcastCache[height]; + + if (JSON.stringify(current) !== JSON.stringify(old)) { + delta[height] = current; + this.lastBroadcastCache[height] = JSON.parse(JSON.stringify(current)); + } + } + + if (Object.keys(delta).length > 0 ) { + this.feeds.broadcast(Feed.consensusInfo(delta)); + } } private authoritySetChanged(node: Node, authorities: Types.Authorities, authoritySetId: Types.AuthoritySetId) { diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index 7c21a00b0..c19a386a4 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -161,9 +161,14 @@ export class Connection { } case Actions.ConsensusInfo: { - const consensusInfo = message.payload; + const receivedConsensusInfo = message.payload; + const updatedConsensusInfo = JSON.parse(JSON.stringify(this.state.consensusInfo)); - this.state = this.update({ consensusInfo }); + for (const height of Object.keys(receivedConsensusInfo)) { + updatedConsensusInfo[height] = receivedConsensusInfo[height]; + } + + this.state = this.update({ consensusInfo: updatedConsensusInfo }); break; } From 1e824c7dee53fedd9a5ae9d5d1c1ac3e57fc2dd7 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 7 Apr 2019 12:40:39 +0200 Subject: [PATCH 07/50] Minor code improvements --- packages/backend/src/Chain.ts | 3 +-- packages/backend/src/Node.ts | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 6b24e2952..f81ee2b54 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -182,8 +182,7 @@ export default class Chain { } private updateConsensusInfo(node: Node) { - let height; - for (height in node.consensusCache) { + for (let height in node.consensusCache) { if (height !== undefined) { this.initialiseConsensusView(parseInt(height) as BlockNumber, String(node.address), String(node.address)); this.chainConsensusCache[height][String(node.address)] = node.consensusCache[height]; diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 35adf0fd2..76b293de4 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -276,6 +276,7 @@ export default class Node { if (message.msg === 'afg.authority_set') { this.onAfgAuthoritySet(message); } + this.truncateBlockCache(); } private onSystemInterval(message: SystemInterval) { @@ -367,8 +368,6 @@ export default class Node { // we can set them and display them in the ui. this.consensusCache[finalizedHeight][addr].Prevote = true; this.consensusCache[finalizedHeight][addr].Precommit = true; - - this.truncateBlockCache(); } public markImplicitlyFinalized(finalizedHeight: BlockNumber) { @@ -411,17 +410,14 @@ export default class Node { // this node voted for this chain and all the blocks before the current // one as well. if there no commits yet registered for the prior block // close the gap to the last block by creating initial block objects. - let to = targetNumber; - this.backfill(voter, to as BlockNumber, (i) => { - // the function denotes when we stop backfilling the cache - i = i as BlockNumber; + const mutate = (i: BlockNumber) => { const info = this.consensusCache[i][voter]; if (info.Precommit || info.ImplicitPrecommit) { return false; } - this.consensusCache[i][voter].ImplicitPrecommit = true; - this.consensusCache[i][voter].ImplicitPointer = to; + info.ImplicitPrecommit = true; + info.ImplicitPointer = to; let firstBlockReached = String(i) === Object.keys(this.consensusCache)[0]; if (!this.alreadyPrecommit && firstBlockReached) { @@ -430,7 +426,9 @@ export default class Node { } return true; - }); + }; + const to = targetNumber as BlockNumber; + this.backfill(voter, to, mutate); this.events.emit('consensus-info'); } @@ -445,8 +443,7 @@ export default class Node { this.initialiseConsensusView(targetNumber as BlockNumber, voter); this.consensusCache[targetNumber as BlockNumber][voter].Prevote = true; - let to = targetNumber; - this.backfill(voter, to as BlockNumber, (i) => { + const mutate = (i: BlockNumber) => { // the function denotes when we stop backfilling the cache i = i as BlockNumber; const info = this.consensusCache[i][voter]; @@ -464,7 +461,9 @@ export default class Node { } return true; - }); + }; + const to = targetNumber as BlockNumber; + this.backfill(voter, to, mutate); this.events.emit('consensus-info'); } From a7ba53101682b48ed17652c4d2fd2101c3d63b62 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 08:59:32 +0200 Subject: [PATCH 08/50] Use NodeId instead of Address in first dimension By using the NodeId instead of the Address in the first dimension of the consensus matrice we save quite some space in the payload which is sent to the browser. The commit also contains some minor refactoring. --- packages/backend/src/Chain.ts | 16 ++-- packages/backend/src/Node.ts | 84 ++++++++++--------- packages/common/src/types.ts | 2 +- .../components/Consensus/ConsensusBlock.tsx | 26 +++--- 4 files changed, 65 insertions(+), 63 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index f81ee2b54..15324d9a8 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -168,24 +168,24 @@ export default class Chain { this.updateConsensusInfo(node); } - private initialiseConsensusView(height: BlockNumber, id1: string, id2: string) { + private initialiseConsensusView(height: BlockNumber, id_node1: string, addr_node2: string) { if (this.chainConsensusCache[height] === undefined) { this.chainConsensusCache[height] = {}; } - if (this.chainConsensusCache[height][id1] === undefined) { - this.chainConsensusCache[height][id1] = {}; - this.chainConsensusCache[height][id1][id2] = {} as Types.ConsensusInfo; + if (this.chainConsensusCache[height][id_node1] === undefined) { + this.chainConsensusCache[height][id_node1] = {}; + this.chainConsensusCache[height][id_node1][addr_node2] = {} as Types.ConsensusInfo; } - if (this.chainConsensusCache[height][id1][id2] === undefined) { - this.chainConsensusCache[height][id1][id2] = {} as Types.ConsensusInfo; + if (this.chainConsensusCache[height][id_node1][addr_node2] === undefined) { + this.chainConsensusCache[height][id_node1][addr_node2] = {} as Types.ConsensusInfo; } } private updateConsensusInfo(node: Node) { for (let height in node.consensusCache) { if (height !== undefined) { - this.initialiseConsensusView(parseInt(height) as BlockNumber, String(node.address), String(node.address)); - this.chainConsensusCache[height][String(node.address)] = node.consensusCache[height]; + this.initialiseConsensusView(parseInt(height) as BlockNumber, String(node.id), String(node.address)); + this.chainConsensusCache[height][String(node.id)] = node.consensusCache[height]; } } diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 76b293de4..9ac1cae98 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -324,13 +324,12 @@ export default class Node { } } - public initialiseConsensusView(height: BlockNumber, id1_: string) { - let id1 = id1_; + public initialiseConsensusView(height: Types.BlockNumber, addr: Maybe) { if (!(height in this.consensusCache)) { this.consensusCache[height] = {}; } - if (!(id1 in this.consensusCache[height])) { - this.consensusCache[height][id1] = {} as Types.ConsensusInfo; + if (addr && !(addr in this.consensusCache[height])) { + this.consensusCache[height][addr] = {} as Types.ConsensusInfo; } } @@ -348,16 +347,15 @@ export default class Node { height: height, } = message; - let addr = String(this.address); - this.initialiseConsensusView(height as BlockNumber, addr); - this.consensusCache[height as BlockNumber][addr].FinalizedHash = best; + this.initialiseConsensusView(height as BlockNumber, this.address); + this.consensusCache[height as BlockNumber][String(this.address)].FinalizedHash = best; this.events.emit('consensus-info'); } public markFinalized(finalizedHeight: BlockNumber, finalizedHash: BlockHash) { let addr = String(this.address); - this.initialiseConsensusView(finalizedHeight, addr); + this.initialiseConsensusView(finalizedHeight, this.address); this.consensusCache[finalizedHeight][addr].Finalized = true; this.consensusCache[finalizedHeight][addr].FinalizedHash = finalizedHash; this.consensusCache[finalizedHeight][addr].FinalizedHeight = finalizedHeight; @@ -373,7 +371,7 @@ export default class Node { public markImplicitlyFinalized(finalizedHeight: BlockNumber) { let addr = String(this.address); - this.initialiseConsensusView(finalizedHeight, addr); + this.initialiseConsensusView(finalizedHeight, this.address); this.consensusCache[finalizedHeight][addr].Finalized = true; this.consensusCache[finalizedHeight][addr].FinalizedHeight = finalizedHeight; this.consensusCache[finalizedHeight][addr].ImplicitFinalized = true; @@ -402,8 +400,7 @@ export default class Node { target_number: targetNumber, target_hash: targetHash, } = message; - const voter = String(message.voter.replace(/"/g, '')); - + const voter = this.extractVoter(message.voter); this.initialiseConsensusView(targetNumber as BlockNumber, voter); this.consensusCache[targetNumber as BlockNumber][voter].Precommit = true; @@ -438,8 +435,7 @@ export default class Node { target_number: targetNumber, target_hash: targetHash, } = message; - const voter = String(message.voter.replace(/"/g, '')); - + const voter = this.extractVoter(message.voter); this.initialiseConsensusView(targetNumber as BlockNumber, voter); this.consensusCache[targetNumber as BlockNumber][voter].Prevote = true; @@ -485,28 +481,6 @@ export default class Node { } } - // fill the block cache back from the `to` number to the last block. - // the function `f` is used to evaluate if we should continue backfilling. - private backfill(voter_: string, to: BlockNumber, f: Maybe<(i: BlockNumber) => boolean>) { - // if this is the first block in the cache then we don't fill latter blocks - if (Object.keys(this.consensusCache).length < 1) { - return to; - } - - let cont = true; - while (cont && to-- > 0) { - if (this.consensusCache[to] !== undefined) { - // we reached the next block prior to this - return to; - } - - this.initialiseConsensusView(to, voter_); - cont = f ? f(to) : true; - } - - return to; - } - private onAfgFinalized(message: AfgFinalized) { const { finalized_number: finalizedNumber, @@ -516,17 +490,15 @@ export default class Node { this.markFinalized(finalizedNumber, finalizedHash); let to = finalizedNumber; - let addr = String(this.address); - this.backfill(addr, to as BlockNumber, (i) => { + this.backfill(this.address, to as BlockNumber, (i) => { i = i as BlockNumber; - let addr = String(this.address); - const info = this.consensusCache[i][addr]; + const info = this.consensusCache[i][String(this.address)]; if (info.Finalized || info.ImplicitFinalized) { return false; } this.markImplicitlyFinalized(i); - this.consensusCache[i][addr].ImplicitPointer = to; + this.consensusCache[i][String(this.address)].ImplicitPointer = to; let firstBlockReached = String(i) === Object.keys(this.consensusCache)[0]; if (!this.alreadyFinalized && firstBlockReached) { @@ -540,6 +512,36 @@ export default class Node { this.events.emit('consensus-info'); } + // fill the block cache back from the `to` number to the last block. + // the function `f` is used to evaluate if we should continue backfilling. + private backfill(voter: Maybe, to: BlockNumber, f: Maybe<(i: BlockNumber) => boolean>) { + if (!voter) { + return false; + } + + // if this is the first block in the cache then we don't fill latter blocks + if (Object.keys(this.consensusCache).length < 1) { + return to; + } + + let cont = true; + while (cont && to-- > 0) { + if (this.consensusCache[to] !== undefined) { + // we reached the next block prior to this + return to; + } + + this.initialiseConsensusView(to, voter); + cont = f ? f(to) : true; + } + + return to; + } + + private extractVoter(message_voter: String): Types.Address { + return String(message_voter.replace(/"/g, '')) as Types.Address; + } + private updateLatency(now: Types.Timestamp) { // if (this.pingStart) { // console.error(`${this.name} timed out on ping message.`); @@ -582,7 +584,7 @@ export default class Node { } const target = this.best.number as BlockNumber; - this.backfill(String(this.address), target, null); + this.backfill(this.address, target, null); } } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 95a27005a..d90bdd274 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -38,7 +38,7 @@ export declare type ConsensusInfo = { BlockNumber: ConsensusView; }; export declare type ConsensusView = { - Address: ConsensusState; + NodeId: ConsensusState; }; export declare type ConsensusState = { Address: ConsensusDetail; diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx index 677c46981..9deee5716 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -105,24 +105,24 @@ export class ConsensusBlock extends React.Component { } private isFinalized(node: Node): boolean { - const { address } = node; + const { address, id } = node; const consensus = this.props.consensusView; return consensus !== undefined && - address in consensus && - address in consensus[address] && - consensus[address][address].Finalized === true; + id in consensus && + address in consensus[id] && + consensus[id][address].Finalized === true; } private getFinalizedHash(node: Node): Types.BlockHash { - const { address } = node; + const { address, id } = node; const consensus = this.props.consensusView; if (consensus !== undefined && - address in consensus && - address in consensus[address] && - consensus[address][address].Finalized === true) { - return consensus[address][address].FinalizedHash; + id in consensus && + address in consensus[id] && + consensus[id][address].Finalized === true) { + return consensus[id][address].FinalizedHash; } return '' as Types.BlockHash; } @@ -132,7 +132,7 @@ export class ConsensusBlock extends React.Component { let finalizedHash; if (this.isFinalized(node)) { - const matrice = this.props.consensusView[node.address][node.address]; + const matrice = this.props.consensusView[node.id][node.address]; finalizedInfo = matrice.ImplicitFinalized ? @@ -196,9 +196,9 @@ export class ConsensusBlock extends React.Component { private getMatriceContent(rowNode: Node, columnNode: Node) { const consensusInfo = this.props.consensusView && - rowNode.address in this.props.consensusView && - columnNode.address in this.props.consensusView[rowNode.address] ? - this.props.consensusView[rowNode.address][columnNode.address] : null; + rowNode.id in this.props.consensusView && + columnNode.address in this.props.consensusView[rowNode.id] ? + this.props.consensusView[rowNode.id][columnNode.address] : null; let tooltipText = consensusInfo ? rowNode.name + ' has seen this of ' + columnNode.name + ': ' + From 672a33feb90a36d06c2c6b83c4a55739e882d971 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 09:24:12 +0200 Subject: [PATCH 09/50] Refactoring and improving naming --- packages/backend/src/Node.ts | 18 +++++++------- .../src/components/Consensus/Consensus.tsx | 24 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 9ac1cae98..7b104bb5e 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -386,15 +386,6 @@ export default class Node { this.consensusCache[finalizedHeight][addr].ImplicitPrecommit = true; } - private truncateBlockCache() { - let list = Object.keys(this.consensusCache).reverse(); - list.map((_, i) => { - if (i > MAX_BLOCKS_IN_NODE_CACHE) { - delete this.consensusCache[i]; - } - }); - } - private onAfgReceivedPrecommit(message: AfgReceivedPrecommit) { const { target_number: targetNumber, @@ -538,6 +529,15 @@ export default class Node { return to; } + private truncateBlockCache() { + let list = Object.keys(this.consensusCache).reverse(); + list.map((_, i) => { + if (i > MAX_BLOCKS_IN_NODE_CACHE) { + delete this.consensusCache[i]; + } + }); + } + private extractVoter(message_voter: String): Types.Address { return String(message_voter.replace(/"/g, '')) as Types.Address; } diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index 0265adb27..ff9656def 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -25,27 +25,27 @@ export class Consensus extends React.Component { largeBlockWithLegend: { width: -1, height: -1 }, largeBlock: { width: -1, height: -1 }, countBlocksInLargeRow: 2, - largeRowsFlexClassAdded: false, + largeRowsAddFlexClass: false, smallBlock: { width: -1, height: -1 }, smallBlocksRows: 1, countBlocksInSmallRow: 1, - smallRowsFlexClassAdded: false, + smallRowsAddFlexClass: false, }; - public initialBlockSizeSet(): boolean { + public largeBlocksSizeDetected(): boolean { return this.state.largeBlockWithLegend.width > -1 && this.state.largeBlockWithLegend.height > -1 && this.state.largeBlock.width > -1 && this.state.largeBlock.height > -1; } - public initialSmallBlockSizeSet(): boolean { + public smallBlocksSizeDetected(): boolean { return this.state.smallBlock.width > -1 && this.state.largeBlockWithLegend.height > -1; } public calculateBoxCount(wasResized: boolean) { // if the css class for flexing has already been added we don't calculate // any box measurements then, because the box sizes would be skewed then. - if ((wasResized || this.state.largeRowsFlexClassAdded === false) && this.initialBlockSizeSet()) { + if ((wasResized || this.state.largeRowsAddFlexClass === false) && this.largeBlocksSizeDetected()) { // we need to add +2 because of the last block which doesn't contain a border. let countBlocks = (this.state.dimensions.width - this.state.largeBlockWithLegend.width + 2) / (this.state.largeBlock.width + 2); @@ -56,10 +56,10 @@ export class Consensus extends React.Component { // which fit. countBlocks = Math.floor(countBlocks + 1) < 1 ? 2 : Math.floor(countBlocks + 1); - this.setState({largeRowsFlexClassAdded: true, countBlocksInLargeRow: countBlocks }); + this.setState({largeRowsAddFlexClass: true, countBlocksInLargeRow: countBlocks }); } - if ((wasResized || this.state.smallRowsFlexClassAdded === false) && this.initialSmallBlockSizeSet()) { + if ((wasResized || this.state.smallRowsAddFlexClass === false) && this.smallBlocksSizeDetected()) { const howManyRows = 2; const heightLeft = this.state.dimensions.height - (this.state.largeBlock.height * howManyRows); @@ -70,7 +70,7 @@ export class Consensus extends React.Component { let countBlocksInSmallRow = this.state.dimensions.width / this.state.smallBlock.width; countBlocksInSmallRow = countBlocksInSmallRow < 1 ? 1 : Math.floor(countBlocksInSmallRow); - this.setState({ smallRowsFlexClassAdded: true, countBlocksInSmallRow, smallBlocksRows }); + this.setState({ smallRowsAddFlexClass: true, countBlocksInSmallRow, smallBlocksRows }); } } @@ -139,7 +139,7 @@ export class Consensus extends React.Component { private getLargeRow(blocks: string[], id: number) { const largeBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { - if (this.initialBlockSizeSet()) { + if (this.largeBlocksSizeDetected()) { return; } if (isFirstBlock) { @@ -151,7 +151,7 @@ export class Consensus extends React.Component { const stretchLastRowMajor = blocks.length < this.state.countBlocksInLargeRow ? 'noStretchOnLastRow' : ''; - const flexClass = this.state.largeRowsFlexClassAdded ? 'flexContainerLargeRow' : ''; + const flexClass = this.state.largeRowsAddFlexClass ? 'flexContainerLargeRow' : ''; return
{ private getSmallRow(blocks: string[]) { const smallBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { - if (this.initialSmallBlockSizeSet()) { + if (this.smallBlocksSizeDetected()) { return; } const dimensionsChanged = this.state.smallBlock.height !== rect.height && @@ -186,7 +186,7 @@ export class Consensus extends React.Component { const stretchLastRow = blocks.length < this.state.countBlocksInSmallRow * this.state.smallBlocksRows ? 'noStretchOnLastRow' : ''; - const classes = `ConsensusList SmallRow ${this.state.smallRowsFlexClassAdded ? 'flexContainerSmallRow' : ''} ${stretchLastRow}`; + const classes = `ConsensusList SmallRow ${this.state.smallRowsAddFlexClass ? 'flexContainerSmallRow' : ''} ${stretchLastRow}`; return
{blocks.map((height, i) => { From e4b491627d7cc528ed20c54e2513df5e5a9ae9fa Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 09:36:32 +0200 Subject: [PATCH 10/50] Display boxes only after size has been detected This look a bit nicer, otherwise the UI will still adapt the box sizes once everything has already been loaded up. --- packages/frontend/src/components/Consensus/Consensus.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/frontend/src/components/Consensus/Consensus.css b/packages/frontend/src/components/Consensus/Consensus.css index 14e4eff3d..0a2cf21e1 100644 --- a/packages/frontend/src/components/Consensus/Consensus.css +++ b/packages/frontend/src/components/Consensus/Consensus.css @@ -1,3 +1,7 @@ +.ConsensusList { + opacity: 0; /* the box should only show up once flexing has been applied */ +} + .ConsensusList table { border-spacing: 0px; } @@ -6,6 +10,7 @@ display: flex; align-items: stretch; flex-direction: row; + opacity: 1.0; } .flexContainerLargeRow .firstInRow { @@ -24,6 +29,7 @@ align-items: stretch; flex-direction: row; flex-wrap: wrap; + opacity: 1.0; } .flexContainerSmallRow div { From b2253e0d7604f917ff8ebb71a1847501a589f021 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 09:58:17 +0200 Subject: [PATCH 11/50] Fix cache --- packages/backend/src/Chain.ts | 14 ++++++++++++-- packages/backend/src/Node.ts | 6 +++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 15324d9a8..da1bb418d 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -7,11 +7,10 @@ import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common'; import { BlockNumber, ConsensusInfo } from "@dotstats/common/build/types"; const BLOCK_TIME_HISTORY = 10; -const MAX_BLOCKS_IN_CHAIN_CACHE = 5; +const MAX_BLOCKS_IN_CHAIN_CACHE = 50; export default class Chain { private nodes = new Set(); - private chainConsensusCache: Types.ConsensusInfo = {} as ConsensusInfo; private lastBroadcastCache: Types.ConsensusInfo = {} as ConsensusInfo; private feeds = new FeedSet(); @@ -21,6 +20,7 @@ export default class Chain { public height = 0 as Types.BlockNumber; public finalized = Block.ZERO; public blockTimestamp = 0 as Types.Timestamp; + public chainConsensusCache: Types.ConsensusInfo = {} as ConsensusInfo; private blockTimes = new NumStats(BLOCK_TIME_HISTORY); private averageBlockTime: Maybe = null; @@ -203,6 +203,7 @@ export default class Chain { if (Object.keys(delta).length > 0 ) { this.feeds.broadcast(Feed.consensusInfo(delta)); + this.truncateChainConsensusCache(); } } @@ -216,6 +217,15 @@ export default class Chain { } } + private truncateChainConsensusCache() { + let list = Object.keys(this.chainConsensusCache).reverse(); + list.map((k, i) => { + if (i > MAX_BLOCKS_IN_CHAIN_CACHE) { + delete this.chainConsensusCache[k]; + } + }); + } + private restartVis() { this.nodes.forEach(node => node.resetCache()); this.feeds.broadcast(Feed.consensusInfo(this.chainConsensusCache)); diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 7b104bb5e..05b677a3b 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -23,7 +23,7 @@ const BLOCK_TIME_HISTORY = 10; const MEMORY_RECORDS = 20; const CPU_RECORDS = 20; const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute -const MAX_BLOCKS_IN_NODE_CACHE = 5; +const MAX_BLOCKS_IN_NODE_CACHE = 50; const nextId = idGenerator(); @@ -531,9 +531,9 @@ export default class Node { private truncateBlockCache() { let list = Object.keys(this.consensusCache).reverse(); - list.map((_, i) => { + list.map((k, i) => { if (i > MAX_BLOCKS_IN_NODE_CACHE) { - delete this.consensusCache[i]; + delete this.consensusCache[k]; } }); } From a3e9f06c0ee5ef8673f6a2e1bc904e7b6bb5e11a Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 09:58:12 +0200 Subject: [PATCH 12/50] Send consensus info on first subscribe So that frontend can immediately display the current state and doesn't have to aggregate first. --- packages/backend/src/Aggregator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend/src/Aggregator.ts b/packages/backend/src/Aggregator.ts index 45c69ac02..63e5443ac 100644 --- a/packages/backend/src/Aggregator.ts +++ b/packages/backend/src/Aggregator.ts @@ -34,6 +34,7 @@ export default class Aggregator { if (chain) { feed.sendMessage(Feed.subscribedTo(label)); + feed.sendMessage(Feed.consensusInfo(chain.chainConsensusCache)); chain.addFeed(feed); } }); From 4b5505bc29c2f62bfd89cc4e28114d2bce167711 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 10:00:26 +0200 Subject: [PATCH 13/50] Increase cache size --- packages/backend/src/Chain.ts | 2 +- packages/backend/src/Node.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index da1bb418d..898f5535f 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -7,7 +7,7 @@ import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common'; import { BlockNumber, ConsensusInfo } from "@dotstats/common/build/types"; const BLOCK_TIME_HISTORY = 10; -const MAX_BLOCKS_IN_CHAIN_CACHE = 50; +const MAX_BLOCKS_IN_CHAIN_CACHE = 100; export default class Chain { private nodes = new Set(); diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 05b677a3b..d6ffc505f 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -23,7 +23,7 @@ const BLOCK_TIME_HISTORY = 10; const MEMORY_RECORDS = 20; const CPU_RECORDS = 20; const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute -const MAX_BLOCKS_IN_NODE_CACHE = 50; +const MAX_BLOCKS_IN_NODE_CACHE = 100; const nextId = idGenerator(); From 5c48daaac2e53f1b611bc9c89777b8675f7ae405 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 10:20:53 +0200 Subject: [PATCH 14/50] Send deltas only if block in cache Otherwise the UI will update old blocks which are still visible to an empty shell. --- packages/backend/src/Chain.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 898f5535f..523f567ef 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -191,7 +191,14 @@ export default class Chain { // broadcast only the cache blocks which changed const delta: Types.ConsensusInfo = {} as ConsensusInfo; + const keys = Object.keys(this.chainConsensusCache); + const tip = keys[keys.length - 1]; for (let height in this.chainConsensusCache) { + const in_cache_range = parseInt(tip) - parseInt(height) < MAX_BLOCKS_IN_CHAIN_CACHE; + if (!in_cache_range) { + continue + } + const current = this.chainConsensusCache[height]; const old = this.lastBroadcastCache[height]; From 0623e5b673785b0cfa88ed87867db66c4c93c0a6 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 10:29:22 +0200 Subject: [PATCH 15/50] Adjust cache size --- packages/backend/src/Chain.ts | 2 +- packages/backend/src/Node.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 523f567ef..4aee4db56 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -7,7 +7,7 @@ import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common'; import { BlockNumber, ConsensusInfo } from "@dotstats/common/build/types"; const BLOCK_TIME_HISTORY = 10; -const MAX_BLOCKS_IN_CHAIN_CACHE = 100; +const MAX_BLOCKS_IN_CHAIN_CACHE = 50; export default class Chain { private nodes = new Set(); diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index d6ffc505f..05b677a3b 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -23,7 +23,7 @@ const BLOCK_TIME_HISTORY = 10; const MEMORY_RECORDS = 20; const CPU_RECORDS = 20; const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute -const MAX_BLOCKS_IN_NODE_CACHE = 100; +const MAX_BLOCKS_IN_NODE_CACHE = 50; const nextId = idGenerator(); From 064506a2ff211ddfedbfdd6fcbb8f19dc6bc7c39 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 10:47:31 +0200 Subject: [PATCH 16/50] Make cache sizes dependent --- packages/backend/src/Chain.ts | 2 +- packages/backend/src/Node.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 4aee4db56..a3fb1504f 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -7,7 +7,7 @@ import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common'; import { BlockNumber, ConsensusInfo } from "@dotstats/common/build/types"; const BLOCK_TIME_HISTORY = 10; -const MAX_BLOCKS_IN_CHAIN_CACHE = 50; +export const MAX_BLOCKS_IN_CHAIN_CACHE = 50; export default class Chain { private nodes = new Set(); diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 05b677a3b..93a8bc6c5 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -18,12 +18,13 @@ import { import { locate, Location } from './location'; import MeanList from './MeanList'; import Block from './Block'; +import { MAX_BLOCKS_IN_CHAIN_CACHE } from './Chain'; const BLOCK_TIME_HISTORY = 10; const MEMORY_RECORDS = 20; const CPU_RECORDS = 20; const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute -const MAX_BLOCKS_IN_NODE_CACHE = 50; +const MAX_BLOCKS_IN_NODE_CACHE = MAX_BLOCKS_IN_CHAIN_CACHE; const nextId = idGenerator(); From bde604a7416e05988c89fbbc65d24bd9ef06f4c8 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 8 Apr 2019 10:47:35 +0200 Subject: [PATCH 17/50] Ensure authority caches are aligned If only one authority has already submitted consensus info for a new block then the cache of that one is offset by one from all other authorities. --- packages/backend/src/Node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 93a8bc6c5..a9e29b384 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -533,7 +533,7 @@ export default class Node { private truncateBlockCache() { let list = Object.keys(this.consensusCache).reverse(); list.map((k, i) => { - if (i > MAX_BLOCKS_IN_NODE_CACHE) { + if (i > MAX_BLOCKS_IN_NODE_CACHE + 1) { delete this.consensusCache[k]; } }); From 5b590ba093aa88af14ea624e344f749ff1428f99 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 10 Apr 2019 14:19:22 +0200 Subject: [PATCH 18/50] Extract function --- packages/frontend/src/components/Consensus/Consensus.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index ff9656def..4dd708fbe 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -95,11 +95,6 @@ export class Consensus extends React.Component { } public render() { - const handleOnResize = (contentRect: ContentRect) => { - this.setState({ dimensions: contentRect.bounds as BoundingRect }); - this.calculateBoxCount(true); - }; - this.calculateBoxCount(false); const lastBlocks = Object.keys(this.props.appState.consensusInfo).reverse(); @@ -118,7 +113,7 @@ export class Consensus extends React.Component { return ( - + {({ measureRef }) => (
{firstLargeRow} From 062866ae4097d2a05a907fa4611a82934c978232 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 10 Apr 2019 14:15:26 +0200 Subject: [PATCH 19/50] Handle restarts on authority set changes properly --- packages/backend/src/Aggregator.ts | 1 - packages/backend/src/Chain.ts | 18 ++++++++++++------ packages/backend/src/Node.ts | 2 ++ packages/frontend/src/Connection.ts | 8 ++++++-- .../src/components/Consensus/Consensus.tsx | 4 ++++ 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/backend/src/Aggregator.ts b/packages/backend/src/Aggregator.ts index 63e5443ac..45c69ac02 100644 --- a/packages/backend/src/Aggregator.ts +++ b/packages/backend/src/Aggregator.ts @@ -34,7 +34,6 @@ export default class Aggregator { if (chain) { feed.sendMessage(Feed.subscribedTo(label)); - feed.sendMessage(Feed.consensusInfo(chain.chainConsensusCache)); chain.addFeed(feed); } }); diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index a3fb1504f..53ec415d1 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -25,6 +25,9 @@ export default class Chain { private blockTimes = new NumStats(BLOCK_TIME_HISTORY); private averageBlockTime: Maybe = null; + public lastBroadcastedAuthoritySetId: Types.AuthoritySetId = -1 as Types.AuthoritySetId; + public lastBroadcastedAuthoritySet: Types.Authorities = {} as Types.Authorities; + constructor(label: Types.ChainLabel) { this.label = label; } @@ -76,6 +79,9 @@ export default class Chain { feed.sendMessage(Feed.timeSync()); feed.sendMessage(Feed.bestBlock(this.height, this.blockTimestamp, this.averageBlockTime)); feed.sendMessage(Feed.bestFinalizedBlock(this.finalized)); + feed.sendMessage(Feed.authoritySet(this.lastBroadcastedAuthoritySet, + this.lastBroadcastedAuthoritySetId)); + feed.sendMessage(Feed.consensusInfo(this.chainConsensusCache)); for (const node of this.nodes.values()) { feed.sendMessage(Feed.addedNode(node)); @@ -215,12 +221,11 @@ export default class Chain { } private authoritySetChanged(node: Node, authorities: Types.Authorities, authoritySetId: Types.AuthoritySetId) { - if (node.isAuthority()) { + if (node.isAuthority() && authoritySetId !== this.lastBroadcastedAuthoritySetId) { this.feeds.broadcast(Feed.authoritySet(authorities, authoritySetId)); - - if (authoritySetId > 0) { - this.restartVis(); - } + this.lastBroadcastedAuthoritySetId = authoritySetId; + this.lastBroadcastedAuthoritySet = authorities; + this.restartVis(); } } @@ -235,8 +240,9 @@ export default class Chain { private restartVis() { this.nodes.forEach(node => node.resetCache()); - this.feeds.broadcast(Feed.consensusInfo(this.chainConsensusCache)); this.chainConsensusCache = {} as ConsensusInfo; + this.lastBroadcastCache = {} as ConsensusInfo; + this.feeds.broadcast(Feed.consensusInfo(this.chainConsensusCache)); } private updateAverageBlockTime(height: Types.BlockNumber, now: Types.Timestamp) { diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index a9e29b384..674c2e4bf 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -471,6 +471,8 @@ export default class Node { this.authoritySetId !== authoritySetId) { this.events.emit('authority-set-changed', authorities, authoritySetId, number, hash); } + + this.authorities = authorities; } private onAfgFinalized(message: AfgFinalized) { diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index c19a386a4..f4ca22dab 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -164,11 +164,15 @@ export class Connection { const receivedConsensusInfo = message.payload; const updatedConsensusInfo = JSON.parse(JSON.stringify(this.state.consensusInfo)); + if (Object.keys(receivedConsensusInfo).length === 0) { + this.state = this.update({ consensusInfo: {} as Types.ConsensusInfo }); + break; + } + for (const height of Object.keys(receivedConsensusInfo)) { updatedConsensusInfo[height] = receivedConsensusInfo[height]; } - - this.state = this.update({ consensusInfo: updatedConsensusInfo }); + this.state = this.update({consensusInfo: updatedConsensusInfo}); break; } diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index 4dd708fbe..4183d735a 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -78,6 +78,9 @@ export class Consensus extends React.Component { if (this.props.appState.authorities.length === 0 && nextProps.appState.authorities.length === 0) { return false; } + if (this.props.appState.nodes.sorted().length === 0 && nextProps.appState.nodes.sorted().length === 0) { + return false; + } const authoritiesDidChange = JSON.stringify(this.props.appState.authorities) !== JSON.stringify(nextProps.appState.authorities); @@ -127,6 +130,7 @@ export class Consensus extends React.Component { } private getAuthorities(): Node[] { + // find the node for each of these authority addresses return this.props.appState.authorities.map(address => this.props.appState.nodes.sorted() .filter(node => node.address === address)[0]); From a569f5449f731e44aa33b072162b4b62b3dde7c5 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 10 Apr 2019 14:16:25 +0200 Subject: [PATCH 20/50] Fix backfill mechanism --- packages/backend/src/Node.ts | 71 ++++++++----------- .../src/components/Consensus/Consensus.tsx | 5 ++ 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 674c2e4bf..bfb2e0631 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -74,10 +74,6 @@ export default class Node { // how this node views itself and others public consensusCache: ConsensusView = {} as ConsensusView; - private alreadyPrevote = false; - private alreadyPrecommit = false; - private alreadyFinalized = false; - private authorities: Types.Authorities = [] as Types.Authorities; private authoritySetId: Types.AuthoritySetId = 0 as Types.AuthoritySetId; @@ -406,18 +402,12 @@ export default class Node { } info.ImplicitPrecommit = true; - info.ImplicitPointer = to; - - let firstBlockReached = String(i) === Object.keys(this.consensusCache)[0]; - if (!this.alreadyPrecommit && firstBlockReached) { - this.alreadyPrecommit = true; - return false; - } + info.ImplicitPointer = from; return true; }; - const to = targetNumber as BlockNumber; - this.backfill(voter, to, mutate); + const from = targetNumber as BlockNumber; + this.backfill(voter, from, mutate); this.events.emit('consensus-info'); } @@ -431,8 +421,8 @@ export default class Node { this.initialiseConsensusView(targetNumber as BlockNumber, voter); this.consensusCache[targetNumber as BlockNumber][voter].Prevote = true; + const firstBlockNumber = Object.keys(this.consensusCache)[0]; const mutate = (i: BlockNumber) => { - // the function denotes when we stop backfilling the cache i = i as BlockNumber; const info = this.consensusCache[i][voter]; if (info.Prevote || info.ImplicitPrevote) { @@ -440,18 +430,12 @@ export default class Node { } this.consensusCache[i][voter].ImplicitPrevote = true; - this.consensusCache[i][voter].ImplicitPointer = to; - - let firstBlockReached = String(i) === Object.keys(this.consensusCache)[0]; - if (!this.alreadyPrevote && firstBlockReached) { - this.alreadyPrevote = true; - return false; - } + this.consensusCache[i][voter].ImplicitPointer = from; return true; }; - const to = targetNumber as BlockNumber; - this.backfill(voter, to, mutate); + const from = targetNumber as BlockNumber; + this.backfill(voter, from, mutate); this.events.emit('consensus-info'); } @@ -494,12 +478,6 @@ export default class Node { this.markImplicitlyFinalized(i); this.consensusCache[i][String(this.address)].ImplicitPointer = to; - let firstBlockReached = String(i) === Object.keys(this.consensusCache)[0]; - if (!this.alreadyFinalized && firstBlockReached) { - this.alreadyFinalized = true; - return false; - } - return true; }); @@ -508,28 +486,41 @@ export default class Node { // fill the block cache back from the `to` number to the last block. // the function `f` is used to evaluate if we should continue backfilling. - private backfill(voter: Maybe, to: BlockNumber, f: Maybe<(i: BlockNumber) => boolean>) { + // `f` returns false when backfilling the cache should be stopped, true to continue. + // + // returns block number until which we backfilled + private backfill(voter: Maybe, from: BlockNumber, f: Maybe<(i: BlockNumber) => boolean>): BlockNumber { if (!voter) { - return false; + return from; } // if this is the first block in the cache then we don't fill latter blocks - if (Object.keys(this.consensusCache).length < 1) { - return to; + if (Object.keys(this.consensusCache).length <= 1) { + return from; + } + + // if below this `from` there are not yet other blocks we don't create empty blocks + if (!this.consensusCache[from - 1]) { + return from; } + const firstBlockNumber = Object.keys(this.consensusCache)[0]; let cont = true; - while (cont && to-- > 0) { - if (this.consensusCache[to] !== undefined) { + while (cont && from-- > 0) { + if (this.consensusCache[from] !== undefined) { // we reached the next block prior to this - return to; + return from; } - this.initialiseConsensusView(to, voter); - cont = f ? f(to) : true; - } + this.initialiseConsensusView(from, voter); + cont = f ? f(from) : true; - return to; + let firstBlockReached = String(from) === firstBlockNumber; + if (firstBlockReached) { + break; + } + } + return from; } private truncateBlockCache() { diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index 4183d735a..994c2c239 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -129,6 +129,11 @@ export class Consensus extends React.Component { ); } + private handleOnResize = (contentRect: ContentRect) => { + this.setState({ dimensions: contentRect.bounds as BoundingRect }); + this.calculateBoxCount(true); + }; + private getAuthorities(): Node[] { // find the node for each of these authority addresses return this.props.appState.authorities.map(address => From 003aacee60c9ba6c608aad15cb04fbec648cf6a9 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 10 Apr 2019 15:57:17 +0200 Subject: [PATCH 21/50] Display only blocks since last authority set change --- packages/backend/src/Chain.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 53ec415d1..9baea2841 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -27,6 +27,7 @@ export default class Chain { public lastBroadcastedAuthoritySetId: Types.AuthoritySetId = -1 as Types.AuthoritySetId; public lastBroadcastedAuthoritySet: Types.Authorities = {} as Types.Authorities; + public authoritySetLastChangedAt: Types.BlockNumber = -1 as Types.BlockNumber; constructor(label: Types.ChainLabel) { this.label = label; @@ -48,7 +49,7 @@ export default class Chain { node.events.on('finalized', () => this.updateFinalized(node)); node.events.on('consensus-info', () => this.updateConsensusInfo(node)); node.events.on('authority-set-changed', (authorities, authoritySetId, blockNumber, blockHash) => - this.authoritySetChanged(node, authorities, authoritySetId)); + this.authoritySetChanged(node, authorities, authoritySetId, blockNumber, blockHash)); node.events.on('stats', () => this.feeds.broadcast(Feed.stats(node))); node.events.on('hardware', () => this.feeds.broadcast(Feed.hardware(node))); node.events.on('location', (location) => this.feeds.broadcast(Feed.locatedNode(node, location))); @@ -208,7 +209,10 @@ export default class Chain { const current = this.chainConsensusCache[height]; const old = this.lastBroadcastCache[height]; - if (JSON.stringify(current) !== JSON.stringify(old)) { + // only display blocks since the last authority set changed + const inRange = parseInt(height) > this.authoritySetLastChangedAt; + + if (JSON.stringify(current) !== JSON.stringify(old) && inRange) { delta[height] = current; this.lastBroadcastCache[height] = JSON.parse(JSON.stringify(current)); } @@ -220,11 +224,13 @@ export default class Chain { } } - private authoritySetChanged(node: Node, authorities: Types.Authorities, authoritySetId: Types.AuthoritySetId) { + private authoritySetChanged(node: Node, authorities: Types.Authorities, authoritySetId: Types.AuthoritySetId, + blockNumber: Types.BlockNumber, blockHash: Types.BlockHash) { if (node.isAuthority() && authoritySetId !== this.lastBroadcastedAuthoritySetId) { this.feeds.broadcast(Feed.authoritySet(authorities, authoritySetId)); this.lastBroadcastedAuthoritySetId = authoritySetId; this.lastBroadcastedAuthoritySet = authorities; + this.authoritySetLastChangedAt = blockNumber; this.restartVis(); } } From b3d3507e79bab8cb123a126bc7856bda78331ba0 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Fri, 12 Apr 2019 18:37:33 +0200 Subject: [PATCH 22/50] Handle authority set sent on connect When nodes lose their connection to telemetry or connect on first time they sent their current authority set for the UI to have something to display. These sets don't contain an explicit block number, because the set didn't change -- it just got resent. In this case the set is `undefined`. --- packages/backend/src/Chain.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 9baea2841..a99f06232 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -210,7 +210,8 @@ export default class Chain { const old = this.lastBroadcastCache[height]; // only display blocks since the last authority set changed - const inRange = parseInt(height) > this.authoritySetLastChangedAt; + const inRange = parseInt(height) > this.authoritySetLastChangedAt || + this.authoritySetLastChangedAt === undefined; if (JSON.stringify(current) !== JSON.stringify(old) && inRange) { delta[height] = current; From 03b3ae46dfaa70156ea38fec62ed8f5b5bd5b46d Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Fri, 12 Apr 2019 18:52:45 +0200 Subject: [PATCH 23/50] Introduce Authority type This is necessary to cover the case where one node connects, submits its authority set containing another node which has not yet connected to Telemetry. In this case we still want to create a shell object and fill it with the address. --- packages/common/src/types.ts | 5 ++ .../src/components/Consensus/Consensus.tsx | 14 ++-- .../components/Consensus/ConsensusBlock.tsx | 75 ++++++++++--------- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index d90bdd274..cf13533e3 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -32,6 +32,11 @@ export type NodeStats = [PeerCount, TransactionCount]; export type NodeHardware = [Array, Array, Array, Array, Array]; export type NodeLocation = [Latitude, Longitude, City]; +export declare type Authority = { + Address: Address, + NodeId: Maybe, + Name: Maybe, +}; export declare type Authorities = Array
; export declare type AuthoritySetId = Opaque; export declare type ConsensusInfo = { diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index 994c2c239..b92057ca6 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -3,7 +3,7 @@ import { Types } from '@dotstats/common'; import Measure, {BoundingRect, ContentRect} from 'react-measure'; import { ConsensusBlock } from './'; -import { State as AppState, Node } from '../../state'; +import { State as AppState } from '../../state'; import './Consensus.css'; @@ -134,11 +134,15 @@ export class Consensus extends React.Component { this.calculateBoxCount(true); }; - private getAuthorities(): Node[] { + private getAuthorities(): Types.Authority[] { // find the node for each of these authority addresses - return this.props.appState.authorities.map(address => - this.props.appState.nodes.sorted() - .filter(node => node.address === address)[0]); + return this.props.appState.authorities.map(address => { + const node2 = this.props.appState.nodes.sorted().filter(node => node.address === address)[0]; + if (!node2) { + return {Address: address, NodeId: null, Name: null} as Types.Authority; + } + return {Address: address, NodeId: node2.id, Name: node2.name} as Types.Authority; + }); } private getLargeRow(blocks: string[], id: number) { diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx index 9deee5716..2c779a25a 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -4,7 +4,6 @@ import Measure, {BoundingRect, ContentRect} from 'react-measure'; import { Types } from '@dotstats/common'; import Identicon from 'polkadot-identicon'; -import { Node } from '../../state'; import { Icon, Tooltip } from '../'; import Jdenticon from './Jdenticon'; @@ -16,7 +15,7 @@ import './ConsensusBlock.css'; export namespace ConsensusBlock { export interface Props { - authorities: Node[]; + authorities: Types.Authority[]; authoritySetId: Types.AuthoritySetId; authoritySetBlockNumber: Types.BlockNumber; height: Types.BlockNumber; @@ -44,7 +43,8 @@ export class ConsensusBlock extends React.Component { } public render() { - const finalizedByWhom = this.props.authorities.filter(node => this.isFinalized(node)); + const finalizedByWhom = this.props.authorities.filter(authority => this.isFinalized(authority)); + const ratio = finalizedByWhom.length + '/' + this.props.authorities.length; const tooltip = `${ratio} authorities finalized this block. Authority Set Id: ${this.props.authoritySetId}.`; let titleFinal = {ratio}; @@ -81,17 +81,17 @@ export class ConsensusBlock extends React.Component { {titleFinal} - {this.props.authorities.map(node => + {this.props.authorities.map(authority => - {this.getNodeContent(node, false)} + key={`${this.props.height}_matrice_x_${authority.Address}`}> + {this.getAuthorityContent(authority, false)} )} - {this.props.authorities.map((node, row) => - this.renderMatriceRow(node, this.props.authorities, row))} + {this.props.authorities.map((authority, row) => + this.renderMatriceRow(authority, this.props.authorities, row))}
)} @@ -104,21 +104,26 @@ export class ConsensusBlock extends React.Component { '…' + blockNumber.substr(blockNumber.length - 2, blockNumber.length) : blockNumber; } - private isFinalized(node: Node): boolean { - const { address, id } = node; + private isFinalized(authority: Types.Authority): boolean { + if (!authority || authority.NodeId === null || authority.Address === null) { + return false; + } + + const { Address: address, NodeId: id } = authority; const consensus = this.props.consensusView; return consensus !== undefined && - id in consensus && - address in consensus[id] && - consensus[id][address].Finalized === true; + String(id) in consensus && + address in consensus[String(id)] && + consensus[String(id)][address].Finalized === true; } - private getFinalizedHash(node: Node): Types.BlockHash { - const { address, id } = node; + private getFinalizedHash(authority: Types.Authority): Types.BlockHash { + const { Address: address , NodeId: id } = authority; const consensus = this.props.consensusView; if (consensus !== undefined && + id != null && id in consensus && address in consensus[id] && consensus[id][address].Finalized === true) { @@ -127,18 +132,19 @@ export class ConsensusBlock extends React.Component { return '' as Types.BlockHash; } - private renderMatriceRow(node: Node, authorities: Node[], row: number): JSX.Element { + private renderMatriceRow(authority: Types.Authority, authorities: Types.Authority[], row: number): JSX.Element { let finalizedInfo =  ; let finalizedHash; - if (this.isFinalized(node)) { - const matrice = this.props.consensusView[node.id][node.address]; + if (authority.NodeId !== null && authority.NodeId !== undefined && this.isFinalized(authority)) { + const matrice = this.props.consensusView[String(authority.NodeId)][authority.Address]; + finalizedInfo = matrice.ImplicitFinalized ? - + : - + @@ -148,27 +154,27 @@ export class ConsensusBlock extends React.Component { :
 
; } - const firstName = this.props.firstInRow ? {node.name} : ''; + const firstName = this.props.firstInRow ? {authority.Name} : ''; return {firstName} - {this.getNodeContent(node, true)} + {this.getAuthorityContent(authority, true)} {finalizedInfo}{finalizedHash} { authorities.map((columnNode, column) => { const evenOdd = ((row % 2) + column) % 2 === 0 ? 'even' : 'odd'; - return {this.getMatriceContent(node, columnNode)} + return {this.getMatriceContent(authority, columnNode)} }) } ; } - private getNodeContent(node: Node, nodeName: boolean): JSX.Element { + private getAuthorityContent(authority: Types.Authority, nodeName: boolean): JSX.Element { return
- - + +
; @@ -194,17 +200,18 @@ export class ConsensusBlock extends React.Component { return txt.join(', '); // + JSON.stringify((consensusDetail)); } - private getMatriceContent(rowNode: Node, columnNode: Node) { + private getMatriceContent(rowAuthority: Types.Authority, columnAuthority: Types.Authority) { const consensusInfo = this.props.consensusView && - rowNode.id in this.props.consensusView && - columnNode.address in this.props.consensusView[rowNode.id] ? - this.props.consensusView[rowNode.id][columnNode.address] : null; + String(rowAuthority.NodeId) && + String(rowAuthority.NodeId) in this.props.consensusView && + columnAuthority.Address in this.props.consensusView[String(rowAuthority.NodeId)] ? + this.props.consensusView[String(rowAuthority.NodeId)][columnAuthority.Address] : null; let tooltipText = consensusInfo ? - rowNode.name + ' has seen this of ' + columnNode.name + ': ' + + rowAuthority.Name + ' has seen this of ' + columnAuthority.Name + ': ' + this.format(consensusInfo) : 'No information available yet.'; - if (rowNode.address === columnNode.address) { + if (rowAuthority.Address === columnAuthority.Address) { tooltipText = 'Self-referential.'; } @@ -214,7 +221,7 @@ export class ConsensusBlock extends React.Component { const precommit = consensusInfo && consensusInfo.Precommit; const implicitPrecommit = consensusInfo && consensusInfo.ImplicitPrecommit; - if (rowNode.address !== columnNode.address) { + if (rowAuthority.Address !== columnAuthority.Address) { let statPrevote; let statPrecommit; From fdc86c59f5592bc99d28a71910dfd1efafed7aa6 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 15 Apr 2019 12:06:52 +0200 Subject: [PATCH 24/50] Handle corner case In the case of only one block having been produced, two authorities, and only one authority connected, the UI did not show up. --- .../src/components/Consensus/Consensus.tsx | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index b92057ca6..bc0af7896 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -14,6 +14,16 @@ export namespace Consensus { export interface State { dimensions: BoundingRect; + + largeBlockWithLegend: BoundingRect, + largeBlock: BoundingRect, + countBlocksInLargeRow: number, + largeRowsAddFlexClass: boolean, + + smallBlock: BoundingRect, + smallBlocksRows: number, + countBlocksInSmallRow: number, + smallRowsAddFlexClass: boolean, } } @@ -22,30 +32,37 @@ export class Consensus extends React.Component { // entire area available for rendering the visualization dimensions: { width: -1, height: -1 } as BoundingRect, - largeBlockWithLegend: { width: -1, height: -1 }, - largeBlock: { width: -1, height: -1 }, + largeBlockWithLegend: { width: -1, height: -1 } as BoundingRect, + largeBlock: { width: -1, height: -1 } as BoundingRect, countBlocksInLargeRow: 2, largeRowsAddFlexClass: false, - smallBlock: { width: -1, height: -1 }, + smallBlock: { width: -1, height: -1 } as BoundingRect, smallBlocksRows: 1, countBlocksInSmallRow: 1, smallRowsAddFlexClass: false, }; - public largeBlocksSizeDetected(): boolean { - return this.state.largeBlockWithLegend.width > -1 && this.state.largeBlockWithLegend.height > -1 && - this.state.largeBlock.width > -1 && this.state.largeBlock.height > -1; + public largeBlocksSizeDetected(state: Consensus.State): boolean { + const countBlocks = Object.keys(this.props.appState.consensusInfo).length; + if (countBlocks === 1) { + return state.largeBlockWithLegend.width > -1 && state.largeBlockWithLegend.height > -1; + } + + // if there is more than one block then the size of the first block (with legend) + // will be different from the succeeding blocks (without legend) + return state.largeBlockWithLegend.width > -1 && state.largeBlockWithLegend.height > -1 && + state.largeBlock.width > -1 && state.largeBlock.height > -1; } - public smallBlocksSizeDetected(): boolean { - return this.state.smallBlock.width > -1 && this.state.largeBlockWithLegend.height > -1; + public smallBlocksSizeDetected(state: Consensus.State): boolean { + return state.smallBlock.width > -1 && state.largeBlockWithLegend.height > -1; } public calculateBoxCount(wasResized: boolean) { // if the css class for flexing has already been added we don't calculate // any box measurements then, because the box sizes would be skewed then. - if ((wasResized || this.state.largeRowsAddFlexClass === false) && this.largeBlocksSizeDetected()) { + if ((wasResized || this.state.largeRowsAddFlexClass === false) && this.largeBlocksSizeDetected(this.state)) { // we need to add +2 because of the last block which doesn't contain a border. let countBlocks = (this.state.dimensions.width - this.state.largeBlockWithLegend.width + 2) / (this.state.largeBlock.width + 2); @@ -59,7 +76,7 @@ export class Consensus extends React.Component { this.setState({largeRowsAddFlexClass: true, countBlocksInLargeRow: countBlocks }); } - if ((wasResized || this.state.smallRowsAddFlexClass === false) && this.smallBlocksSizeDetected()) { + if ((wasResized || this.state.smallRowsAddFlexClass === false) && this.smallBlocksSizeDetected(this.state)) { const howManyRows = 2; const heightLeft = this.state.dimensions.height - (this.state.largeBlock.height * howManyRows); @@ -93,8 +110,14 @@ export class Consensus extends React.Component { const windowSizeChanged = JSON.stringify(this.state.dimensions) !== JSON.stringify(nextState.dimensions); + // size detected, but flex class has not yet been added + const largeBlocksSizeDetected = this.largeBlocksSizeDetected(nextState) === true && + this.state.largeRowsAddFlexClass === false; + const smallBlocksSizeDetected = this.smallBlocksSizeDetected(nextState) === true && + this.state.smallRowsAddFlexClass === false; + return authoritiesDidChange || authoritySetIdDidChange || newConsensusInfoAvailable || - windowSizeChanged; + windowSizeChanged || largeBlocksSizeDetected || smallBlocksSizeDetected; } public render() { @@ -147,7 +170,7 @@ export class Consensus extends React.Component { private getLargeRow(blocks: string[], id: number) { const largeBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { - if (this.largeBlocksSizeDetected()) { + if (this.largeBlocksSizeDetected(this.state)) { return; } if (isFirstBlock) { @@ -182,7 +205,7 @@ export class Consensus extends React.Component { private getSmallRow(blocks: string[]) { const smallBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { - if (this.smallBlocksSizeDetected()) { + if (this.smallBlocksSizeDetected(this.state)) { return; } const dimensionsChanged = this.state.smallBlock.height !== rect.height && From b8d689bd93b91406707cbbe373dbf87a290471b2 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 15 Apr 2019 12:07:47 +0200 Subject: [PATCH 25/50] Display placeholder if name not yet available --- packages/frontend/src/components/Consensus/ConsensusBlock.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx index 2c779a25a..39d2e9b52 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -154,7 +154,8 @@ export class ConsensusBlock extends React.Component {
:
 
; } - const firstName = this.props.firstInRow ? {authority.Name} : ''; + const name = authority.Name ? {authority.Name} : no name received yet; + const firstName = this.props.firstInRow ? {name} : ''; return {firstName} From 0a0acce953b1693e545b3ddd1ccbb57ad8791264 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 23 Apr 2019 09:46:02 +0200 Subject: [PATCH 26/50] Replace with camelCase --- packages/backend/src/Chain.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index a99f06232..d887d8d1e 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -201,8 +201,8 @@ export default class Chain { const keys = Object.keys(this.chainConsensusCache); const tip = keys[keys.length - 1]; for (let height in this.chainConsensusCache) { - const in_cache_range = parseInt(tip) - parseInt(height) < MAX_BLOCKS_IN_CHAIN_CACHE; - if (!in_cache_range) { + const inCacheRange = parseInt(tip) - parseInt(height) < MAX_BLOCKS_IN_CHAIN_CACHE; + if (!inCacheRange) { continue } From 23c254e174f2c04e33913da38e2859bb70f18809 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 6 May 2019 10:03:26 +0200 Subject: [PATCH 27/50] Replace with correct types --- packages/common/src/types.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index cf13533e3..3381794dd 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -39,15 +39,9 @@ export declare type Authority = { }; export declare type Authorities = Array
; export declare type AuthoritySetId = Opaque; -export declare type ConsensusInfo = { - BlockNumber: ConsensusView; -}; -export declare type ConsensusView = { - NodeId: ConsensusState; -}; -export declare type ConsensusState = { - Address: ConsensusDetail; -}; +export declare type ConsensusInfo = Map; +export declare type ConsensusView = Map; +export declare type ConsensusState = Map; export declare type ConsensusDetail = { Precommit: Precommit; ImplicitPrecommit: ImplicitPrecommit; From 44bf2a56f0e9bf4e996d9817fc7ad858ad7e2e63 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 6 May 2019 10:09:54 +0200 Subject: [PATCH 28/50] Replace grandpa icon --- README.md | 4 - .../frontend/src/components/Chain/Chain.tsx | 2 +- packages/frontend/src/icons/grandpa.svg | 74 ------------------- 3 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 packages/frontend/src/icons/grandpa.svg diff --git a/README.md b/README.md index ecaed67b5..6762f4867 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,3 @@ docker-compose up --build -d - If you want to makes UI changes, there is no need to rebuild the image as the files are being copied in via volumes. Now navigate to localhost:3000 in your browser to view the app. - -## Attributions - -The [Grandpa icon](https://thenounproject.com/term/bald/1737132/) is by Cezary Lopacinski from the Noun Project diff --git a/packages/frontend/src/components/Chain/Chain.tsx b/packages/frontend/src/components/Chain/Chain.tsx index de25ba7d9..54c8e2b1b 100644 --- a/packages/frontend/src/components/Chain/Chain.tsx +++ b/packages/frontend/src/components/Chain/Chain.tsx @@ -13,7 +13,7 @@ import lastTimeIcon from '../../icons/watch.svg'; import listIcon from '../../icons/list-alt-regular.svg'; import worldIcon from '../../icons/location.svg'; import settingsIcon from '../../icons/settings.svg'; -import consensusIcon from '../../icons/grandpa.svg'; +import consensusIcon from '../../icons/comment-discussion.svg'; import './Chain.css'; diff --git a/packages/frontend/src/icons/grandpa.svg b/packages/frontend/src/icons/grandpa.svg deleted file mode 100644 index 218bfebee..000000000 --- a/packages/frontend/src/icons/grandpa.svg +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - From 3a6427a6db3d05e65f1e615459f4b4e21123d2b7 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 13 May 2019 12:46:45 +0200 Subject: [PATCH 29/50] Change consensus icon to cube (finalized block icon) --- packages/frontend/src/components/Chain/Chain.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/Chain/Chain.tsx b/packages/frontend/src/components/Chain/Chain.tsx index 54c8e2b1b..af0012089 100644 --- a/packages/frontend/src/components/Chain/Chain.tsx +++ b/packages/frontend/src/components/Chain/Chain.tsx @@ -13,7 +13,7 @@ import lastTimeIcon from '../../icons/watch.svg'; import listIcon from '../../icons/list-alt-regular.svg'; import worldIcon from '../../icons/location.svg'; import settingsIcon from '../../icons/settings.svg'; -import consensusIcon from '../../icons/comment-discussion.svg'; +import consensusIcon from '../../icons/cube-alt.svg'; import './Chain.css'; From bf4d9ea48b3417860ccf40f0c5122027ffc59689 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 15 May 2019 15:13:47 +0200 Subject: [PATCH 30/50] Upgrade dependencies --- package-lock.json | 799 ++++++++++++++++++++++++++++++++- package.json | 3 + packages/frontend/package.json | 2 +- yarn.lock | 244 +++++++--- 4 files changed, 983 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62ca6a70c..4fc2c77a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,4 +1,801 @@ { "version": "0.1.0", - "lockfileVersion": 1 + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/runtime": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz", + "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, + "@polkadot/util": { + "version": "0.41.1", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-0.41.1.tgz", + "integrity": "sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ==", + "requires": { + "@babel/runtime": "^7.4.0", + "@types/bn.js": "^4.11.4", + "@types/deasync": "^0.1.0", + "@types/ip-regex": "^3.0.0", + "bn.js": "^4.11.8", + "camelcase": "^5.2.0", + "chalk": "^2.4.2", + "ip-regex": "^4.0.0", + "moment": "^2.24.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "ip-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", + "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==" + } + } + }, + "@polkadot/wasm-crypto": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz", + "integrity": "sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg==" + }, + "@polkadot/wasm-schnorrkel": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz", + "integrity": "sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA==" + }, + "@types/bn.js": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", + "integrity": "sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng==", + "requires": { + "@types/node": "*" + } + }, + "@types/deasync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@types/deasync/-/deasync-0.1.0.tgz", + "integrity": "sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA==" + }, + "@types/ip-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/ip-regex/-/ip-regex-3.0.0.tgz", + "integrity": "sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw==" + }, + "@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "base-x": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", + "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip39": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", + "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "blake2js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/blake2js/-/blake2js-1.0.0.tgz", + "integrity": "sha1-tokMOU3blAXQbZp6089lZxHcrYk=", + "requires": { + "bindings": "^1.2.1", + "debug": "^2.2.0", + "nan": "^2.4.0", + "readable-stream": "^2.1.4" + } + }, + "blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "canvas-renderer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/canvas-renderer/-/canvas-renderer-2.1.1.tgz", + "integrity": "sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "change-case": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", + "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", + "requires": { + "camel-case": "^3.0.0", + "constant-case": "^2.0.0", + "dot-case": "^2.1.0", + "header-case": "^1.0.0", + "is-lower-case": "^1.1.0", + "is-upper-case": "^1.1.0", + "lower-case": "^1.1.1", + "lower-case-first": "^1.0.0", + "no-case": "^2.3.2", + "param-case": "^2.1.0", + "pascal-case": "^2.0.0", + "path-case": "^2.1.0", + "sentence-case": "^2.1.0", + "snake-case": "^2.1.0", + "swap-case": "^1.1.0", + "title-case": "^2.1.0", + "upper-case": "^1.1.1", + "upper-case-first": "^1.1.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "constant-case": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", + "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", + "requires": { + "snake-case": "^2.1.0", + "upper-case": "^1.1.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "dot-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", + "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", + "requires": { + "no-case": "^2.2.0" + } + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "header-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", + "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.3" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "requires": { + "lower-case": "^1.1.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "requires": { + "upper-case": "^1.1.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "jdenticon": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jdenticon/-/jdenticon-2.1.1.tgz", + "integrity": "sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg==", + "requires": { + "canvas-renderer": "~2.1.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "lower-case-first": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", + "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", + "requires": { + "lower-case": "^1.1.2" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "oo7": { + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/oo7/-/oo7-0.7.12.tgz", + "integrity": "sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA==" + }, + "oo7-react": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/oo7-react/-/oo7-react-0.8.13.tgz", + "integrity": "sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q==", + "requires": { + "oo7": "^0.7.12", + "react": "^16.5.2" + }, + "dependencies": { + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + } + } + }, + "oo7-substrate": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/oo7-substrate/-/oo7-substrate-0.8.0.tgz", + "integrity": "sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA==", + "requires": { + "@polkadot/util": "^0.41.1", + "@polkadot/wasm-crypto": "^0.5.1", + "@polkadot/wasm-schnorrkel": "^0.3.1", + "base-x": "^3.0.4", + "bip39": "^2.5.0", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "buffer": "^5.2.1", + "change-case": "^3.0.2", + "isomorphic-fetch": "^2.2.1", + "isomorphic-ws": "^4.0.1", + "jdenticon": "^2.1.1", + "oo7": "^0.7.12", + "pbkdf2": "^3.0.17", + "ss58": "^1.0.2", + "text-encoding": "^0.7.0", + "text-encoding-polyfill": "^0.6.7", + "tweetnacl": "^1.0.0", + "ws": "^6.1.2", + "xxhashjs": "^0.2.2" + }, + "dependencies": { + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "tweetnacl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", + "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" + } + } + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "requires": { + "no-case": "^2.2.0" + } + }, + "pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "requires": { + "camel-case": "^3.0.0", + "upper-case-first": "^1.1.0" + } + }, + "path-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", + "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", + "requires": { + "no-case": "^2.2.0" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "polkadot-identicon": { + "version": "1.1.45", + "resolved": "https://registry.npmjs.org/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz", + "integrity": "sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w==", + "requires": { + "blake2js": "^1.0.0", + "oo7": "^0.7.12", + "oo7-react": "^0.8.13", + "oo7-substrate": "^0.8.0", + "react": "^16.4.2", + "ss58": "^1.0.0" + }, + "dependencies": { + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + } + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + } + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "sentence-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", + "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", + "requires": { + "no-case": "^2.2.0", + "upper-case-first": "^1.1.2" + } + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "snake-case": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", + "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", + "requires": { + "no-case": "^2.2.0" + } + }, + "ss58": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ss58/-/ss58-1.0.2.tgz", + "integrity": "sha512-hCpPJ12+GgsYsyVW2dXY6p3KfqZgLFA9zrKp5cgEx3x93JjPG4DDm6lu0Zp87FW0CSRan3gy7jlF4ZCjHqS7Ig==", + "requires": { + "blakejs": "^1.1.0", + "bs58": "^4.0.1" + } + }, + "swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "requires": { + "lower-case": "^1.1.1", + "upper-case": "^1.1.1" + } + }, + "text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, + "text-encoding-polyfill": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/text-encoding-polyfill/-/text-encoding-polyfill-0.6.7.tgz", + "integrity": "sha512-/DZ1XJqhbqRkCop6s9ZFu8JrFRwmVuHg4quIRm+ziFkR3N3ec6ck6yBvJ1GYeEQZhLVwRW0rZE+C3SSJpy0RTg==" + }, + "title-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", + "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.0.3" + } + }, + "unorm": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.5.0.tgz", + "integrity": "sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw==" + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "requires": { + "upper-case": "^1.1.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "requires": { + "cuint": "^0.2.2" + } + } + } } diff --git a/package.json b/package.json index 443ac9c8c..1a2e3e975 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,8 @@ "build:common": "tsc -p packages/common", "check:common": "tsc -p packages/common --noEmit", "test": "scripts/test.sh" + }, + "dependencies": { + "polkadot-identicon": "^1.1.45" } } diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 1e674a330..83feed4df 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -21,7 +21,7 @@ "dependencies": { "@fnando/sparkline": "maciejhirsz/sparkline", "@types/react-measure": "^2.0.5", - "polkadot-identicon": "^1.1.36", + "polkadot-identicon": "^1.1.45", "react": "16.4.0", "react-dom": "16.4.0", "react-measure": "^2.2.4", diff --git a/yarn.lock b/yarn.lock index 2a59eec27..72af375c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,15 +25,54 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.4.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d" + integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg== + dependencies: + regenerator-runtime "^0.13.2" + "@fnando/sparkline@maciejhirsz/sparkline": version "0.3.10" resolved "https://codeload.github.com/maciejhirsz/sparkline/tar.gz/2bdb002b171436be078a84f1e4e617a44ef1fb42" +"@polkadot/util@^0.41.1": + version "0.41.1" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.41.1.tgz#b67762a0a7408138d843adc7240944e704e819e7" + integrity sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ== + dependencies: + "@babel/runtime" "^7.4.0" + "@types/bn.js" "^4.11.4" + "@types/deasync" "^0.1.0" + "@types/ip-regex" "^3.0.0" + bn.js "^4.11.8" + camelcase "^5.2.0" + chalk "^2.4.2" + ip-regex "^4.0.0" + moment "^2.24.0" + +"@polkadot/wasm-crypto@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz#3d5734d6dc2f5174a411689f78538287d21bd710" + integrity sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg== + +"@polkadot/wasm-schnorrkel@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz#08287848f769dee4955517348905888bd289f277" + integrity sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA== + "@tanem/svg-injector@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@tanem/svg-injector/-/svg-injector-1.2.1.tgz#3120e90246d0eb3c4fc6c61586a6f028a3c658ae" integrity sha512-mA5Q5ulPoGQ+e08Vts1R6xw2QU0BKEnMH/KcqoYoS7Gk6imvMTpyFPeu1g+NOZObSIoAzA3/kRzY8m96cEBA2A== +"@types/bn.js@^4.11.4": + version "4.11.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc" + integrity sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng== + dependencies: + "@types/node" "*" + "@types/body-parser@*": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -49,6 +88,11 @@ dependencies: "@types/node" "*" +"@types/deasync@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@types/deasync/-/deasync-0.1.0.tgz#b2bd6c3fcde3cf67b8be4c2f70136ba8f157b45a" + integrity sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -72,6 +116,11 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" +"@types/ip-regex@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/ip-regex/-/ip-regex-3.0.0.tgz#f06748a44dd47810bb24555958b4b410cfe5abab" + integrity sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw== + "@types/jest@^23.0.2": version "23.3.12" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.12.tgz#7e0ced251fa94c3bc2d1023d4b84b2992fa06376" @@ -87,7 +136,12 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== -"@types/node@*", "@types/node@^10.3.2", "@types/node@^10.3.3": +"@types/node@*": + version "12.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.2.tgz#3452a24edf9fea138b48fad4a0a028a683da1e40" + integrity sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA== + +"@types/node@^10.3.2", "@types/node@^10.3.3": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== @@ -1365,14 +1419,16 @@ binary-extensions@^1.0.0: integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== bindings@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5" - integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew== + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" bip39@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" - integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== + version "2.6.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c" + integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg== dependencies: create-hash "^1.1.0" pbkdf2 "^3.0.9" @@ -1400,7 +1456,7 @@ bluebird@^3.4.7, bluebird@^3.5.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== @@ -1634,6 +1690,14 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1724,6 +1788,11 @@ camelcase@^4.0.0, camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelcase@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -1744,6 +1813,11 @@ caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.300008 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000929.tgz#7b391b781a9c3097ecc39ea053301aea8ea16317" integrity sha512-n2w1gPQSsYyorSVYqPMqbSaz1w7o9ZC8VhOEGI9T5MfGDzp7sbopQxG6GaQmYsaq13Xfx/mkxJUWC1Dz3oZfzw== +canvas-renderer@~2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/canvas-renderer/-/canvas-renderer-2.1.1.tgz#d91fe9511ab48056ff9fa8a04514bede76535f55" + integrity sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw== + capture-exit@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" @@ -1785,7 +1859,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3391,6 +3465,11 @@ file-loader@0.11.2: dependencies: loader-utils "^1.0.2" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -4125,9 +4204,9 @@ icss-utils@^2.1.0: postcss "^6.0.1" ieee754@^1.1.4: - version "1.1.12" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" - integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== iferr@^0.1.5: version "0.1.5" @@ -4256,6 +4335,11 @@ ip-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-3.0.0.tgz#0a934694b4066558c46294244a23cc33116bf732" integrity sha512-T8wDtjy+Qf2TAPDQmBp0eGKJ8GavlWlUnamr3wRn6vvdZlKVuJXXMlSncYFRYgVHOM3If5NR1H4+OvVQU9Idvg== +ip-regex@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.1.0.tgz#5ad62f685a14edb421abebc2fff8db94df67b455" + integrity sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA== + ip-validator@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/ip-validator/-/ip-validator-0.0.1.tgz#659eb6001d38c35beab51455a2f751b843299eb5" @@ -4749,6 +4833,13 @@ istanbul-reports@^1.5.1: dependencies: handlebars "^4.0.3" +jdenticon@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/jdenticon/-/jdenticon-2.1.1.tgz#f9288e87b3466e2c5f05948c68db58e1c9e1b800" + integrity sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg== + dependencies: + canvas-renderer "~2.1.1" + jest-changed-files@^22.2.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.4.3.tgz#8882181e022c38bd46a2e4d18d44d19d90a90fb2" @@ -5751,7 +5842,7 @@ longest@^1.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -6069,6 +6160,11 @@ mock-socket@^8.0.2: dependencies: url-parse "^1.2.0" +moment@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + moo@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" @@ -6114,7 +6210,12 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.4.0, nan@^2.9.2: +nan@^2.4.0: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nan@^2.9.2: version "2.12.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== @@ -6473,27 +6574,33 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -oo7-react@^0.8.10: - version "0.8.10" - resolved "https://registry.yarnpkg.com/oo7-react/-/oo7-react-0.8.10.tgz#c04bd418d87f3b5bd32949cefb116eee5a4bb86c" - integrity sha512-kLP9umZt5StkWlZ2TahDIMTg9umsPzMFeXoIi5ClujwrQD+2uRqLaYWiPDprzYlSMpOZgQ0oqZtBW6tUCdG8GA== +oo7-react@^0.8.13: + version "0.8.13" + resolved "https://registry.yarnpkg.com/oo7-react/-/oo7-react-0.8.13.tgz#fbc63eac0397d72a1a5d768481fbbda533503e2e" + integrity sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q== dependencies: - oo7 "^0.7.9" + oo7 "^0.7.12" react "^16.5.2" -oo7-substrate@^0.4.12: - version "0.4.12" - resolved "https://registry.yarnpkg.com/oo7-substrate/-/oo7-substrate-0.4.12.tgz#f27ffa10b0143e75ba2677ddbebbaf9aa5096078" - integrity sha512-oz0UePdDViE8y9oLgWBImwhIRkElcaqHmG9dIAnHd12O1FPWGos1LHeDSKVblXfvtiAs18n2OMe5JJTNBGd6yQ== +oo7-substrate@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/oo7-substrate/-/oo7-substrate-0.8.0.tgz#690a6ec145287ae0cbb5647146f3ce76a8a28ff3" + integrity sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA== dependencies: + "@polkadot/util" "^0.41.1" + "@polkadot/wasm-crypto" "^0.5.1" + "@polkadot/wasm-schnorrkel" "^0.3.1" base-x "^3.0.4" bip39 "^2.5.0" blakejs "^1.1.0" bs58 "^4.0.1" + buffer "^5.2.1" change-case "^3.0.2" isomorphic-fetch "^2.2.1" isomorphic-ws "^4.0.1" - oo7 "^0.7.9" + jdenticon "^2.1.1" + oo7 "^0.7.12" + pbkdf2 "^3.0.17" ss58 "^1.0.2" text-encoding "^0.7.0" text-encoding-polyfill "^0.6.7" @@ -6501,10 +6608,10 @@ oo7-substrate@^0.4.12: ws "^6.1.2" xxhashjs "^0.2.2" -oo7@^0.7.9: - version "0.7.9" - resolved "https://registry.yarnpkg.com/oo7/-/oo7-0.7.9.tgz#ea9c14121fd3a24934b12d58b5f2a185a9609059" - integrity sha512-QcK4x8xY+rZeBBqS1HDe+kyf0g1XEdiqXcEIJl7dBxau+ICU8bGdcJ+d+POMj8/fRH6o9oyaIe2QujytxzERLg== +oo7@^0.7.12: + version "0.7.12" + resolved "https://registry.yarnpkg.com/oo7/-/oo7-0.7.12.tgz#bd7a01ba4e815c1fcde9bea2a9a8226d06ec781e" + integrity sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA== opn@5.2.0: version "5.2.0" @@ -6792,7 +6899,7 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -pbkdf2@^3.0.3, pbkdf2@^3.0.9: +pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== @@ -6847,15 +6954,15 @@ pn@^1.1.0: resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== -polkadot-identicon@^1.1.36: - version "1.1.36" - resolved "https://registry.yarnpkg.com/polkadot-identicon/-/polkadot-identicon-1.1.36.tgz#ef14ebdc788367b20acf05a1613c806211fd44d0" - integrity sha512-wDOpqHG39t41R0mHj7PqMHnZGRgPfjtxMMBGaKTO05cp+xwOtamDUdx2e0LaG4KYZaq8KbkDXK9XKdASTGuDKw== +polkadot-identicon@^1.1.45: + version "1.1.45" + resolved "https://registry.yarnpkg.com/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz#9c8f5644be15f33e47200120e81cca068e4d26ed" + integrity sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w== dependencies: blake2js "^1.0.0" - oo7 "^0.7.9" - oo7-react "^0.8.10" - oo7-substrate "^0.4.12" + oo7 "^0.7.12" + oo7-react "^0.8.13" + oo7-substrate "^0.8.0" react "^16.4.2" ss58 "^1.0.0" @@ -7295,7 +7402,7 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prop-types@^15.6.0, prop-types@^15.6.2: +prop-types@^15.6.0: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== @@ -7303,6 +7410,15 @@ prop-types@^15.6.0, prop-types@^15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" +prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" @@ -7439,13 +7555,20 @@ randomatic@^3.0.0: kind-of "^6.0.0" math-random "^1.0.1" -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== dependencies: safe-buffer "^5.1.0" +randombytes@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + randomfill@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" @@ -7528,6 +7651,11 @@ react-is@^16.6.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa" integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g== +react-is@^16.8.1: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" + integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== + react-measure@^2.2.4: version "2.2.5" resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.2.5.tgz#35f6be9a8c31d61a4cf847282f9d54c310eb1624" @@ -7610,25 +7738,15 @@ react@16.4.0: object-assign "^4.1.1" prop-types "^15.6.0" -react@^16.4.2: - version "16.7.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" - integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A== +react@^16.4.2, react@^16.5.2: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" + integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.12.0" - -react@^16.5.2: - version "16.8.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.0.tgz#8533f0e4af818f448a276eae71681d09e8dd970a" - integrity sha512-g+nikW2D48kqgWSPwNo0NH9tIGG3DsQFlrtrQ1kj6W77z5ahyIHG0w8kPpz4Sdj6gyLnz0lEd/xsjOoGge2MYQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.13.0" + scheduler "^0.13.6" read-pkg-up@^1.0.1: version "1.0.1" @@ -8123,10 +8241,10 @@ scheduler@^0.12.0: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.0.tgz#e701f62e1b3e78d2bbb264046d4e7260f12184dd" - integrity sha512-w7aJnV30jc7OsiZQNPVmBc+HooZuvQZIZIShKutC3tnMFMkcwVN9CZRRSSNw03OnSCKmEkK8usmwcw6dqBaLzw== +scheduler@^0.13.6: + version "0.13.6" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" + integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -9314,9 +9432,9 @@ universalify@^0.1.0: integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== unorm@^1.3.3: - version "1.4.1" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" - integrity sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA= + version "1.5.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.5.0.tgz#01fa9b76f1c60f7916834605c032aa8962c3f00a" + integrity sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -9788,9 +9906,9 @@ ws@^5.2.0: async-limiter "~1.0.0" ws@^6.1.2: - version "6.1.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.3.tgz#d2d2e5f0e3c700ef2de89080ebc0ac6e1bf3a72d" - integrity sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg== + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== dependencies: async-limiter "~1.0.0" From 7040545963b86534b048c8dcda0906208c0c8a3e Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 15 May 2019 15:21:47 +0200 Subject: [PATCH 31/50] Implement thin backend instead of thick --- packages/backend/src/Aggregator.ts | 18 ++ packages/backend/src/Chain.ts | 126 +++----- packages/backend/src/Feed.ts | 64 +++- packages/backend/src/Node.ts | 178 +---------- packages/common/src/feed.ts | 43 ++- packages/common/src/types.ts | 5 +- packages/frontend/src/AfgHandling.ts | 276 ++++++++++++++++++ packages/frontend/src/App.tsx | 5 +- packages/frontend/src/Connection.ts | 93 ++++-- .../frontend/src/components/Chain/Chain.tsx | 6 +- .../src/components/Consensus/Consensus.css | 3 +- .../src/components/Consensus/Consensus.tsx | 84 +++--- .../components/Consensus/ConsensusBlock.tsx | 63 ++-- packages/frontend/src/state.ts | 15 +- 14 files changed, 566 insertions(+), 413 deletions(-) create mode 100644 packages/frontend/src/AfgHandling.ts diff --git a/packages/backend/src/Aggregator.ts b/packages/backend/src/Aggregator.ts index 45c69ac02..b13d908b4 100644 --- a/packages/backend/src/Aggregator.ts +++ b/packages/backend/src/Aggregator.ts @@ -46,6 +46,24 @@ export default class Aggregator { feed.sendMessage(Feed.unsubscribedFrom(label)); } }); + + feed.events.on('subscribe-consensus-info', (label: Types.ChainLabel) => { + const chain = this.chains.get(label); + + if (chain) { + feed.sendMessage(Feed.subscribedTo(label)); + chain.addFeed(feed); + } + }); + + feed.events.on('unsubscribe-consensus-info', (label: Types.ChainLabel) => { + const chain = this.chains.get(label); + + if (chain) { + chain.removeFeed(feed); + feed.sendMessage(Feed.unsubscribedFrom(label)); + } + }); } public getExistingChain(label: Types.ChainLabel) : Maybe { diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index d887d8d1e..882b1a9c5 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -3,15 +3,13 @@ import Node from './Node'; import Feed from './Feed'; import FeedSet from './FeedSet'; import Block from './Block'; -import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common'; -import { BlockNumber, ConsensusInfo } from "@dotstats/common/build/types"; +import { Maybe, Types, NumStats } from '@dotstats/common'; const BLOCK_TIME_HISTORY = 10; export const MAX_BLOCKS_IN_CHAIN_CACHE = 50; export default class Chain { private nodes = new Set(); - private lastBroadcastCache: Types.ConsensusInfo = {} as ConsensusInfo; private feeds = new FeedSet(); public readonly events = new EventEmitter(); @@ -20,14 +18,11 @@ export default class Chain { public height = 0 as Types.BlockNumber; public finalized = Block.ZERO; public blockTimestamp = 0 as Types.Timestamp; - public chainConsensusCache: Types.ConsensusInfo = {} as ConsensusInfo; private blockTimes = new NumStats(BLOCK_TIME_HISTORY); private averageBlockTime: Maybe = null; - public lastBroadcastedAuthoritySetId: Types.AuthoritySetId = -1 as Types.AuthoritySetId; - public lastBroadcastedAuthoritySet: Types.Authorities = {} as Types.Authorities; - public authoritySetLastChangedAt: Types.BlockNumber = -1 as Types.BlockNumber; + public lastBroadcastedAuthoritySetInfo: Maybe = null; constructor(label: Types.ChainLabel) { this.label = label; @@ -47,9 +42,33 @@ export default class Chain { node.events.on('block', () => this.updateBlock(node)); node.events.on('finalized', () => this.updateFinalized(node)); - node.events.on('consensus-info', () => this.updateConsensusInfo(node)); - node.events.on('authority-set-changed', (authorities, authoritySetId, blockNumber, blockHash) => - this.authoritySetChanged(node, authorities, authoritySetId, blockNumber, blockHash)); + + node.events.on('afg-finalized', (finalizedNumber, finalizedHash) => this.feeds.each( + f => f.sendConsensusMessage(Feed.afgFinalized(node, finalizedNumber, finalizedHash)) + )); + node.events.on('afg-received-prevote', (finalizedNumber, finalizedHash, voter) => this.feeds.each( + f => f.sendConsensusMessage(Feed.afgReceivedPrevote(node, finalizedNumber, finalizedHash, voter)) + )); + node.events.on('afg-received-precommit', (finalizedNumber, finalizedHash, voter) => this.feeds.each( + f => f.sendConsensusMessage(Feed.afgReceivedPrecommit(node, finalizedNumber, finalizedHash, voter)) + )); + node.events.on('authority-set-changed', (authorities, authoritySetId, blockNumber, blockHash) => { + let newSet; + if (this.lastBroadcastedAuthoritySetInfo == null) { + newSet = true; + } else { + const [lastBroadcastedAuthoritySetId] = this.lastBroadcastedAuthoritySetInfo; + newSet = authoritySetId !== lastBroadcastedAuthoritySetId; + } + + if (node.isAuthority() && newSet) { + const addr = node.address != null ? node.address : "" as Types.Address; + const set = [authoritySetId, authorities, addr, blockNumber, blockHash] as Types.AuthoritySetInfo; + this.feeds.broadcast(Feed.afgAuthoritySet(set)); + this.lastBroadcastedAuthoritySetInfo = set; + } + }); + node.events.on('stats', () => this.feeds.broadcast(Feed.stats(node))); node.events.on('hardware', () => this.feeds.broadcast(Feed.hardware(node))); node.events.on('location', (location) => this.feeds.broadcast(Feed.locatedNode(node, location))); @@ -80,9 +99,10 @@ export default class Chain { feed.sendMessage(Feed.timeSync()); feed.sendMessage(Feed.bestBlock(this.height, this.blockTimestamp, this.averageBlockTime)); feed.sendMessage(Feed.bestFinalizedBlock(this.finalized)); - feed.sendMessage(Feed.authoritySet(this.lastBroadcastedAuthoritySet, - this.lastBroadcastedAuthoritySetId)); - feed.sendMessage(Feed.consensusInfo(this.chainConsensusCache)); + + if (this.lastBroadcastedAuthoritySetInfo != null) { + feed.sendMessage(Feed.afgAuthoritySet(this.lastBroadcastedAuthoritySetInfo)); + } for (const node of this.nodes.values()) { feed.sendMessage(Feed.addedNode(node)); @@ -134,7 +154,6 @@ export default class Chain { } this.feeds.broadcast(Feed.imported(node)); - this.updateConsensusInfo(node); console.log(`[${this.label}] ${node.name} imported ${height}, block time: ${node.blockTime / 1000}s, average: ${node.average / 1000}s | latency ${node.latency}`); } @@ -171,85 +190,6 @@ export default class Chain { } this.feeds.broadcast(Feed.finalized(node)); - - this.updateConsensusInfo(node); - } - - private initialiseConsensusView(height: BlockNumber, id_node1: string, addr_node2: string) { - if (this.chainConsensusCache[height] === undefined) { - this.chainConsensusCache[height] = {}; - } - if (this.chainConsensusCache[height][id_node1] === undefined) { - this.chainConsensusCache[height][id_node1] = {}; - this.chainConsensusCache[height][id_node1][addr_node2] = {} as Types.ConsensusInfo; - } - if (this.chainConsensusCache[height][id_node1][addr_node2] === undefined) { - this.chainConsensusCache[height][id_node1][addr_node2] = {} as Types.ConsensusInfo; - } - } - - private updateConsensusInfo(node: Node) { - for (let height in node.consensusCache) { - if (height !== undefined) { - this.initialiseConsensusView(parseInt(height) as BlockNumber, String(node.id), String(node.address)); - this.chainConsensusCache[height][String(node.id)] = node.consensusCache[height]; - } - } - - // broadcast only the cache blocks which changed - const delta: Types.ConsensusInfo = {} as ConsensusInfo; - const keys = Object.keys(this.chainConsensusCache); - const tip = keys[keys.length - 1]; - for (let height in this.chainConsensusCache) { - const inCacheRange = parseInt(tip) - parseInt(height) < MAX_BLOCKS_IN_CHAIN_CACHE; - if (!inCacheRange) { - continue - } - - const current = this.chainConsensusCache[height]; - const old = this.lastBroadcastCache[height]; - - // only display blocks since the last authority set changed - const inRange = parseInt(height) > this.authoritySetLastChangedAt || - this.authoritySetLastChangedAt === undefined; - - if (JSON.stringify(current) !== JSON.stringify(old) && inRange) { - delta[height] = current; - this.lastBroadcastCache[height] = JSON.parse(JSON.stringify(current)); - } - } - - if (Object.keys(delta).length > 0 ) { - this.feeds.broadcast(Feed.consensusInfo(delta)); - this.truncateChainConsensusCache(); - } - } - - private authoritySetChanged(node: Node, authorities: Types.Authorities, authoritySetId: Types.AuthoritySetId, - blockNumber: Types.BlockNumber, blockHash: Types.BlockHash) { - if (node.isAuthority() && authoritySetId !== this.lastBroadcastedAuthoritySetId) { - this.feeds.broadcast(Feed.authoritySet(authorities, authoritySetId)); - this.lastBroadcastedAuthoritySetId = authoritySetId; - this.lastBroadcastedAuthoritySet = authorities; - this.authoritySetLastChangedAt = blockNumber; - this.restartVis(); - } - } - - private truncateChainConsensusCache() { - let list = Object.keys(this.chainConsensusCache).reverse(); - list.map((k, i) => { - if (i > MAX_BLOCKS_IN_CHAIN_CACHE) { - delete this.chainConsensusCache[k]; - } - }); - } - - private restartVis() { - this.nodes.forEach(node => node.resetCache()); - this.chainConsensusCache = {} as ConsensusInfo; - this.lastBroadcastCache = {} as ConsensusInfo; - this.feeds.broadcast(Feed.consensusInfo(this.chainConsensusCache)); } private updateAverageBlockTime(height: Types.BlockNumber, now: Types.Timestamp) { diff --git a/packages/backend/src/Feed.ts b/packages/backend/src/Feed.ts index 277cdef7e..1de65f481 100644 --- a/packages/backend/src/Feed.ts +++ b/packages/backend/src/Feed.ts @@ -19,6 +19,7 @@ export default class Feed { private socket: WebSocket; private messages: Array = []; private waitingForPong = false; + private sendFinality = false; constructor(socket: WebSocket) { this.id = nextId(); @@ -86,24 +87,53 @@ export default class Feed { }; } - public static consensusInfo(blocks: ConsensusInfo): FeedMessage.Message { + public static stats(node: Node): FeedMessage.Message { return { - action: Actions.ConsensusInfo, - payload: blocks + action: Actions.NodeStats, + payload: [node.id, node.nodeStats()] }; } - public static authoritySet(authorities: Authorities, authoritySetId: AuthoritySetId): FeedMessage.Message { + public static afgFinalized(node: Node, finalizedNumber: Types.BlockNumber, finalizedHash: Types.BlockHash): FeedMessage.Message { + const addr = node.address != null ? node.address : "" as Types.Address; return { - action: Actions.AuthoritySet, - payload: [authorities, authoritySetId] + action: Actions.AfgFinalized, + payload: [addr, finalizedNumber, finalizedHash] }; } - public static stats(node: Node): FeedMessage.Message { + public static afgReceivedPrevote( + node: Node, + targetNumber: Types.BlockNumber, + targetHash: Types.BlockHash, + voter: Types.Address + ): FeedMessage.Message { + const addr = node.address != null ? node.address : "" as Types.Address; return { - action: Actions.NodeStats, - payload: [node.id, node.nodeStats()] + action: Actions.AfgReceivedPrevote, + payload: [addr, targetNumber, targetHash, voter] + }; + } + + public static afgReceivedPrecommit( + node: Node, + targetNumber: Types.BlockNumber, + targetHash: Types.BlockHash, + voter: Types.Address + ): FeedMessage.Message { + const addr = node.address != null ? node.address : "" as Types.Address; + return { + action: Actions.AfgReceivedPrecommit, + payload: [addr, targetNumber, targetHash, voter] + }; + } + + public static afgAuthoritySet( + authoritySetInfo: Types.AuthoritySetInfo, + ): FeedMessage.Message { + return { + action: Actions.AfgAuthoritySet, + payload: authoritySetInfo, }; } @@ -170,6 +200,14 @@ export default class Feed { } } + public sendConsensusMessage(message: FeedMessage.Message) { + if (!this.sendFinality) { + return; + } + + this.sendMessage(message); + } + public ping() { if (this.waitingForPong) { this.disconnect(); @@ -203,6 +241,14 @@ export default class Feed { this.events.emit('subscribe', payload as Types.ChainLabel); break; + case 'send-finality': + this.sendFinality = true; + break; + + case 'no-more-finality': + this.sendFinality = false; + break; + case 'ping': this.sendMessage(Feed.pong(payload)); break; diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index bfb2e0631..2284a2c36 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -71,9 +71,6 @@ export default class Node { private pingStart = 0 as Types.Timestamp; private throttle = false; - // how this node views itself and others - public consensusCache: ConsensusView = {} as ConsensusView; - private authorities: Types.Authorities = [] as Types.Authorities; private authoritySetId: Types.AuthoritySetId = 0 as Types.AuthoritySetId; @@ -258,9 +255,6 @@ export default class Node { this.onSystemInterval(message); } - if (message.msg === 'notify.finalized') { - this.onNotifyFinalized(message); - } if (message.msg === 'afg.finalized') { this.onAfgFinalized(message); } @@ -273,7 +267,6 @@ export default class Node { if (message.msg === 'afg.authority_set') { this.onAfgAuthoritySet(message); } - this.truncateBlockCache(); } private onSystemInterval(message: SystemInterval) { @@ -321,95 +314,17 @@ export default class Node { } } - public initialiseConsensusView(height: Types.BlockNumber, addr: Maybe) { - if (!(height in this.consensusCache)) { - this.consensusCache[height] = {}; - } - if (addr && !(addr in this.consensusCache[height])) { - this.consensusCache[height][addr] = {} as Types.ConsensusInfo; - } - } - - public resetCache() { - this.consensusCache = {} as ConsensusView; - } - public isAuthority(): boolean { return this.authority; } - private onNotifyFinalized(message: NotifyFinalized) { - const { - best: best, - height: height, - } = message; - - this.initialiseConsensusView(height as BlockNumber, this.address); - this.consensusCache[height as BlockNumber][String(this.address)].FinalizedHash = best; - this.events.emit('consensus-info'); - } - - public markFinalized(finalizedHeight: BlockNumber, finalizedHash: BlockHash) { - let addr = String(this.address); - - this.initialiseConsensusView(finalizedHeight, this.address); - this.consensusCache[finalizedHeight][addr].Finalized = true; - this.consensusCache[finalizedHeight][addr].FinalizedHash = finalizedHash; - this.consensusCache[finalizedHeight][addr].FinalizedHeight = finalizedHeight; - - // this is extrapolated. if this app was just started up we - // might not yet have received prevotes/precommits. but - // those are a necessary precontion for finalization, so - // we can set them and display them in the ui. - this.consensusCache[finalizedHeight][addr].Prevote = true; - this.consensusCache[finalizedHeight][addr].Precommit = true; - } - - public markImplicitlyFinalized(finalizedHeight: BlockNumber) { - let addr = String(this.address); - - this.initialiseConsensusView(finalizedHeight, this.address); - this.consensusCache[finalizedHeight][addr].Finalized = true; - this.consensusCache[finalizedHeight][addr].FinalizedHeight = finalizedHeight; - this.consensusCache[finalizedHeight][addr].ImplicitFinalized = true; - - // this is extrapolated. if this app was just started up we - // might not yet have received prevotes/precommits. but - // those are a necessary precontion for finalization, so - // we can set them and display them in the ui. - this.consensusCache[finalizedHeight][addr].Prevote = true; - this.consensusCache[finalizedHeight][addr].Precommit = true; - this.consensusCache[finalizedHeight][addr].ImplicitPrevote = true; - this.consensusCache[finalizedHeight][addr].ImplicitPrecommit = true; - } - private onAfgReceivedPrecommit(message: AfgReceivedPrecommit) { const { target_number: targetNumber, target_hash: targetHash, } = message; const voter = this.extractVoter(message.voter); - this.initialiseConsensusView(targetNumber as BlockNumber, voter); - this.consensusCache[targetNumber as BlockNumber][voter].Precommit = true; - - // this node voted for this chain and all the blocks before the current - // one as well. if there no commits yet registered for the prior block - // close the gap to the last block by creating initial block objects. - const mutate = (i: BlockNumber) => { - const info = this.consensusCache[i][voter]; - if (info.Precommit || info.ImplicitPrecommit) { - return false; - } - - info.ImplicitPrecommit = true; - info.ImplicitPointer = from; - - return true; - }; - const from = targetNumber as BlockNumber; - this.backfill(voter, from, mutate); - - this.events.emit('consensus-info'); + this.events.emit('afg-received-precommit', targetNumber, targetHash, voter); } private onAfgReceivedPrevote(message: AfgReceivedPrevote) { @@ -418,26 +333,7 @@ export default class Node { target_hash: targetHash, } = message; const voter = this.extractVoter(message.voter); - this.initialiseConsensusView(targetNumber as BlockNumber, voter); - this.consensusCache[targetNumber as BlockNumber][voter].Prevote = true; - - const firstBlockNumber = Object.keys(this.consensusCache)[0]; - const mutate = (i: BlockNumber) => { - i = i as BlockNumber; - const info = this.consensusCache[i][voter]; - if (info.Prevote || info.ImplicitPrevote) { - return false; - } - - this.consensusCache[i][voter].ImplicitPrevote = true; - this.consensusCache[i][voter].ImplicitPointer = from; - - return true; - }; - const from = targetNumber as BlockNumber; - this.backfill(voter, from, mutate); - - this.events.emit('consensus-info'); + this.events.emit('afg-received-prevote', targetNumber, targetHash, voter); } private onAfgAuthoritySet(message: AfgAuthoritySet) { @@ -455,8 +351,6 @@ export default class Node { this.authoritySetId !== authoritySetId) { this.events.emit('authority-set-changed', authorities, authoritySetId, number, hash); } - - this.authorities = authorities; } private onAfgFinalized(message: AfgFinalized) { @@ -464,72 +358,7 @@ export default class Node { finalized_number: finalizedNumber, finalized_hash: finalizedHash, } = message; - - this.markFinalized(finalizedNumber, finalizedHash); - - let to = finalizedNumber; - this.backfill(this.address, to as BlockNumber, (i) => { - i = i as BlockNumber; - const info = this.consensusCache[i][String(this.address)]; - if (info.Finalized || info.ImplicitFinalized) { - return false; - } - - this.markImplicitlyFinalized(i); - this.consensusCache[i][String(this.address)].ImplicitPointer = to; - - return true; - }); - - this.events.emit('consensus-info'); - } - - // fill the block cache back from the `to` number to the last block. - // the function `f` is used to evaluate if we should continue backfilling. - // `f` returns false when backfilling the cache should be stopped, true to continue. - // - // returns block number until which we backfilled - private backfill(voter: Maybe, from: BlockNumber, f: Maybe<(i: BlockNumber) => boolean>): BlockNumber { - if (!voter) { - return from; - } - - // if this is the first block in the cache then we don't fill latter blocks - if (Object.keys(this.consensusCache).length <= 1) { - return from; - } - - // if below this `from` there are not yet other blocks we don't create empty blocks - if (!this.consensusCache[from - 1]) { - return from; - } - - const firstBlockNumber = Object.keys(this.consensusCache)[0]; - let cont = true; - while (cont && from-- > 0) { - if (this.consensusCache[from] !== undefined) { - // we reached the next block prior to this - return from; - } - - this.initialiseConsensusView(from, voter); - cont = f ? f(from) : true; - - let firstBlockReached = String(from) === firstBlockNumber; - if (firstBlockReached) { - break; - } - } - return from; - } - - private truncateBlockCache() { - let list = Object.keys(this.consensusCache).reverse(); - list.map((k, i) => { - if (i > MAX_BLOCKS_IN_NODE_CACHE + 1) { - delete this.consensusCache[k]; - } - }); + this.events.emit('afg-finalized', finalizedNumber, finalizedHash); } private extractVoter(message_voter: String): Types.Address { @@ -578,7 +407,6 @@ export default class Node { } const target = this.best.number as BlockNumber; - this.backfill(this.address, target, null); } } diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 5bef4bc30..9f938cac9 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -20,7 +20,7 @@ import { BlockDetails, Timestamp, Milliseconds, - ChainLabel + ChainLabel, AuthoritySetInfo } from './types'; export const Actions = { @@ -41,7 +41,10 @@ export const Actions = { UnsubscribedFrom : 0x0E as 0x0E, Pong : 0x0F as 0x0F, ConsensusInfo : 0x10 as 0x10, - AuthoritySet : 0x11 as 0x11, + AfgFinalized : 0x11 as 0x11, + AfgReceivedPrevote : 0x12 as 0x12, + AfgReceivedPrecommit : 0x13 as 0x13, + AfgAuthoritySet : 0x14 as 0x14, }; export type Action = typeof Actions[keyof typeof Actions]; @@ -92,16 +95,6 @@ export namespace Variants { payload: [NodeId, BlockNumber, BlockHash]; } - export interface ConsensusInfoMessage extends MessageBase { - action: typeof Actions.ConsensusInfo; - payload: ConsensusInfo; - } - - export interface AuthoritySetMessage extends MessageBase { - action: typeof Actions.AuthoritySet; - payload: [Authorities, AuthoritySetId]; - } - export interface NodeStatsMessage extends MessageBase { action: typeof Actions.NodeStats; payload: [NodeId, NodeStats]; @@ -141,6 +134,26 @@ export namespace Variants { action: typeof Actions.Pong; payload: string; // just echo whatever `ping` sent } + + export interface AfgFinalizedMessage extends MessageBase { + action: typeof Actions.AfgFinalized; + payload: [Address, BlockNumber, BlockHash]; + } + + export interface AfgAuthoritySet extends MessageBase { + action: typeof Actions.AfgAuthoritySet; + payload: AuthoritySetInfo; + } + + export interface AfgReceivedPrecommit extends MessageBase { + action: typeof Actions.AfgReceivedPrecommit; + payload: [Address, BlockNumber, BlockHash, Address]; + } + + export interface AfgReceivedPrevote extends MessageBase { + action: typeof Actions.AfgReceivedPrevote; + payload: [Address, BlockNumber, BlockHash, Address]; + } } export type Message = @@ -152,8 +165,6 @@ export type Message = | Variants.LocatedNodeMessage | Variants.ImportedBlockMessage | Variants.FinalizedBlockMessage - | Variants.ConsensusInfoMessage - | Variants.AuthoritySetMessage | Variants.NodeStatsMessage | Variants.NodeHardwareMessage | Variants.TimeSyncMessage @@ -161,6 +172,10 @@ export type Message = | Variants.RemovedChainMessage | Variants.SubscribedToMessage | Variants.UnsubscribedFromMessage + | Variants.AfgFinalizedMessage + | Variants.AfgReceivedPrevote + | Variants.AfgReceivedPrecommit + | Variants.AfgAuthoritySet | Variants.PongMessage; /** diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 3381794dd..47d98200e 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -39,8 +39,9 @@ export declare type Authority = { }; export declare type Authorities = Array
; export declare type AuthoritySetId = Opaque; -export declare type ConsensusInfo = Map; -export declare type ConsensusView = Map; +export declare type AuthoritySetInfo = [AuthoritySetId, Authorities, Address, BlockNumber, BlockHash]; +export declare type ConsensusInfo = Array<[BlockNumber, ConsensusView]>; +export declare type ConsensusView = Map; export declare type ConsensusState = Map; export declare type ConsensusDetail = { Precommit: Precommit; diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts new file mode 100644 index 000000000..5b4b523dd --- /dev/null +++ b/packages/frontend/src/AfgHandling.ts @@ -0,0 +1,276 @@ +import { Types, Maybe } from '@dotstats/common'; +import { State } from './state'; + +export function afgAuthoritySet( + authoritySetId: Types.AuthoritySetId, + authorities: Types.Authorities, + updateState: (state: any) => void, + getState: () => State, +) { + if (authoritySetId !== getState().authoritySetId) { + // the visualization is restarted when we receive a new auhority set + updateState({ authoritySetId, authorities, consensusInfo: [] }); + } + return null; +} + +export function afgFinalized( + addr: Types.Address, + finalizedNumber: Types.BlockNumber, + finalizedHash: Types.BlockHash, + updateState: (state: any) => void, + getState: () => State, +) { + const consensusInfo = getState().consensusInfo; + markFinalized(addr, finalizedNumber, finalizedHash, updateState, getState); + + const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { + const consensusDetail = view[addr][addr]; + if (consensusDetail.Finalized || consensusDetail.ImplicitFinalized) { + return false; + } + + markImplicitlyFinalized(i, addr, finalizedNumber, addr, updateState, getState); + return true; + }; + backfill(consensusInfo, finalizedNumber, op, addr, addr); +} + +export function afgMarkPre( + addr: Types.Address, + height: Types.BlockNumber, + hash: Types.BlockHash, + voter: Types.Address, + what: string, + updateState: (state: any) => void, + getState: () => State, +) { + const consensusInfo = getState().consensusInfo; + initialiseConsensusView(consensusInfo, height, addr, voter); + + const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); + const [, consensusView] = consensusInfo[index]; + + if (what === "prevote") { + consensusView[addr][voter].Prevote = true; + } else if (what === "precommit") { + consensusView[addr][voter].Precommit = true; + } + + if (index !== -1) { + consensusInfo[index] = [height, consensusView]; + } else { + // append at the beginning + consensusInfo.unshift([height, consensusView]); + } + + updateState({consensusInfo}); + + const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { + const consensusDetail = view[addr][voter]; + if (consensusDetail.Prevote || consensusDetail.ImplicitPrevote) { + return false; + } + + markImplicitlyPre(i, addr, height, what, voter, updateState, getState); + return true; + }; + backfill(consensusInfo, height, op, addr, voter); +} + +function markFinalized( + addr: Types.Address, + finalizedHeight: Types.BlockNumber, + finalizedHash: Types.BlockHash, + updateState: (state: any) => void, + getState: () => State, +) { + const consensusInfo = getState().consensusInfo; + + initialiseConsensusView(consensusInfo, finalizedHeight, addr, addr); + + const index = consensusInfo + .findIndex(([blockNumber,]) => blockNumber === finalizedHeight); + if (index === -1) { + return; + } + const [, consensusView] = consensusInfo[index]; + + consensusView[addr][addr].Finalized = true; + consensusView[addr][addr].FinalizedHash = finalizedHash; + consensusView[addr][addr].FinalizedHeight = finalizedHeight; + + // this is extrapolated. if this app was just started up we + // might not yet have received prevotes/precommits. but + // those are a necessary precondition for finalization, so + // we can set them and display them in the ui. + consensusView[addr][addr].Prevote = true; + consensusView[addr][addr].Precommit = true; + + consensusInfo[index] = [finalizedHeight, consensusView]; + + if (index !== -1) { + consensusInfo[index] = [finalizedHeight, consensusView]; + } else { + consensusInfo.unshift([finalizedHeight, consensusView]); + } + + updateState({consensusInfo}); +} + +// An Prevote or Precommit on a block implicitly includes +// a vote on all preceding blocks. This function marks +// the preceding blocks as implicitly voted on and stores +// a pointer to the block which contains the explicit vote. +function markImplicitlyPre( + height: Types.BlockNumber, + addr: Types.Address, + where: Types.BlockNumber, + what: string, + voter: Types.Address, + updateState: (state: any) => void, + getState: () => State, +) { + const consensusInfo = getState().consensusInfo; + initialiseConsensusView(consensusInfo, height, addr, voter); + + const [consensusView, index] = getConsensusView(consensusInfo, height); + + if (what === "prevote") { + consensusView[addr][voter].ImplicitPrevote = true; + } else if (what === "precommit") { + consensusView[addr][voter].ImplicitPrecommit = true; + } + consensusView[addr][voter].ImplicitPointer = where; + + consensusInfo[index] = [height, consensusView]; + updateState({consensusInfo}); +} + +// Finalizing a block implicitly includes finalizing all +// preceding blocks. This function marks the preceding +// blocks as implicitly finalized on and stores a pointer +// to the block which contains the explicit finalization. +function markImplicitlyFinalized( + height: Types.BlockNumber, + addr: Types.Address, + to: Types.BlockNumber, + voter: Types.Address, + updateState: (state: any) => void, + getState: () => State, +) { + const consensusInfo = getState().consensusInfo; + initialiseConsensusView(consensusInfo, height, addr, voter); + + const [consensusView, index] = getConsensusView(consensusInfo, height); + + consensusView[addr][voter].Finalized = true; + consensusView[addr][voter].FinalizedHeight = height; + consensusView[addr][voter].ImplicitFinalized = true; + consensusView[addr][voter].ImplicitPointer = to; + + // this is extrapolated. if this app was just started up we + // might not yet have received prevotes/precommits. but + // those are a necessary precondition for finalization, so + // we can set them and display them in the ui. + consensusView[addr][voter].Prevote = true; + consensusView[addr][voter].Precommit = true; + consensusView[addr][voter].ImplicitPrevote = true; + consensusView[addr][voter].ImplicitPrecommit = true; + + if (index !== -1) { + consensusInfo[index] = [height, consensusView]; + } else { + consensusInfo.unshift([height, consensusView]); + } + + updateState({consensusInfo}); +} + +// Initializes the `ConsensusView` with empty objects. +function initialiseConsensusView( + consensusInfo: Types.ConsensusInfo, + height: Types.BlockNumber, + own: Types.Address, + other: Types.Address, +) { + const index = consensusInfo.findIndex(item => { + const [blockNumber,] = item; + return blockNumber === height; + }); + + let consensusView; + if (index === -1) { + consensusView = {} as Types.ConsensusView; + } else { + const found = consensusInfo[index]; + const [, foundView] = found; + consensusView = foundView; + } + + if (!consensusView[own]) { + consensusView[own] = {} as Types.ConsensusState; + } + + if (!consensusView[own][other]) { + consensusView[own][other] = {} as Types.ConsensusDetail; + } + + if (index === -1) { + // append at the beginning + consensusInfo.unshift([height, consensusView]); + } else { + consensusInfo[index] = [height, consensusView]; + } +} + +// Fill the block cache back from the `to` number to the last block. +// The function `f` is used to evaluate if we should continue backfilling. +// `f` returns false when backfilling the cache should be stopped, true to continue. +// +// Returns block number until which we backfilled. +function backfill( + consensusInfo: Types.ConsensusInfo, + to: Types.BlockNumber, + f: Maybe<(i: Types.BlockNumber, consensusView: Types.ConsensusView) => boolean>, + own: Types.Address, + other: Types.Address, +): Types.BlockNumber { + let cont = true; + for (const i of consensusInfo) { + const [height,] = i; + if (height >= to) { + continue; + } + + initialiseConsensusView(consensusInfo, height, own, other); + + const index = consensusInfo.findIndex(item => { + const [blockNumber, ] = item; + return blockNumber === height; + }); + + if (index === -1) { + cont = false; + break; + } + + const [, consensusView] = consensusInfo[index]; + + cont = f ? f(height, consensusView) : true; + if (!cont) { + break; + } + } + return to; +} + +function getConsensusView( + consensusInfo: Types.ConsensusInfo, + height: Types.BlockNumber, +): [Types.ConsensusView, number] { + const index = + consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); + const [, consensusView] = consensusInfo[index]; + return [consensusView, index]; +} diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index f08dccac5..00e8b0ee9 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -53,7 +53,7 @@ export default class App extends React.Component<{}, State> { status: 'offline', best: 0 as Types.BlockNumber, finalized: 0 as Types.BlockNumber, - consensusInfo: {} as Types.ConsensusInfo, + consensusInfo: new Array(), authorities: new Array() as Types.Authorities, authoritySetId: -1 as Types.AuthoritySetId, authoritySetBlockNumber: -1 as Types.BlockNumber, @@ -61,6 +61,7 @@ export default class App extends React.Component<{}, State> { blockAverage: null, timeDiff: 0 as Types.Milliseconds, subscribed: null, + sendFinality: false, chains: new Map(), nodes: new SortedCollection(Node.compare), settings: this.settings.raw(), @@ -94,7 +95,7 @@ export default class App extends React.Component<{}, State> {
- +
); } diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index f4ca22dab..f8d131ec5 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -2,6 +2,7 @@ import { VERSION, timestamp, FeedMessage, Types, Maybe, sleep } from '@dotstats/ import { State, Update, Node } from './state'; import { PersistentSet } from './persist'; import { getHashData, setHashData } from './utils'; +import { afgAuthoritySet, afgFinalized, afgMarkPre } from './AfgHandling'; const { Actions } = FeedMessage; @@ -63,6 +64,7 @@ export class Connection { private pingTimeout: NodeJS.Timer; private pingSent: Maybe = null; private resubscribeTo: Maybe = getHashData().chain; + private resubscribeSendFinality: boolean = getHashData().tab === 'consensus'; private socket: WebSocket; private state: Readonly; private readonly update: Update; @@ -80,6 +82,18 @@ export class Connection { this.socket.send(`subscribe:${chain}`); } + public subscribeConsensus(chain: Types.ChainLabel) { + setHashData({ chain }); + this.resubscribeSendFinality = true; + this.socket.send(`send-finality:${chain}`); + } + + public unsubscribeConsensus(chain: Types.ChainLabel) { + setHashData({ chain }); + this.resubscribeSendFinality = true; + this.socket.send(`no-more-finality:${chain}`); + } + public handleMessages = (messages: FeedMessage.Message[]) => { const { nodes, chains } = this.state; const ref = nodes.ref(); @@ -160,32 +174,6 @@ export class Connection { break; } - case Actions.ConsensusInfo: { - const receivedConsensusInfo = message.payload; - const updatedConsensusInfo = JSON.parse(JSON.stringify(this.state.consensusInfo)); - - if (Object.keys(receivedConsensusInfo).length === 0) { - this.state = this.update({ consensusInfo: {} as Types.ConsensusInfo }); - break; - } - - for (const height of Object.keys(receivedConsensusInfo)) { - updatedConsensusInfo[height] = receivedConsensusInfo[height]; - } - this.state = this.update({consensusInfo: updatedConsensusInfo}); - - break; - } - - case Actions.AuthoritySet: { - const [authorities, authoritySetId] = message.payload; - - this.state = this.update({ authorities: authorities as Types.Authorities, - authoritySetId }); - - break; - } - case Actions.NodeStats: { const [id, nodeStats] = message.payload; @@ -254,6 +242,49 @@ export class Connection { break; } + case Actions.AfgFinalized: { + const [nodeAddress, finalizedNumber, finalizedHash] = message.payload; + afgFinalized(nodeAddress, finalizedNumber, finalizedHash, + (foo: any) => { + console.log("in closure"); + this.state = this.update(foo); + }, + () => this.state + ); + + break; + } + + case Actions.AfgReceivedPrevote: { + const [nodeAddress, blockNumber, blockHash, voter] = message.payload; + afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "prevote", + (foo: any) => { this.state = this.update(foo)}, + () => this.state + ); + + break; + } + + case Actions.AfgReceivedPrecommit: { + const [nodeAddress, blockNumber, blockHash, voter] = message.payload; + afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "precommit", + (foo: any) => { this.state = this.update(foo)}, + () => this.state + ); + + break; + } + + case Actions.AfgAuthoritySet: { + const [authoritySetId, authorities] = message.payload; + afgAuthoritySet(authoritySetId, authorities, + (foo: any) => { this.state = this.update(foo)}, + () => this.state, + ); + + break; + } + default: { break; } @@ -281,7 +312,9 @@ export class Connection { if (this.state.subscribed) { this.resubscribeTo = this.state.subscribed; - this.state = this.update({ subscribed: null }); + this.resubscribeSendFinality = this.state.sendFinality; + + this.state = this.update({ subscribed: null, sendFinality: false }); } this.socket.addEventListener('message', this.handleFeedData); @@ -339,7 +372,7 @@ export class Connection { private autoSubscribe() { const { subscribed, chains } = this.state; - const { resubscribeTo } = this; + const { resubscribeTo, resubscribeSendFinality } = this; if (subscribed) { return; @@ -347,7 +380,11 @@ export class Connection { if (resubscribeTo) { if (chains.has(resubscribeTo)) { + this.subscribe(resubscribeTo); + if (resubscribeSendFinality) { + this.subscribeConsensus(resubscribeTo); + } return; } } diff --git a/packages/frontend/src/components/Chain/Chain.tsx b/packages/frontend/src/components/Chain/Chain.tsx index af0012089..0c8db165b 100644 --- a/packages/frontend/src/components/Chain/Chain.tsx +++ b/packages/frontend/src/components/Chain/Chain.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Connection } from '../../Connection'; import { Types } from '@dotstats/common'; import { State as AppState } from '../../state'; import { formatNumber, secondsWithPrecision, getHashData } from '../../utils'; @@ -22,6 +23,7 @@ export namespace Chain { export interface Props { appState: Readonly; + connection: Promise; settings: PersistentObject; pins: PersistentSet; } @@ -89,10 +91,10 @@ export class Chain extends React.Component { return ; } - const { appState, pins } = this.props; + const { appState, connection, pins } = this.props; if (display === 'consensus') { - return ; + return ; } return ( diff --git a/packages/frontend/src/components/Consensus/Consensus.css b/packages/frontend/src/components/Consensus/Consensus.css index 0a2cf21e1..b16cf16f0 100644 --- a/packages/frontend/src/components/Consensus/Consensus.css +++ b/packages/frontend/src/components/Consensus/Consensus.css @@ -1,5 +1,6 @@ .ConsensusList { - opacity: 0; /* the box should only show up once flexing has been applied */ + // TODO revert to 0 + opacity: 1.0; /* the box should only show up once flexing has been applied */ } .ConsensusList table { diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index bc0af7896..c9598aabc 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { Types } from '@dotstats/common'; +import { Connection } from '../../Connection'; import Measure, {BoundingRect, ContentRect} from 'react-measure'; import { ConsensusBlock } from './'; @@ -10,6 +11,7 @@ import './Consensus.css'; export namespace Consensus { export interface Props { appState: Readonly; + connection: Promise; } export interface State { @@ -43,6 +45,20 @@ export class Consensus extends React.Component { smallRowsAddFlexClass: false, }; + public componentDidMount() { + if (this.props.appState.subscribed != null) { + const chain = this.props.appState.subscribed; + this.subscribeConsensus(chain); + } + } + + public componentWillUnmount() { + if (this.props.appState.subscribed != null) { + const chain = this.props.appState.subscribed; + this.unsubscribeConsensus(chain); + } + } + public largeBlocksSizeDetected(state: Consensus.State): boolean { const countBlocks = Object.keys(this.props.appState.consensusInfo).length; if (countBlocks === 1) { @@ -91,39 +107,10 @@ export class Consensus extends React.Component { } } - public shouldComponentUpdate(nextProps: Consensus.Props, nextState: Consensus.State): boolean { - if (this.props.appState.authorities.length === 0 && nextProps.appState.authorities.length === 0) { - return false; - } - if (this.props.appState.nodes.sorted().length === 0 && nextProps.appState.nodes.sorted().length === 0) { - return false; - } - - const authoritiesDidChange = JSON.stringify(this.props.appState.authorities) !== - JSON.stringify(nextProps.appState.authorities); - const authoritySetIdDidChange = this.props.appState.authoritySetId !== - nextProps.appState.authoritySetId; - - const newConsensusInfoAvailable = JSON.stringify(this.props.appState.consensusInfo) !== - JSON.stringify(nextProps.appState.consensusInfo); - - const windowSizeChanged = JSON.stringify(this.state.dimensions) !== - JSON.stringify(nextState.dimensions); - - // size detected, but flex class has not yet been added - const largeBlocksSizeDetected = this.largeBlocksSizeDetected(nextState) === true && - this.state.largeRowsAddFlexClass === false; - const smallBlocksSizeDetected = this.smallBlocksSizeDetected(nextState) === true && - this.state.smallRowsAddFlexClass === false; - - return authoritiesDidChange || authoritySetIdDidChange || newConsensusInfoAvailable || - windowSizeChanged || largeBlocksSizeDetected || smallBlocksSizeDetected; - } - public render() { this.calculateBoxCount(false); - const lastBlocks = Object.keys(this.props.appState.consensusInfo).reverse(); + const lastBlocks = this.props.appState.consensusInfo; let from = 0; let to = this.state.countBlocksInLargeRow; @@ -159,6 +146,10 @@ export class Consensus extends React.Component { private getAuthorities(): Types.Authority[] { // find the node for each of these authority addresses + if (this.props.appState.authorities == null) { + return []; + } + return this.props.appState.authorities.map(address => { const node2 = this.props.appState.nodes.sorted().filter(node => node.address === address)[0]; if (!node2) { @@ -168,7 +159,7 @@ export class Consensus extends React.Component { }); } - private getLargeRow(blocks: string[], id: number) { + private getLargeRow(blocks: Types.ConsensusInfo, id: number) { const largeBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { if (this.largeBlocksSizeDetected(this.state)) { return; @@ -187,23 +178,25 @@ export class Consensus extends React.Component { return
- {blocks.map((height, i) => - { + const [height, consensusView] = item; + return )} + />; + })}
; } - private getSmallRow(blocks: string[]) { + private getSmallRow(blocks: Types.ConsensusInfo) { const smallBlockSizeChanged = (isFirstBlock: boolean, rect: BoundingRect) => { if (this.smallBlocksSizeDetected(this.state)) { return; @@ -220,7 +213,8 @@ export class Consensus extends React.Component { const classes = `ConsensusList SmallRow ${this.state.smallRowsAddFlexClass ? 'flexContainerSmallRow' : ''} ${stretchLastRow}`; return
- {blocks.map((height, i) => { + {blocks.map((item, i) => { + const [height, consensusView] = item; let lastInRow = (i+1) % this.state.countBlocksInSmallRow === 0 ? true : false; if (lastInRow && i === 0) { // should not be marked as last one in row if it's the very first in row @@ -233,8 +227,8 @@ export class Consensus extends React.Component { lastInRow={lastInRow} compact={true} key={height} - height={parseInt(height, 10) as Types.BlockNumber} - consensusView={this.props.appState.consensusInfo[height]} + height={height} + consensusView={consensusView} authorities={this.getAuthorities()} authoritySetBlockNumber={this.props.appState.authoritySetBlockNumber} authoritySetId={this.props.appState.authoritySetId} />; @@ -242,4 +236,14 @@ export class Consensus extends React.Component { }
; } + + private async subscribeConsensus(chain: Types.ChainLabel) { + const connection = await this.props.connection; + connection.subscribeConsensus(chain); + } + + private async unsubscribeConsensus(chain: Types.ChainLabel) { + const connection = await this.props.connection; + connection.unsubscribeConsensus(chain); + } } diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx index 39d2e9b52..e9be16ec0 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Measure, {BoundingRect, ContentRect} from 'react-measure'; -import { Types } from '@dotstats/common'; +import { Types, Maybe } from '@dotstats/common'; import Identicon from 'polkadot-identicon'; import { Icon, Tooltip } from '../'; @@ -29,19 +29,6 @@ export namespace ConsensusBlock { export class ConsensusBlock extends React.Component { - public shouldComponentUpdate(nextProps: ConsensusBlock.Props): boolean { - if (this.props.authorities.length === 0 && nextProps.authorities.length === 0) { - return false; - } - - const newConsensusInfo = - JSON.stringify(nextProps.consensusView) !== JSON.stringify(this.props.consensusView); - const positionInfoChanged = this.props.firstInRow !== nextProps.firstInRow || - this.props.lastInRow !== nextProps.lastInRow; - - return newConsensusInfo || positionInfoChanged; - } - public render() { const finalizedByWhom = this.props.authorities.filter(authority => this.isFinalized(authority)); @@ -55,8 +42,8 @@ export class ConsensusBlock extends React.Component { } else if (majorityFinalized && this.props.compact) { const hash = this.getFinalizedHash(finalizedByWhom[0]); titleFinal = - - + + ; } @@ -85,7 +72,7 @@ export class ConsensusBlock extends React.Component { - {this.getAuthorityContent(authority, false)} + {this.getAuthorityContent(authority)} )} @@ -105,39 +92,31 @@ export class ConsensusBlock extends React.Component { } private isFinalized(authority: Types.Authority): boolean { - if (!authority || authority.NodeId === null || authority.Address === null) { + if (!authority || authority.NodeId == null || authority.Address == null) { return false; } - const { Address: address, NodeId: id } = authority; + const { Address: addr } = authority; const consensus = this.props.consensusView; - return consensus !== undefined && - String(id) in consensus && - address in consensus[String(id)] && - consensus[String(id)][address].Finalized === true; + return consensus != null && addr in consensus && addr in consensus[addr] + && consensus[addr][addr].Finalized === true; } - private getFinalizedHash(authority: Types.Authority): Types.BlockHash { - const { Address: address , NodeId: id } = authority; - const consensus = this.props.consensusView; - - if (consensus !== undefined && - id != null && - id in consensus && - address in consensus[id] && - consensus[id][address].Finalized === true) { - return consensus[id][address].FinalizedHash; + private getFinalizedHash(authority: Types.Authority): Maybe { + if (this.isFinalized(authority)) { + const { Address: addr } = authority; + return this.props.consensusView[addr][addr].FinalizedHash; } - return '' as Types.BlockHash; + return null; } private renderMatriceRow(authority: Types.Authority, authorities: Types.Authority[], row: number): JSX.Element { let finalizedInfo =  ; let finalizedHash; - if (authority.NodeId !== null && authority.NodeId !== undefined && this.isFinalized(authority)) { - const matrice = this.props.consensusView[String(authority.NodeId)][authority.Address]; + if (authority.NodeId != null && this.isFinalized(authority)) { + const matrice = this.props.consensusView[authority.Address][authority.Address]; finalizedInfo = matrice.ImplicitFinalized ? @@ -159,7 +138,7 @@ export class ConsensusBlock extends React.Component { return {firstName} - {this.getAuthorityContent(authority, true)} + {this.getAuthorityContent(authority)} {finalizedInfo}{finalizedHash} { authorities.map((columnNode, column) => { @@ -171,7 +150,7 @@ export class ConsensusBlock extends React.Component { ; } - private getAuthorityContent(authority: Types.Authority, nodeName: boolean): JSX.Element { + private getAuthorityContent(authority: Types.Authority): JSX.Element { return
@@ -203,10 +182,10 @@ export class ConsensusBlock extends React.Component { private getMatriceContent(rowAuthority: Types.Authority, columnAuthority: Types.Authority) { const consensusInfo = this.props.consensusView && - String(rowAuthority.NodeId) && - String(rowAuthority.NodeId) in this.props.consensusView && - columnAuthority.Address in this.props.consensusView[String(rowAuthority.NodeId)] ? - this.props.consensusView[String(rowAuthority.NodeId)][columnAuthority.Address] : null; + rowAuthority.Address && + rowAuthority.Address in this.props.consensusView && + columnAuthority.Address in this.props.consensusView[rowAuthority.Address] ? + this.props.consensusView[rowAuthority.Address][columnAuthority.Address] : null; let tooltipText = consensusInfo ? rowAuthority.Name + ' has seen this of ' + columnAuthority.Name + ': ' + diff --git a/packages/frontend/src/state.ts b/packages/frontend/src/state.ts index 1925fd7d3..d221a7315 100644 --- a/packages/frontend/src/state.ts +++ b/packages/frontend/src/state.ts @@ -42,7 +42,6 @@ export class Node { public propagationTime: Maybe; public finalized = 0 as Types.BlockNumber; - public consensusInfo: Types.ConsensusInfo; public finalizedHash = '' as Types.BlockHash; public lat: Maybe; @@ -50,6 +49,7 @@ export class Node { public city: Maybe; private readonly subscriptions = new Set<(node: Node) => void>(); + private readonly subscriptionsConsensus = new Set<(node: Node) => void>(); constructor( pinned: boolean, @@ -119,10 +119,6 @@ export class Node { this.finalizedHash = hash; } - public updateConsensusInfo(consensusInfo: Types.ConsensusInfo) { - this.consensusInfo = consensusInfo; - } - public updateLocation(location: Types.NodeLocation) { const [lat, lon, city] = location; @@ -155,6 +151,14 @@ export class Node { this.subscriptions.delete(handler); } + public subscribeConsensus(handler: (node: Node) => void) { + this.subscriptionsConsensus.add(handler); + } + + public unsubscribeConsensus(handler: (node: Node) => void) { + this.subscriptionsConsensus.delete(handler); + } + private trigger() { for (const handler of this.subscriptions.values()) { handler(this); @@ -197,6 +201,7 @@ export interface State { blockAverage: Maybe; timeDiff: Types.Milliseconds; subscribed: Maybe; + sendFinality: boolean; chains: Map; nodes: SortedCollection; settings: Readonly; From ca5d29bb436880acffdc0a87ec10556a0f9ce356 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 16 May 2019 21:27:16 +0200 Subject: [PATCH 32/50] Cleanup and minor improvements --- packages/backend/src/Chain.ts | 1 - packages/backend/src/Node.ts | 2 -- packages/common/src/feed.ts | 3 ++- packages/frontend/src/AfgHandling.ts | 2 +- packages/frontend/src/App.tsx | 2 +- packages/frontend/src/Connection.ts | 27 +++++-------------- .../src/components/Consensus/Consensus.css | 3 +-- packages/frontend/src/state.ts | 2 +- 8 files changed, 12 insertions(+), 30 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index 882b1a9c5..82493d24c 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -6,7 +6,6 @@ import Block from './Block'; import { Maybe, Types, NumStats } from '@dotstats/common'; const BLOCK_TIME_HISTORY = 10; -export const MAX_BLOCKS_IN_CHAIN_CACHE = 50; export default class Chain { private nodes = new Set(); diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 2284a2c36..becc71bed 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -18,13 +18,11 @@ import { import { locate, Location } from './location'; import MeanList from './MeanList'; import Block from './Block'; -import { MAX_BLOCKS_IN_CHAIN_CACHE } from './Chain'; const BLOCK_TIME_HISTORY = 10; const MEMORY_RECORDS = 20; const CPU_RECORDS = 20; const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute -const MAX_BLOCKS_IN_NODE_CACHE = MAX_BLOCKS_IN_CHAIN_CACHE; const nextId = idGenerator(); diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 9f938cac9..372fc3ae7 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -20,7 +20,8 @@ import { BlockDetails, Timestamp, Milliseconds, - ChainLabel, AuthoritySetInfo + ChainLabel, + AuthoritySetInfo, } from './types'; export const Actions = { diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index 5b4b523dd..c16d0d0c7 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -118,7 +118,7 @@ function markFinalized( updateState({consensusInfo}); } -// An Prevote or Precommit on a block implicitly includes +// A Prevote or Precommit on a block implicitly includes // a vote on all preceding blocks. This function marks // the preceding blocks as implicitly voted on and stores // a pointer to the block which contains the explicit vote. diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 00e8b0ee9..7eb3ec2e3 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -57,11 +57,11 @@ export default class App extends React.Component<{}, State> { authorities: new Array() as Types.Authorities, authoritySetId: -1 as Types.AuthoritySetId, authoritySetBlockNumber: -1 as Types.BlockNumber, + sendFinality: false, blockTimestamp: 0 as Types.Timestamp, blockAverage: null, timeDiff: 0 as Types.Milliseconds, subscribed: null, - sendFinality: false, chains: new Map(), nodes: new SortedCollection(Node.compare), settings: this.settings.raw(), diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index f8d131ec5..194875037 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -97,6 +97,8 @@ export class Connection { public handleMessages = (messages: FeedMessage.Message[]) => { const { nodes, chains } = this.state; const ref = nodes.ref(); + const setState = (state: State) => { this.state = this.update(state); }; + const getState = () => this.state; for (const message of messages) { switch (message.action) { @@ -244,43 +246,28 @@ export class Connection { case Actions.AfgFinalized: { const [nodeAddress, finalizedNumber, finalizedHash] = message.payload; - afgFinalized(nodeAddress, finalizedNumber, finalizedHash, - (foo: any) => { - console.log("in closure"); - this.state = this.update(foo); - }, - () => this.state - ); + afgFinalized( nodeAddress, finalizedNumber, finalizedHash, setState, getState); break; } case Actions.AfgReceivedPrevote: { const [nodeAddress, blockNumber, blockHash, voter] = message.payload; - afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "prevote", - (foo: any) => { this.state = this.update(foo)}, - () => this.state - ); + afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "prevote", setState, getState); break; } case Actions.AfgReceivedPrecommit: { const [nodeAddress, blockNumber, blockHash, voter] = message.payload; - afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "precommit", - (foo: any) => { this.state = this.update(foo)}, - () => this.state - ); + afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "precommit", setState, getState); break; } case Actions.AfgAuthoritySet: { const [authoritySetId, authorities] = message.payload; - afgAuthoritySet(authoritySetId, authorities, - (foo: any) => { this.state = this.update(foo)}, - () => this.state, - ); + afgAuthoritySet(authoritySetId, authorities, setState, getState); break; } @@ -313,7 +300,6 @@ export class Connection { if (this.state.subscribed) { this.resubscribeTo = this.state.subscribed; this.resubscribeSendFinality = this.state.sendFinality; - this.state = this.update({ subscribed: null, sendFinality: false }); } @@ -380,7 +366,6 @@ export class Connection { if (resubscribeTo) { if (chains.has(resubscribeTo)) { - this.subscribe(resubscribeTo); if (resubscribeSendFinality) { this.subscribeConsensus(resubscribeTo); diff --git a/packages/frontend/src/components/Consensus/Consensus.css b/packages/frontend/src/components/Consensus/Consensus.css index b16cf16f0..0309150dd 100644 --- a/packages/frontend/src/components/Consensus/Consensus.css +++ b/packages/frontend/src/components/Consensus/Consensus.css @@ -1,6 +1,5 @@ .ConsensusList { - // TODO revert to 0 - opacity: 1.0; /* the box should only show up once flexing has been applied */ + opacity: 0.0; /* the box should only show up once flexing has been applied */ } .ConsensusList table { diff --git a/packages/frontend/src/state.ts b/packages/frontend/src/state.ts index d221a7315..faca362b3 100644 --- a/packages/frontend/src/state.ts +++ b/packages/frontend/src/state.ts @@ -197,11 +197,11 @@ export interface State { authorities: Types.Address[]; authoritySetId: Types.AuthoritySetId; authoritySetBlockNumber: Types.BlockNumber; + sendFinality: boolean; blockTimestamp: Types.Timestamp; blockAverage: Maybe; timeDiff: Types.Milliseconds; subscribed: Maybe; - sendFinality: boolean; chains: Map; nodes: SortedCollection; settings: Readonly; From 0bc61dc98185c61c564c580f667d35efea7bae32 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 16 May 2019 21:54:08 +0200 Subject: [PATCH 33/50] Minor refactoring --- packages/frontend/src/AfgHandling.ts | 13 ++++--------- packages/frontend/src/Connection.ts | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index c16d0d0c7..c7c9753ce 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -194,10 +194,8 @@ function initialiseConsensusView( own: Types.Address, other: Types.Address, ) { - const index = consensusInfo.findIndex(item => { - const [blockNumber,] = item; - return blockNumber === height; - }); + const index = + consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); let consensusView; if (index === -1) { @@ -245,11 +243,8 @@ function backfill( initialiseConsensusView(consensusInfo, height, own, other); - const index = consensusInfo.findIndex(item => { - const [blockNumber, ] = item; - return blockNumber === height; - }); - + const index = + consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); if (index === -1) { cont = false; break; diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index 194875037..7e5d53e4d 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -97,7 +97,7 @@ export class Connection { public handleMessages = (messages: FeedMessage.Message[]) => { const { nodes, chains } = this.state; const ref = nodes.ref(); - const setState = (state: State) => { this.state = this.update(state); }; + const setState = (state: any) => { this.state = this.update(state); }; const getState = () => this.state; for (const message of messages) { From 019d1f5c8b7bd426615fd2de04827aea999cae01 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 16 May 2019 22:49:46 +0200 Subject: [PATCH 34/50] Extract common code into function --- packages/frontend/src/AfgHandling.ts | 99 +++++++++++++--------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index c7c9753ce..c99a61375 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -45,26 +45,9 @@ export function afgMarkPre( updateState: (state: any) => void, getState: () => State, ) { - const consensusInfo = getState().consensusInfo; - initialiseConsensusView(consensusInfo, height, addr, voter); - - const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - const [, consensusView] = consensusInfo[index]; - - if (what === "prevote") { - consensusView[addr][voter].Prevote = true; - } else if (what === "precommit") { - consensusView[addr][voter].Precommit = true; - } - - if (index !== -1) { - consensusInfo[index] = [height, consensusView]; - } else { - // append at the beginning - consensusInfo.unshift([height, consensusView]); - } - - updateState({consensusInfo}); + const obj = {}; + obj[what === "prevote" ? "Prevote" : "Precommit"] = true; + updateConsensusInfo(height, addr, voter, obj, updateState, getState); const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { const consensusDetail = view[addr][voter]; @@ -75,7 +58,7 @@ export function afgMarkPre( markImplicitlyPre(i, addr, height, what, voter, updateState, getState); return true; }; - backfill(consensusInfo, height, op, addr, voter); + backfill(getState().consensusInfo, height, op, addr, voter); } function markFinalized( @@ -85,37 +68,19 @@ function markFinalized( updateState: (state: any) => void, getState: () => State, ) { - const consensusInfo = getState().consensusInfo; - - initialiseConsensusView(consensusInfo, finalizedHeight, addr, addr); - - const index = consensusInfo - .findIndex(([blockNumber,]) => blockNumber === finalizedHeight); - if (index === -1) { - return; - } - const [, consensusView] = consensusInfo[index]; - - consensusView[addr][addr].Finalized = true; - consensusView[addr][addr].FinalizedHash = finalizedHash; - consensusView[addr][addr].FinalizedHeight = finalizedHeight; - - // this is extrapolated. if this app was just started up we - // might not yet have received prevotes/precommits. but - // those are a necessary precondition for finalization, so - // we can set them and display them in the ui. - consensusView[addr][addr].Prevote = true; - consensusView[addr][addr].Precommit = true; - - consensusInfo[index] = [finalizedHeight, consensusView]; - - if (index !== -1) { - consensusInfo[index] = [finalizedHeight, consensusView]; - } else { - consensusInfo.unshift([finalizedHeight, consensusView]); - } - - updateState({consensusInfo}); + const obj = { + Finalized: true, + FinalizedHash: finalizedHash, + FinalizedHeight: finalizedHeight, + + // this is extrapolated. if this app was just started up we + // might not yet have received prevotes/precommits. but + // those are a necessary precondition for finalization, so + // we can set them and display them in the ui. + Prevote: true, + Precommit: true, + }; + updateConsensusInfo(finalizedHeight, addr, addr, obj, updateState, getState); } // A Prevote or Precommit on a block implicitly includes @@ -269,3 +234,33 @@ function getConsensusView( const [, consensusView] = consensusInfo[index]; return [consensusView, index]; } + +function updateConsensusInfo( + height: Types.BlockNumber, + addr: Types.Address, + voter: Types.Address, + obj: object, + updateState: (state: any) => void, + getState: () => State, +) { + const consensusInfo = getState().consensusInfo; + initialiseConsensusView(consensusInfo, height, addr, voter); + + const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); + const [, consensusView] = consensusInfo[index]; + + for (const o in obj) { + if (obj.hasOwnProperty(o)) { + consensusView[addr][voter][o] = obj[o]; + } + } + + if (index !== -1) { + consensusInfo[index] = [height, consensusView]; + } else { + // append at the beginning + consensusInfo.unshift([height, consensusView]); + } + + updateState({consensusInfo}); +} From ed429c640d42117f9eb32c9616e2293f58ba650d Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 16 May 2019 23:00:38 +0200 Subject: [PATCH 35/50] Switch module to class --- packages/frontend/src/AfgHandling.ts | 449 +++++++++++++-------------- packages/frontend/src/Connection.ts | 14 +- 2 files changed, 232 insertions(+), 231 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index c99a61375..fd03c74af 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -1,266 +1,265 @@ import { Types, Maybe } from '@dotstats/common'; import { State } from './state'; -export function afgAuthoritySet( - authoritySetId: Types.AuthoritySetId, - authorities: Types.Authorities, - updateState: (state: any) => void, - getState: () => State, -) { - if (authoritySetId !== getState().authoritySetId) { - // the visualization is restarted when we receive a new auhority set - updateState({ authoritySetId, authorities, consensusInfo: [] }); +export class AfgHandling { + private updateState: (state: any) => void; + private getState: () => State; + + constructor( + updateState: (state: any) => void, + getState: () => State, + ) { + this.updateState = updateState; + this.getState = getState; } - return null; -} -export function afgFinalized( - addr: Types.Address, - finalizedNumber: Types.BlockNumber, - finalizedHash: Types.BlockHash, - updateState: (state: any) => void, - getState: () => State, -) { - const consensusInfo = getState().consensusInfo; - markFinalized(addr, finalizedNumber, finalizedHash, updateState, getState); - - const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { - const consensusDetail = view[addr][addr]; - if (consensusDetail.Finalized || consensusDetail.ImplicitFinalized) { - return false; + public receivedAuthoritySet( + authoritySetId: Types.AuthoritySetId, + authorities: Types.Authorities, + ) { + if (authoritySetId !== this.getState().authoritySetId) { + // the visualization is restarted when we receive a new auhority set + this.updateState({authoritySetId, authorities, consensusInfo: []}); } + return null; + } - markImplicitlyFinalized(i, addr, finalizedNumber, addr, updateState, getState); - return true; - }; - backfill(consensusInfo, finalizedNumber, op, addr, addr); -} + public receivedFinalized( + addr: Types.Address, + finalizedNumber: Types.BlockNumber, + finalizedHash: Types.BlockHash, + ) { + const consensusInfo = this.getState().consensusInfo; + this.markFinalized(addr, finalizedNumber, finalizedHash); + + const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { + const consensusDetail = view[addr][addr]; + if (consensusDetail.Finalized || consensusDetail.ImplicitFinalized) { + return false; + } + + this.markImplicitlyFinalized(i, addr, finalizedNumber, addr); + return true; + }; + this.backfill(consensusInfo, finalizedNumber, op, addr, addr); + } + + public receivedPre( + addr: Types.Address, + height: Types.BlockNumber, + hash: Types.BlockHash, + voter: Types.Address, + what: string, + ) { + const obj = {}; + obj[what === "prevote" ? "Prevote" : "Precommit"] = true; + this.updateConsensusInfo(height, addr, voter, obj); + + const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { + const consensusDetail = view[addr][voter]; + if (consensusDetail.Prevote || consensusDetail.ImplicitPrevote) { + return false; + } + + this.markImplicitlyPre(i, addr, height, what, voter); + return true; + }; + this.backfill(this.getState().consensusInfo, height, op, addr, voter); + } -export function afgMarkPre( - addr: Types.Address, - height: Types.BlockNumber, - hash: Types.BlockHash, - voter: Types.Address, - what: string, - updateState: (state: any) => void, - getState: () => State, -) { - const obj = {}; - obj[what === "prevote" ? "Prevote" : "Precommit"] = true; - updateConsensusInfo(height, addr, voter, obj, updateState, getState); - - const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { - const consensusDetail = view[addr][voter]; - if (consensusDetail.Prevote || consensusDetail.ImplicitPrevote) { - return false; + private markFinalized( + addr: Types.Address, + finalizedHeight: Types.BlockNumber, + finalizedHash: Types.BlockHash, + ) { + const obj = { + Finalized: true, + FinalizedHash: finalizedHash, + FinalizedHeight: finalizedHeight, + + // this is extrapolated. if this app was just started up we + // might not yet have received prevotes/precommits. but + // those are a necessary precondition for finalization, so + // we can set them and display them in the ui. + Prevote: true, + Precommit: true, + }; + this.updateConsensusInfo(finalizedHeight, addr, addr, obj); + } + + // A Prevote or Precommit on a block implicitly includes + // a vote on all preceding blocks. This function marks + // the preceding blocks as implicitly voted on and stores + // a pointer to the block which contains the explicit vote. + private markImplicitlyPre( + height: Types.BlockNumber, + addr: Types.Address, + where: Types.BlockNumber, + what: string, + voter: Types.Address, + ) { + const consensusInfo = this.getState().consensusInfo; + this.initialiseConsensusView(consensusInfo, height, addr, voter); + + const [consensusView, index] = this.getConsensusView(consensusInfo, height); + + if (what === "prevote") { + consensusView[addr][voter].ImplicitPrevote = true; + } else if (what === "precommit") { + consensusView[addr][voter].ImplicitPrecommit = true; } + consensusView[addr][voter].ImplicitPointer = where; - markImplicitlyPre(i, addr, height, what, voter, updateState, getState); - return true; - }; - backfill(getState().consensusInfo, height, op, addr, voter); -} + consensusInfo[index] = [height, consensusView]; + this.updateState({consensusInfo}); + } -function markFinalized( - addr: Types.Address, - finalizedHeight: Types.BlockNumber, - finalizedHash: Types.BlockHash, - updateState: (state: any) => void, - getState: () => State, -) { - const obj = { - Finalized: true, - FinalizedHash: finalizedHash, - FinalizedHeight: finalizedHeight, + // Finalizing a block implicitly includes finalizing all + // preceding blocks. This function marks the preceding + // blocks as implicitly finalized on and stores a pointer + // to the block which contains the explicit finalization. + private markImplicitlyFinalized( + height: Types.BlockNumber, + addr: Types.Address, + to: Types.BlockNumber, + voter: Types.Address, + ) { + const consensusInfo = this.getState().consensusInfo; + this.initialiseConsensusView(consensusInfo, height, addr, voter); + + const [consensusView, index] = this.getConsensusView(consensusInfo, height); + + consensusView[addr][voter].Finalized = true; + consensusView[addr][voter].FinalizedHeight = height; + consensusView[addr][voter].ImplicitFinalized = true; + consensusView[addr][voter].ImplicitPointer = to; // this is extrapolated. if this app was just started up we // might not yet have received prevotes/precommits. but // those are a necessary precondition for finalization, so // we can set them and display them in the ui. - Prevote: true, - Precommit: true, - }; - updateConsensusInfo(finalizedHeight, addr, addr, obj, updateState, getState); -} - -// A Prevote or Precommit on a block implicitly includes -// a vote on all preceding blocks. This function marks -// the preceding blocks as implicitly voted on and stores -// a pointer to the block which contains the explicit vote. -function markImplicitlyPre( - height: Types.BlockNumber, - addr: Types.Address, - where: Types.BlockNumber, - what: string, - voter: Types.Address, - updateState: (state: any) => void, - getState: () => State, -) { - const consensusInfo = getState().consensusInfo; - initialiseConsensusView(consensusInfo, height, addr, voter); - - const [consensusView, index] = getConsensusView(consensusInfo, height); - - if (what === "prevote") { + consensusView[addr][voter].Prevote = true; + consensusView[addr][voter].Precommit = true; consensusView[addr][voter].ImplicitPrevote = true; - } else if (what === "precommit") { consensusView[addr][voter].ImplicitPrecommit = true; - } - consensusView[addr][voter].ImplicitPointer = where; - consensusInfo[index] = [height, consensusView]; - updateState({consensusInfo}); -} + if (index !== -1) { + consensusInfo[index] = [height, consensusView]; + } else { + consensusInfo.unshift([height, consensusView]); + } -// Finalizing a block implicitly includes finalizing all -// preceding blocks. This function marks the preceding -// blocks as implicitly finalized on and stores a pointer -// to the block which contains the explicit finalization. -function markImplicitlyFinalized( - height: Types.BlockNumber, - addr: Types.Address, - to: Types.BlockNumber, - voter: Types.Address, - updateState: (state: any) => void, - getState: () => State, -) { - const consensusInfo = getState().consensusInfo; - initialiseConsensusView(consensusInfo, height, addr, voter); - - const [consensusView, index] = getConsensusView(consensusInfo, height); - - consensusView[addr][voter].Finalized = true; - consensusView[addr][voter].FinalizedHeight = height; - consensusView[addr][voter].ImplicitFinalized = true; - consensusView[addr][voter].ImplicitPointer = to; - - // this is extrapolated. if this app was just started up we - // might not yet have received prevotes/precommits. but - // those are a necessary precondition for finalization, so - // we can set them and display them in the ui. - consensusView[addr][voter].Prevote = true; - consensusView[addr][voter].Precommit = true; - consensusView[addr][voter].ImplicitPrevote = true; - consensusView[addr][voter].ImplicitPrecommit = true; - - if (index !== -1) { - consensusInfo[index] = [height, consensusView]; - } else { - consensusInfo.unshift([height, consensusView]); + this.updateState({consensusInfo}); } - updateState({consensusInfo}); -} + // Initializes the `ConsensusView` with empty objects. + private initialiseConsensusView( + consensusInfo: Types.ConsensusInfo, + height: Types.BlockNumber, + own: Types.Address, + other: Types.Address, + ) { + const index = + consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); -// Initializes the `ConsensusView` with empty objects. -function initialiseConsensusView( - consensusInfo: Types.ConsensusInfo, - height: Types.BlockNumber, - own: Types.Address, - other: Types.Address, -) { - const index = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - - let consensusView; - if (index === -1) { - consensusView = {} as Types.ConsensusView; - } else { - const found = consensusInfo[index]; - const [, foundView] = found; - consensusView = foundView; - } + let consensusView; + if (index === -1) { + consensusView = {} as Types.ConsensusView; + } else { + const found = consensusInfo[index]; + const [, foundView] = found; + consensusView = foundView; + } - if (!consensusView[own]) { - consensusView[own] = {} as Types.ConsensusState; - } + if (!consensusView[own]) { + consensusView[own] = {} as Types.ConsensusState; + } - if (!consensusView[own][other]) { - consensusView[own][other] = {} as Types.ConsensusDetail; - } + if (!consensusView[own][other]) { + consensusView[own][other] = {} as Types.ConsensusDetail; + } - if (index === -1) { - // append at the beginning - consensusInfo.unshift([height, consensusView]); - } else { - consensusInfo[index] = [height, consensusView]; + if (index === -1) { + // append at the beginning + consensusInfo.unshift([height, consensusView]); + } else { + consensusInfo[index] = [height, consensusView]; + } } -} -// Fill the block cache back from the `to` number to the last block. -// The function `f` is used to evaluate if we should continue backfilling. -// `f` returns false when backfilling the cache should be stopped, true to continue. -// -// Returns block number until which we backfilled. -function backfill( - consensusInfo: Types.ConsensusInfo, - to: Types.BlockNumber, - f: Maybe<(i: Types.BlockNumber, consensusView: Types.ConsensusView) => boolean>, - own: Types.Address, - other: Types.Address, -): Types.BlockNumber { - let cont = true; - for (const i of consensusInfo) { - const [height,] = i; - if (height >= to) { - continue; + // Fill the block cache back from the `to` number to the last block. + // The function `f` is used to evaluate if we should continue backfilling. + // `f` returns false when backfilling the cache should be stopped, true to continue. + // + // Returns block number until which we backfilled. + private backfill( + consensusInfo: Types.ConsensusInfo, + to: Types.BlockNumber, + f: Maybe<(i: Types.BlockNumber, consensusView: Types.ConsensusView) => boolean>, + own: Types.Address, + other: Types.Address, + ): Types.BlockNumber { + let cont = true; + for (const i of consensusInfo) { + const [height,] = i; + if (height >= to) { + continue; + } + + this.initialiseConsensusView(consensusInfo, height, own, other); + + const index = + consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); + if (index === -1) { + cont = false; + break; + } + + const [, consensusView] = consensusInfo[index]; + + cont = f ? f(height, consensusView) : true; + if (!cont) { + break; + } } + return to; + } - initialiseConsensusView(consensusInfo, height, own, other); - + private getConsensusView( + consensusInfo: Types.ConsensusInfo, + height: Types.BlockNumber, + ): [Types.ConsensusView, number] { const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - if (index === -1) { - cont = false; - break; - } + const [, consensusView] = consensusInfo[index]; + return [consensusView, index]; + } + private updateConsensusInfo( + height: Types.BlockNumber, + addr: Types.Address, + voter: Types.Address, + obj: object, + ) { + const consensusInfo = this.getState().consensusInfo; + this.initialiseConsensusView(consensusInfo, height, addr, voter); + + const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); const [, consensusView] = consensusInfo[index]; - cont = f ? f(height, consensusView) : true; - if (!cont) { - break; + for (const o in obj) { + if (obj.hasOwnProperty(o)) { + consensusView[addr][voter][o] = obj[o]; + } } - } - return to; -} -function getConsensusView( - consensusInfo: Types.ConsensusInfo, - height: Types.BlockNumber, -): [Types.ConsensusView, number] { - const index = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - const [, consensusView] = consensusInfo[index]; - return [consensusView, index]; -} - -function updateConsensusInfo( - height: Types.BlockNumber, - addr: Types.Address, - voter: Types.Address, - obj: object, - updateState: (state: any) => void, - getState: () => State, -) { - const consensusInfo = getState().consensusInfo; - initialiseConsensusView(consensusInfo, height, addr, voter); - - const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - const [, consensusView] = consensusInfo[index]; - - for (const o in obj) { - if (obj.hasOwnProperty(o)) { - consensusView[addr][voter][o] = obj[o]; + if (index !== -1) { + consensusInfo[index] = [height, consensusView]; + } else { + // append at the beginning + consensusInfo.unshift([height, consensusView]); } - } - if (index !== -1) { - consensusInfo[index] = [height, consensusView]; - } else { - // append at the beginning - consensusInfo.unshift([height, consensusView]); + this.updateState({consensusInfo}); } - - updateState({consensusInfo}); } diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index 7e5d53e4d..921904df0 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -2,7 +2,7 @@ import { VERSION, timestamp, FeedMessage, Types, Maybe, sleep } from '@dotstats/ import { State, Update, Node } from './state'; import { PersistentSet } from './persist'; import { getHashData, setHashData } from './utils'; -import { afgAuthoritySet, afgFinalized, afgMarkPre } from './AfgHandling'; +import { AfgHandling } from './AfgHandling'; const { Actions } = FeedMessage; @@ -97,8 +97,10 @@ export class Connection { public handleMessages = (messages: FeedMessage.Message[]) => { const { nodes, chains } = this.state; const ref = nodes.ref(); - const setState = (state: any) => { this.state = this.update(state); }; + + const updateState = (state: any) => { this.state = this.update(state); }; const getState = () => this.state; + const afg = new AfgHandling(updateState, getState); for (const message of messages) { switch (message.action) { @@ -246,28 +248,28 @@ export class Connection { case Actions.AfgFinalized: { const [nodeAddress, finalizedNumber, finalizedHash] = message.payload; - afgFinalized( nodeAddress, finalizedNumber, finalizedHash, setState, getState); + afg.receivedFinalized( nodeAddress, finalizedNumber, finalizedHash); break; } case Actions.AfgReceivedPrevote: { const [nodeAddress, blockNumber, blockHash, voter] = message.payload; - afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "prevote", setState, getState); + afg.receivedPre(nodeAddress, blockNumber, blockHash, voter, "prevote"); break; } case Actions.AfgReceivedPrecommit: { const [nodeAddress, blockNumber, blockHash, voter] = message.payload; - afgMarkPre(nodeAddress, blockNumber, blockHash, voter, "precommit", setState, getState); + afg.receivedPre(nodeAddress, blockNumber, blockHash, voter, "precommit"); break; } case Actions.AfgAuthoritySet: { const [authoritySetId, authorities] = message.payload; - afgAuthoritySet(authoritySetId, authorities, setState, getState); + afg.receivedAuthoritySet(authoritySetId, authorities); break; } From 6fe140aef617af8afd30d2f40d952987d01ce051 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 16 May 2019 23:06:29 +0200 Subject: [PATCH 36/50] Remove unused code --- packages/backend/src/Feed.ts | 1 - packages/backend/src/Node.ts | 2 -- packages/common/src/feed.ts | 12 ++++-------- packages/frontend/src/App.tsx | 1 - .../frontend/src/components/Consensus/Consensus.tsx | 2 -- .../src/components/Consensus/ConsensusBlock.tsx | 1 - packages/frontend/src/state.ts | 1 - 7 files changed, 4 insertions(+), 16 deletions(-) diff --git a/packages/backend/src/Feed.ts b/packages/backend/src/Feed.ts index 1de65f481..2b9a39ea2 100644 --- a/packages/backend/src/Feed.ts +++ b/packages/backend/src/Feed.ts @@ -5,7 +5,6 @@ import Chain from './Chain'; import Block from './Block'; import { VERSION, timestamp, Maybe, FeedMessage, Types, idGenerator } from '@dotstats/common'; import { Location } from './location'; -import { Authorities, AuthoritySetId, ConsensusInfo } from "@dotstats/common/build/types"; const nextId = idGenerator(); const { Actions } = FeedMessage; diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index becc71bed..71655d142 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -403,8 +403,6 @@ export default class Node { this.throttle = false; }, 1000); } - - const target = this.best.number as BlockNumber; } } diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 372fc3ae7..285fd9cb7 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -3,9 +3,6 @@ import { stringify, parse, Stringified } from './stringify'; import { FeedVersion, Address, - Authorities, - AuthoritySetId, - ConsensusInfo, Latitude, Longitude, City, @@ -41,11 +38,10 @@ export const Actions = { SubscribedTo : 0x0D as 0x0D, UnsubscribedFrom : 0x0E as 0x0E, Pong : 0x0F as 0x0F, - ConsensusInfo : 0x10 as 0x10, - AfgFinalized : 0x11 as 0x11, - AfgReceivedPrevote : 0x12 as 0x12, - AfgReceivedPrecommit : 0x13 as 0x13, - AfgAuthoritySet : 0x14 as 0x14, + AfgFinalized : 0x10 as 0x10, + AfgReceivedPrevote : 0x11 as 0x11, + AfgReceivedPrecommit : 0x12 as 0x12, + AfgAuthoritySet : 0x13 as 0x13, }; export type Action = typeof Actions[keyof typeof Actions]; diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 7eb3ec2e3..80e0ccfde 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -56,7 +56,6 @@ export default class App extends React.Component<{}, State> { consensusInfo: new Array(), authorities: new Array() as Types.Authorities, authoritySetId: -1 as Types.AuthoritySetId, - authoritySetBlockNumber: -1 as Types.BlockNumber, sendFinality: false, blockTimestamp: 0 as Types.Timestamp, blockAverage: null, diff --git a/packages/frontend/src/components/Consensus/Consensus.tsx b/packages/frontend/src/components/Consensus/Consensus.tsx index c9598aabc..94c0dde4a 100644 --- a/packages/frontend/src/components/Consensus/Consensus.tsx +++ b/packages/frontend/src/components/Consensus/Consensus.tsx @@ -190,7 +190,6 @@ export class Consensus extends React.Component { consensusView={consensusView} authorities={this.getAuthorities()} authoritySetId={this.props.appState.authoritySetId} - authoritySetBlockNumber={this.props.appState.authoritySetBlockNumber} />; })}
; @@ -230,7 +229,6 @@ export class Consensus extends React.Component { height={height} consensusView={consensusView} authorities={this.getAuthorities()} - authoritySetBlockNumber={this.props.appState.authoritySetBlockNumber} authoritySetId={this.props.appState.authoritySetId} />; }) } diff --git a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx index e9be16ec0..5172ec16d 100644 --- a/packages/frontend/src/components/Consensus/ConsensusBlock.tsx +++ b/packages/frontend/src/components/Consensus/ConsensusBlock.tsx @@ -17,7 +17,6 @@ export namespace ConsensusBlock { export interface Props { authorities: Types.Authority[]; authoritySetId: Types.AuthoritySetId; - authoritySetBlockNumber: Types.BlockNumber; height: Types.BlockNumber; firstInRow: boolean; lastInRow: boolean; diff --git a/packages/frontend/src/state.ts b/packages/frontend/src/state.ts index faca362b3..043a0b736 100644 --- a/packages/frontend/src/state.ts +++ b/packages/frontend/src/state.ts @@ -196,7 +196,6 @@ export interface State { consensusInfo: Types.ConsensusInfo; authorities: Types.Address[]; authoritySetId: Types.AuthoritySetId; - authoritySetBlockNumber: Types.BlockNumber; sendFinality: boolean; blockTimestamp: Types.Timestamp; blockAverage: Maybe; From 4e73e8fa87ab20905345b26b1db3ae3c6d4162f7 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 16 May 2019 23:13:18 +0200 Subject: [PATCH 37/50] Clean markup --- packages/frontend/src/icons/finalized.svg | 10 +---- packages/frontend/src/icons/hatching.svg | 46 +---------------------- 2 files changed, 2 insertions(+), 54 deletions(-) diff --git a/packages/frontend/src/icons/finalized.svg b/packages/frontend/src/icons/finalized.svg index 6bd538508..3c07d6c39 100644 --- a/packages/frontend/src/icons/finalized.svg +++ b/packages/frontend/src/icons/finalized.svg @@ -1,17 +1,9 @@ + version="1.1"> diff --git a/packages/frontend/src/icons/hatching.svg b/packages/frontend/src/icons/hatching.svg index 3a69ac949..97a2a1da7 100644 --- a/packages/frontend/src/icons/hatching.svg +++ b/packages/frontend/src/icons/hatching.svg @@ -2,57 +2,13 @@ - - - - - - image/svg+xml - - - - - + version="1.1"> Date: Thu, 16 May 2019 23:15:40 +0200 Subject: [PATCH 38/50] Remove unused code --- packages/backend/src/Node.ts | 3 +-- packages/backend/src/message.ts | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 71655d142..f84ab822a 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -13,7 +13,6 @@ import { AfgReceivedPrecommit, AfgReceivedPrevote, AfgAuthoritySet, - NotifyFinalized, } from './message'; import { locate, Location } from './location'; import MeanList from './MeanList'; @@ -343,7 +342,7 @@ export default class Node { // we manually parse the authorities message, because the array was formatted as a // string by substrate before sending it. - let authorities = JSON.parse(String(message.authorities)) as Types.Authorities; + const authorities = JSON.parse(String(message.authorities)) as Types.Authorities; if (JSON.stringify(this.authorities) !== String(message.authorities) || this.authoritySetId !== authoritySetId) { diff --git a/packages/backend/src/message.ts b/packages/backend/src/message.ts index 14ef1ab93..eb46c76b0 100644 --- a/packages/backend/src/message.ts +++ b/packages/backend/src/message.ts @@ -39,10 +39,6 @@ export interface BestBlock { ts: Date; } -export interface NotifyFinalized extends BestBlock { - msg: 'notify.finalized'; -} - export interface AfgFinalized { ts: Date; finalized_number: Types.BlockNumber; @@ -118,7 +114,6 @@ export type Message = MessageBase & ( | SystemInterval | NodeStart | BlockImport - | NotifyFinalized | AfgFinalized | AfgReceivedPrecommit | AfgReceivedPrevote From 174eba464948edbca7a8153751f318921def088c Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 08:09:52 +0200 Subject: [PATCH 39/50] Revert "Upgrade dependencies" This reverts commit bf4d9ea48b3417860ccf40f0c5122027ffc59689. --- package-lock.json | 799 +-------------------------------- package.json | 3 - packages/frontend/package.json | 2 +- yarn.lock | 244 +++------- 4 files changed, 65 insertions(+), 983 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fc2c77a9..62ca6a70c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,801 +1,4 @@ { "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/runtime": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz", - "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==", - "requires": { - "regenerator-runtime": "^0.13.2" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" - } - } - }, - "@polkadot/util": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-0.41.1.tgz", - "integrity": "sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ==", - "requires": { - "@babel/runtime": "^7.4.0", - "@types/bn.js": "^4.11.4", - "@types/deasync": "^0.1.0", - "@types/ip-regex": "^3.0.0", - "bn.js": "^4.11.8", - "camelcase": "^5.2.0", - "chalk": "^2.4.2", - "ip-regex": "^4.0.0", - "moment": "^2.24.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "ip-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", - "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==" - } - } - }, - "@polkadot/wasm-crypto": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz", - "integrity": "sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg==" - }, - "@polkadot/wasm-schnorrkel": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz", - "integrity": "sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA==" - }, - "@types/bn.js": { - "version": "4.11.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", - "integrity": "sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng==", - "requires": { - "@types/node": "*" - } - }, - "@types/deasync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@types/deasync/-/deasync-0.1.0.tgz", - "integrity": "sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA==" - }, - "@types/ip-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/ip-regex/-/ip-regex-3.0.0.tgz", - "integrity": "sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw==" - }, - "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" - }, - "base-x": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", - "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip39": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", - "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "blake2js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/blake2js/-/blake2js-1.0.0.tgz", - "integrity": "sha1-tokMOU3blAXQbZp6089lZxHcrYk=", - "requires": { - "bindings": "^1.2.1", - "debug": "^2.2.0", - "nan": "^2.4.0", - "readable-stream": "^2.1.4" - } - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "canvas-renderer": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/canvas-renderer/-/canvas-renderer-2.1.1.tgz", - "integrity": "sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "change-case": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", - "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", - "requires": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", - "requires": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", - "requires": { - "no-case": "^2.2.0" - } - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", - "requires": { - "lower-case": "^1.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", - "requires": { - "upper-case": "^1.1.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" - }, - "jdenticon": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/jdenticon/-/jdenticon-2.1.1.tgz", - "integrity": "sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg==", - "requires": { - "canvas-renderer": "~2.1.1" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" - }, - "lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", - "requires": { - "lower-case": "^1.1.2" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "oo7": { - "version": "0.7.12", - "resolved": "https://registry.npmjs.org/oo7/-/oo7-0.7.12.tgz", - "integrity": "sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA==" - }, - "oo7-react": { - "version": "0.8.13", - "resolved": "https://registry.npmjs.org/oo7-react/-/oo7-react-0.8.13.tgz", - "integrity": "sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q==", - "requires": { - "oo7": "^0.7.12", - "react": "^16.5.2" - }, - "dependencies": { - "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" - } - } - } - }, - "oo7-substrate": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/oo7-substrate/-/oo7-substrate-0.8.0.tgz", - "integrity": "sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA==", - "requires": { - "@polkadot/util": "^0.41.1", - "@polkadot/wasm-crypto": "^0.5.1", - "@polkadot/wasm-schnorrkel": "^0.3.1", - "base-x": "^3.0.4", - "bip39": "^2.5.0", - "blakejs": "^1.1.0", - "bs58": "^4.0.1", - "buffer": "^5.2.1", - "change-case": "^3.0.2", - "isomorphic-fetch": "^2.2.1", - "isomorphic-ws": "^4.0.1", - "jdenticon": "^2.1.1", - "oo7": "^0.7.12", - "pbkdf2": "^3.0.17", - "ss58": "^1.0.2", - "text-encoding": "^0.7.0", - "text-encoding-polyfill": "^0.6.7", - "tweetnacl": "^1.0.0", - "ws": "^6.1.2", - "xxhashjs": "^0.2.2" - }, - "dependencies": { - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "tweetnacl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", - "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" - } - } - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "requires": { - "no-case": "^2.2.0" - } - }, - "pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", - "requires": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" - } - }, - "path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", - "requires": { - "no-case": "^2.2.0" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "polkadot-identicon": { - "version": "1.1.45", - "resolved": "https://registry.npmjs.org/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz", - "integrity": "sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w==", - "requires": { - "blake2js": "^1.0.0", - "oo7": "^0.7.12", - "oo7-react": "^0.8.13", - "oo7-substrate": "^0.8.0", - "react": "^16.4.2", - "ss58": "^1.0.0" - }, - "dependencies": { - "react": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", - "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" - } - } - } - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - }, - "dependencies": { - "react-is": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", - "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scheduler": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", - "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", - "requires": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", - "requires": { - "no-case": "^2.2.0" - } - }, - "ss58": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ss58/-/ss58-1.0.2.tgz", - "integrity": "sha512-hCpPJ12+GgsYsyVW2dXY6p3KfqZgLFA9zrKp5cgEx3x93JjPG4DDm6lu0Zp87FW0CSRan3gy7jlF4ZCjHqS7Ig==", - "requires": { - "blakejs": "^1.1.0", - "bs58": "^4.0.1" - } - }, - "swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", - "requires": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" - } - }, - "text-encoding": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", - "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" - }, - "text-encoding-polyfill": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/text-encoding-polyfill/-/text-encoding-polyfill-0.6.7.tgz", - "integrity": "sha512-/DZ1XJqhbqRkCop6s9ZFu8JrFRwmVuHg4quIRm+ziFkR3N3ec6ck6yBvJ1GYeEQZhLVwRW0rZE+C3SSJpy0RTg==" - }, - "title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" - } - }, - "unorm": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.5.0.tgz", - "integrity": "sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw==" - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" - }, - "upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", - "requires": { - "upper-case": "^1.1.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "whatwg-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", - "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", - "requires": { - "cuint": "^0.2.2" - } - } - } + "lockfileVersion": 1 } diff --git a/package.json b/package.json index 1a2e3e975..443ac9c8c 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,5 @@ "build:common": "tsc -p packages/common", "check:common": "tsc -p packages/common --noEmit", "test": "scripts/test.sh" - }, - "dependencies": { - "polkadot-identicon": "^1.1.45" } } diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 83feed4df..1e674a330 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -21,7 +21,7 @@ "dependencies": { "@fnando/sparkline": "maciejhirsz/sparkline", "@types/react-measure": "^2.0.5", - "polkadot-identicon": "^1.1.45", + "polkadot-identicon": "^1.1.36", "react": "16.4.0", "react-dom": "16.4.0", "react-measure": "^2.2.4", diff --git a/yarn.lock b/yarn.lock index 72af375c1..2a59eec27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,54 +25,15 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.4.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d" - integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg== - dependencies: - regenerator-runtime "^0.13.2" - "@fnando/sparkline@maciejhirsz/sparkline": version "0.3.10" resolved "https://codeload.github.com/maciejhirsz/sparkline/tar.gz/2bdb002b171436be078a84f1e4e617a44ef1fb42" -"@polkadot/util@^0.41.1": - version "0.41.1" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.41.1.tgz#b67762a0a7408138d843adc7240944e704e819e7" - integrity sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ== - dependencies: - "@babel/runtime" "^7.4.0" - "@types/bn.js" "^4.11.4" - "@types/deasync" "^0.1.0" - "@types/ip-regex" "^3.0.0" - bn.js "^4.11.8" - camelcase "^5.2.0" - chalk "^2.4.2" - ip-regex "^4.0.0" - moment "^2.24.0" - -"@polkadot/wasm-crypto@^0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz#3d5734d6dc2f5174a411689f78538287d21bd710" - integrity sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg== - -"@polkadot/wasm-schnorrkel@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz#08287848f769dee4955517348905888bd289f277" - integrity sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA== - "@tanem/svg-injector@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@tanem/svg-injector/-/svg-injector-1.2.1.tgz#3120e90246d0eb3c4fc6c61586a6f028a3c658ae" integrity sha512-mA5Q5ulPoGQ+e08Vts1R6xw2QU0BKEnMH/KcqoYoS7Gk6imvMTpyFPeu1g+NOZObSIoAzA3/kRzY8m96cEBA2A== -"@types/bn.js@^4.11.4": - version "4.11.5" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc" - integrity sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng== - dependencies: - "@types/node" "*" - "@types/body-parser@*": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -88,11 +49,6 @@ dependencies: "@types/node" "*" -"@types/deasync@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@types/deasync/-/deasync-0.1.0.tgz#b2bd6c3fcde3cf67b8be4c2f70136ba8f157b45a" - integrity sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA== - "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -116,11 +72,6 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" -"@types/ip-regex@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/ip-regex/-/ip-regex-3.0.0.tgz#f06748a44dd47810bb24555958b4b410cfe5abab" - integrity sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw== - "@types/jest@^23.0.2": version "23.3.12" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.12.tgz#7e0ced251fa94c3bc2d1023d4b84b2992fa06376" @@ -136,12 +87,7 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" integrity sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA== -"@types/node@*": - version "12.0.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.2.tgz#3452a24edf9fea138b48fad4a0a028a683da1e40" - integrity sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA== - -"@types/node@^10.3.2", "@types/node@^10.3.3": +"@types/node@*", "@types/node@^10.3.2", "@types/node@^10.3.3": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== @@ -1419,16 +1365,14 @@ binary-extensions@^1.0.0: integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== bindings@^1.2.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" + version "1.3.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5" + integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew== bip39@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c" - integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg== + version "2.5.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" + integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== dependencies: create-hash "^1.1.0" pbkdf2 "^3.0.9" @@ -1456,7 +1400,7 @@ bluebird@^3.4.7, bluebird@^3.5.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== @@ -1690,14 +1634,6 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" - integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1788,11 +1724,6 @@ camelcase@^4.0.0, camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -1813,11 +1744,6 @@ caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.300008 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000929.tgz#7b391b781a9c3097ecc39ea053301aea8ea16317" integrity sha512-n2w1gPQSsYyorSVYqPMqbSaz1w7o9ZC8VhOEGI9T5MfGDzp7sbopQxG6GaQmYsaq13Xfx/mkxJUWC1Dz3oZfzw== -canvas-renderer@~2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/canvas-renderer/-/canvas-renderer-2.1.1.tgz#d91fe9511ab48056ff9fa8a04514bede76535f55" - integrity sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw== - capture-exit@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" @@ -1859,7 +1785,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3465,11 +3391,6 @@ file-loader@0.11.2: dependencies: loader-utils "^1.0.2" -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -4204,9 +4125,9 @@ icss-utils@^2.1.0: postcss "^6.0.1" ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== iferr@^0.1.5: version "0.1.5" @@ -4335,11 +4256,6 @@ ip-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-3.0.0.tgz#0a934694b4066558c46294244a23cc33116bf732" integrity sha512-T8wDtjy+Qf2TAPDQmBp0eGKJ8GavlWlUnamr3wRn6vvdZlKVuJXXMlSncYFRYgVHOM3If5NR1H4+OvVQU9Idvg== -ip-regex@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.1.0.tgz#5ad62f685a14edb421abebc2fff8db94df67b455" - integrity sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA== - ip-validator@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/ip-validator/-/ip-validator-0.0.1.tgz#659eb6001d38c35beab51455a2f751b843299eb5" @@ -4833,13 +4749,6 @@ istanbul-reports@^1.5.1: dependencies: handlebars "^4.0.3" -jdenticon@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/jdenticon/-/jdenticon-2.1.1.tgz#f9288e87b3466e2c5f05948c68db58e1c9e1b800" - integrity sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg== - dependencies: - canvas-renderer "~2.1.1" - jest-changed-files@^22.2.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.4.3.tgz#8882181e022c38bd46a2e4d18d44d19d90a90fb2" @@ -5842,7 +5751,7 @@ longest@^1.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -6160,11 +6069,6 @@ mock-socket@^8.0.2: dependencies: url-parse "^1.2.0" -moment@^2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== - moo@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" @@ -6210,12 +6114,7 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.4.0: - version "2.13.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" - integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== - -nan@^2.9.2: +nan@^2.4.0, nan@^2.9.2: version "2.12.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== @@ -6574,33 +6473,27 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -oo7-react@^0.8.13: - version "0.8.13" - resolved "https://registry.yarnpkg.com/oo7-react/-/oo7-react-0.8.13.tgz#fbc63eac0397d72a1a5d768481fbbda533503e2e" - integrity sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q== +oo7-react@^0.8.10: + version "0.8.10" + resolved "https://registry.yarnpkg.com/oo7-react/-/oo7-react-0.8.10.tgz#c04bd418d87f3b5bd32949cefb116eee5a4bb86c" + integrity sha512-kLP9umZt5StkWlZ2TahDIMTg9umsPzMFeXoIi5ClujwrQD+2uRqLaYWiPDprzYlSMpOZgQ0oqZtBW6tUCdG8GA== dependencies: - oo7 "^0.7.12" + oo7 "^0.7.9" react "^16.5.2" -oo7-substrate@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/oo7-substrate/-/oo7-substrate-0.8.0.tgz#690a6ec145287ae0cbb5647146f3ce76a8a28ff3" - integrity sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA== +oo7-substrate@^0.4.12: + version "0.4.12" + resolved "https://registry.yarnpkg.com/oo7-substrate/-/oo7-substrate-0.4.12.tgz#f27ffa10b0143e75ba2677ddbebbaf9aa5096078" + integrity sha512-oz0UePdDViE8y9oLgWBImwhIRkElcaqHmG9dIAnHd12O1FPWGos1LHeDSKVblXfvtiAs18n2OMe5JJTNBGd6yQ== dependencies: - "@polkadot/util" "^0.41.1" - "@polkadot/wasm-crypto" "^0.5.1" - "@polkadot/wasm-schnorrkel" "^0.3.1" base-x "^3.0.4" bip39 "^2.5.0" blakejs "^1.1.0" bs58 "^4.0.1" - buffer "^5.2.1" change-case "^3.0.2" isomorphic-fetch "^2.2.1" isomorphic-ws "^4.0.1" - jdenticon "^2.1.1" - oo7 "^0.7.12" - pbkdf2 "^3.0.17" + oo7 "^0.7.9" ss58 "^1.0.2" text-encoding "^0.7.0" text-encoding-polyfill "^0.6.7" @@ -6608,10 +6501,10 @@ oo7-substrate@^0.8.0: ws "^6.1.2" xxhashjs "^0.2.2" -oo7@^0.7.12: - version "0.7.12" - resolved "https://registry.yarnpkg.com/oo7/-/oo7-0.7.12.tgz#bd7a01ba4e815c1fcde9bea2a9a8226d06ec781e" - integrity sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA== +oo7@^0.7.9: + version "0.7.9" + resolved "https://registry.yarnpkg.com/oo7/-/oo7-0.7.9.tgz#ea9c14121fd3a24934b12d58b5f2a185a9609059" + integrity sha512-QcK4x8xY+rZeBBqS1HDe+kyf0g1XEdiqXcEIJl7dBxau+ICU8bGdcJ+d+POMj8/fRH6o9oyaIe2QujytxzERLg== opn@5.2.0: version "5.2.0" @@ -6899,7 +6792,7 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: +pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== @@ -6954,15 +6847,15 @@ pn@^1.1.0: resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== -polkadot-identicon@^1.1.45: - version "1.1.45" - resolved "https://registry.yarnpkg.com/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz#9c8f5644be15f33e47200120e81cca068e4d26ed" - integrity sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w== +polkadot-identicon@^1.1.36: + version "1.1.36" + resolved "https://registry.yarnpkg.com/polkadot-identicon/-/polkadot-identicon-1.1.36.tgz#ef14ebdc788367b20acf05a1613c806211fd44d0" + integrity sha512-wDOpqHG39t41R0mHj7PqMHnZGRgPfjtxMMBGaKTO05cp+xwOtamDUdx2e0LaG4KYZaq8KbkDXK9XKdASTGuDKw== dependencies: blake2js "^1.0.0" - oo7 "^0.7.12" - oo7-react "^0.8.13" - oo7-substrate "^0.8.0" + oo7 "^0.7.9" + oo7-react "^0.8.10" + oo7-substrate "^0.4.12" react "^16.4.2" ss58 "^1.0.0" @@ -7402,7 +7295,7 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" -prop-types@^15.6.0: +prop-types@^15.6.0, prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== @@ -7410,15 +7303,6 @@ prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@^15.6.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - proxy-addr@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" @@ -7555,20 +7439,13 @@ randomatic@^3.0.0: kind-of "^6.0.0" math-random "^1.0.1" -randombytes@^2.0.0, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== dependencies: safe-buffer "^5.1.0" -randombytes@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - randomfill@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" @@ -7651,11 +7528,6 @@ react-is@^16.6.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa" integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g== -react-is@^16.8.1: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" - integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== - react-measure@^2.2.4: version "2.2.5" resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.2.5.tgz#35f6be9a8c31d61a4cf847282f9d54c310eb1624" @@ -7738,15 +7610,25 @@ react@16.4.0: object-assign "^4.1.1" prop-types "^15.6.0" -react@^16.4.2, react@^16.5.2: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" - integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== +react@^16.4.2: + version "16.7.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" + integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.6" + scheduler "^0.12.0" + +react@^16.5.2: + version "16.8.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.0.tgz#8533f0e4af818f448a276eae71681d09e8dd970a" + integrity sha512-g+nikW2D48kqgWSPwNo0NH9tIGG3DsQFlrtrQ1kj6W77z5ahyIHG0w8kPpz4Sdj6gyLnz0lEd/xsjOoGge2MYQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.0" read-pkg-up@^1.0.1: version "1.0.1" @@ -8241,10 +8123,10 @@ scheduler@^0.12.0: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.13.6: - version "0.13.6" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" - integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== +scheduler@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.0.tgz#e701f62e1b3e78d2bbb264046d4e7260f12184dd" + integrity sha512-w7aJnV30jc7OsiZQNPVmBc+HooZuvQZIZIShKutC3tnMFMkcwVN9CZRRSSNw03OnSCKmEkK8usmwcw6dqBaLzw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -9432,9 +9314,9 @@ universalify@^0.1.0: integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== unorm@^1.3.3: - version "1.5.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.5.0.tgz#01fa9b76f1c60f7916834605c032aa8962c3f00a" - integrity sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw== + version "1.4.1" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" + integrity sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA= unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -9906,9 +9788,9 @@ ws@^5.2.0: async-limiter "~1.0.0" ws@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + version "6.1.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.3.tgz#d2d2e5f0e3c700ef2de89080ebc0ac6e1bf3a72d" + integrity sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg== dependencies: async-limiter "~1.0.0" From 0da0c4496bc2aa7d1aa6a6e7bcb9cb206a8c640f Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 08:12:53 +0200 Subject: [PATCH 40/50] Update polkadot-identicon in frontend Change version number to `^1.1.45` and run `npm update polkadot-identicon`. --- packages/frontend/package-lock.json | 537 +++++++++++++++++++++++++++- packages/frontend/package.json | 2 +- 2 files changed, 527 insertions(+), 12 deletions(-) diff --git a/packages/frontend/package-lock.json b/packages/frontend/package-lock.json index bed26cdb7..d5bc10438 100644 --- a/packages/frontend/package-lock.json +++ b/packages/frontend/package-lock.json @@ -39,11 +39,87 @@ } } }, + "@babel/runtime": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.4.tgz", + "integrity": "sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, + "@polkadot/util": { + "version": "0.41.1", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-0.41.1.tgz", + "integrity": "sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ==", + "requires": { + "@babel/runtime": "^7.4.0", + "@types/bn.js": "^4.11.4", + "@types/deasync": "^0.1.0", + "@types/ip-regex": "^3.0.0", + "bn.js": "^4.11.8", + "camelcase": "^5.2.0", + "chalk": "^2.4.2", + "ip-regex": "^4.0.0", + "moment": "^2.24.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@polkadot/wasm-crypto": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz", + "integrity": "sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg==" + }, + "@polkadot/wasm-schnorrkel": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz", + "integrity": "sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA==" + }, "@tanem/svg-injector": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-1.2.1.tgz", "integrity": "sha512-mA5Q5ulPoGQ+e08Vts1R6xw2QU0BKEnMH/KcqoYoS7Gk6imvMTpyFPeu1g+NOZObSIoAzA3/kRzY8m96cEBA2A==" }, + "@types/bn.js": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", + "integrity": "sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng==", + "requires": { + "@types/node": "*" + } + }, + "@types/deasync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@types/deasync/-/deasync-0.1.0.tgz", + "integrity": "sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA==" + }, + "@types/ip-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/ip-regex/-/ip-regex-3.0.0.tgz", + "integrity": "sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw==" + }, "@types/jest": { "version": "23.0.2", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.0.2.tgz", @@ -58,8 +134,7 @@ "@types/node": { "version": "10.3.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.2.tgz", - "integrity": "sha512-9NfEUDp3tgRhmoxzTpTo+lq+KIVFxZahuRX0LHF/9IzKHaWuoWsIrrJ61zw5cnnlGINX8lqJzXYfQTOICS5Q+A==", - "dev": true + "integrity": "sha512-9NfEUDp3tgRhmoxzTpTo+lq+KIVFxZahuRX0LHF/9IzKHaWuoWsIrrJ61zw5cnnlGINX8lqJzXYfQTOICS5Q+A==" }, "@types/react": { "version": "16.3.17", @@ -1368,6 +1443,14 @@ } } }, + "base-x": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", + "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", @@ -1397,6 +1480,42 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip39": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", + "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "blake2js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/blake2js/-/blake2js-1.0.0.tgz", + "integrity": "sha1-tokMOU3blAXQbZp6089lZxHcrYk=", + "requires": { + "bindings": "^1.2.1", + "debug": "^2.2.0", + "nan": "^2.4.0", + "readable-stream": "^2.1.4" + } + }, + "blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -1627,6 +1746,14 @@ "electron-to-chromium": "^1.3.30" } }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, "bser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", @@ -1785,6 +1912,11 @@ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000878.tgz", "integrity": "sha512-/dCGTdLCnjVJno1mFRn7Y6eit3AYaeFzSrMQHCoK0LEQaWl5snuLex1Ky4b8/Qu2ig5NgTX4cJx65hH9546puA==" }, + "canvas-renderer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/canvas-renderer/-/canvas-renderer-2.1.1.tgz", + "integrity": "sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw==" + }, "capture-exit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", @@ -1841,6 +1973,31 @@ } } }, + "change-case": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", + "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", + "requires": { + "camel-case": "^3.0.0", + "constant-case": "^2.0.0", + "dot-case": "^2.1.0", + "header-case": "^1.0.0", + "is-lower-case": "^1.1.0", + "is-upper-case": "^1.1.0", + "lower-case": "^1.1.1", + "lower-case-first": "^1.0.0", + "no-case": "^2.3.2", + "param-case": "^2.1.0", + "pascal-case": "^2.0.0", + "path-case": "^2.1.0", + "sentence-case": "^2.1.0", + "snake-case": "^2.1.0", + "swap-case": "^1.1.0", + "title-case": "^2.1.0", + "upper-case": "^1.1.1", + "upper-case-first": "^1.1.0" + } + }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", @@ -2123,6 +2280,15 @@ "date-now": "^0.1.4" } }, + "constant-case": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", + "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", + "requires": { + "snake-case": "^2.1.0", + "upper-case": "^1.1.1" + } + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -2522,6 +2688,11 @@ "integrity": "sha512-G5HnoK8nOiAq3DXIEoY2n/8Vb7Lgrms+jGJl8E4EJpQEeVONEnPFJSl8IK505wPBoxxtrtHhrRm4WX2GgdqarA==", "dev": true }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -2857,6 +3028,14 @@ "domelementtype": "1" } }, + "dot-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", + "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", + "requires": { + "no-case": "^2.2.0" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -3544,6 +3723,11 @@ "loader-utils": "^1.0.2" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -3784,11 +3968,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3801,15 +3987,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3912,7 +4101,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3922,6 +4112,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3934,17 +4125,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3961,6 +4155,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4033,7 +4228,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4043,6 +4239,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4148,6 +4345,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4515,6 +4713,15 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, + "header-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", + "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.3" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -4983,6 +5190,11 @@ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, + "ip-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", + "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==" + }, "ipaddr.js": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", @@ -5153,6 +5365,14 @@ "is-path-inside": "^1.0.0" } }, + "is-lower-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", + "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", + "requires": { + "lower-case": "^1.1.0" + } + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -5276,6 +5496,14 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-upper-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", + "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", + "requires": { + "upper-case": "^1.1.0" + } + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -5315,6 +5543,11 @@ "whatwg-fetch": ">=0.10.0" } }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -5454,6 +5687,14 @@ "handlebars": "^4.0.3" } }, + "jdenticon": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jdenticon/-/jdenticon-2.1.1.tgz", + "integrity": "sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg==", + "requires": { + "canvas-renderer": "~2.1.1" + } + }, "jest": { "version": "22.4.2", "resolved": "https://registry.npmjs.org/jest/-/jest-22.4.2.tgz", @@ -6507,6 +6748,14 @@ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" }, + "lower-case-first": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", + "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", + "requires": { + "lower-case": "^1.1.2" + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -6769,6 +7018,11 @@ "minimist": "0.0.8" } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -6809,8 +7063,7 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "optional": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nanomatch": { "version": "1.2.13", @@ -7102,6 +7355,116 @@ "mimic-fn": "^1.0.0" } }, + "oo7": { + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/oo7/-/oo7-0.7.12.tgz", + "integrity": "sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA==" + }, + "oo7-react": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/oo7-react/-/oo7-react-0.8.13.tgz", + "integrity": "sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q==", + "requires": { + "oo7": "^0.7.12", + "react": "^16.5.2" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + } + } + }, + "oo7-substrate": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/oo7-substrate/-/oo7-substrate-0.8.0.tgz", + "integrity": "sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA==", + "requires": { + "@polkadot/util": "^0.41.1", + "@polkadot/wasm-crypto": "^0.5.1", + "@polkadot/wasm-schnorrkel": "^0.3.1", + "base-x": "^3.0.4", + "bip39": "^2.5.0", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "buffer": "^5.2.1", + "change-case": "^3.0.2", + "isomorphic-fetch": "^2.2.1", + "isomorphic-ws": "^4.0.1", + "jdenticon": "^2.1.1", + "oo7": "^0.7.12", + "pbkdf2": "^3.0.17", + "ss58": "^1.0.2", + "text-encoding": "^0.7.0", + "text-encoding-polyfill": "^0.6.7", + "tweetnacl": "^1.0.0", + "ws": "^6.1.2", + "xxhashjs": "^0.2.2" + }, + "dependencies": { + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "tweetnacl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", + "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "opn": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", @@ -7283,6 +7646,15 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "requires": { + "camel-case": "^3.0.0", + "upper-case-first": "^1.1.0" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -7293,6 +7665,14 @@ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" }, + "path-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", + "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", + "requires": { + "no-case": "^2.2.0" + } + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -7396,6 +7776,52 @@ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, + "polkadot-identicon": { + "version": "1.1.45", + "resolved": "https://registry.npmjs.org/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz", + "integrity": "sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w==", + "requires": { + "blake2js": "^1.0.0", + "oo7": "^0.7.12", + "oo7-react": "^0.8.13", + "oo7-substrate": "^0.8.0", + "react": "^16.4.2", + "ss58": "^1.0.0" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + } + } + }, "portfinder": { "version": "1.0.17", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", @@ -8895,6 +9321,11 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.1.tgz", "integrity": "sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw==" }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + }, "react-scripts-ts": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/react-scripts-ts/-/react-scripts-ts-2.17.0.tgz", @@ -9438,6 +9869,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", @@ -9499,6 +9939,15 @@ } } }, + "sentence-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", + "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", + "requires": { + "no-case": "^2.2.0", + "upper-case-first": "^1.1.2" + } + }, "serialize-javascript": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", @@ -9623,6 +10072,14 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" }, + "snake-case": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", + "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", + "requires": { + "no-case": "^2.2.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -9883,6 +10340,15 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "ss58": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ss58/-/ss58-1.0.2.tgz", + "integrity": "sha512-hCpPJ12+GgsYsyVW2dXY6p3KfqZgLFA9zrKp5cgEx3x93JjPG4DDm6lu0Zp87FW0CSRan3gy7jlF4ZCjHqS7Ig==", + "requires": { + "blakejs": "^1.1.0", + "bs58": "^4.0.1" + } + }, "sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", @@ -10153,6 +10619,15 @@ "serviceworker-cache-polyfill": "^4.0.0" } }, + "swap-case": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", + "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", + "requires": { + "lower-case": "^1.1.1", + "upper-case": "^1.1.1" + } + }, "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", @@ -10183,6 +10658,16 @@ "require-main-filename": "^1.0.1" } }, + "text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, + "text-encoding-polyfill": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/text-encoding-polyfill/-/text-encoding-polyfill-0.6.7.tgz", + "integrity": "sha512-/DZ1XJqhbqRkCop6s9ZFu8JrFRwmVuHg4quIRm+ziFkR3N3ec6ck6yBvJ1GYeEQZhLVwRW0rZE+C3SSJpy0RTg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10230,6 +10715,15 @@ "setimmediate": "^1.0.4" } }, + "title-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", + "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.0.3" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -10699,6 +11193,11 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, + "unorm": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.5.0.tgz", + "integrity": "sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -10784,6 +11283,14 @@ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "requires": { + "upper-case": "^1.1.1" + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -11649,6 +12156,14 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, + "xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "requires": { + "cuint": "^0.2.2" + } + }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 1e674a330..83feed4df 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -21,7 +21,7 @@ "dependencies": { "@fnando/sparkline": "maciejhirsz/sparkline", "@types/react-measure": "^2.0.5", - "polkadot-identicon": "^1.1.36", + "polkadot-identicon": "^1.1.45", "react": "16.4.0", "react-dom": "16.4.0", "react-measure": "^2.2.4", From 64d08c3efb070ea7f3a88686c72dcd49fcdd3e5c Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 08:14:02 +0200 Subject: [PATCH 41/50] Run yarn install --- yarn.lock | 138 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 114 insertions(+), 24 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2a59eec27..a6f033d5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,15 +25,54 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.4.0": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.4.tgz#dc2e34982eb236803aa27a07fea6857af1b9171d" + integrity sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg== + dependencies: + regenerator-runtime "^0.13.2" + "@fnando/sparkline@maciejhirsz/sparkline": version "0.3.10" resolved "https://codeload.github.com/maciejhirsz/sparkline/tar.gz/2bdb002b171436be078a84f1e4e617a44ef1fb42" +"@polkadot/util@^0.41.1": + version "0.41.1" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.41.1.tgz#b67762a0a7408138d843adc7240944e704e819e7" + integrity sha512-1mFHxxdXyRgeFk0ygfJklzsf6HiEEMikrpUgr+3Dw5S7KromjPD8EbWkpcZQZ3Png5PTwGyjrx7MYY4Ajiu5xQ== + dependencies: + "@babel/runtime" "^7.4.0" + "@types/bn.js" "^4.11.4" + "@types/deasync" "^0.1.0" + "@types/ip-regex" "^3.0.0" + bn.js "^4.11.8" + camelcase "^5.2.0" + chalk "^2.4.2" + ip-regex "^4.0.0" + moment "^2.24.0" + +"@polkadot/wasm-crypto@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-0.5.1.tgz#3d5734d6dc2f5174a411689f78538287d21bd710" + integrity sha512-8h7uz85bvLVirtbxLkELr9H25oqAfgnQuDP6FP3QJeag7VfMtVvRF5U2JWGgsiUSiRg+UJnTuCleOSDnageRmg== + +"@polkadot/wasm-schnorrkel@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-schnorrkel/-/wasm-schnorrkel-0.3.1.tgz#08287848f769dee4955517348905888bd289f277" + integrity sha512-2J/lNZe7oDWvzUbsEfvKfiiAvBIBbIsppeBGahwSg2Y+cLweQgThXGizPpQoPo0tHxgMKdTi6jhPu7tLzCW/cA== + "@tanem/svg-injector@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@tanem/svg-injector/-/svg-injector-1.2.1.tgz#3120e90246d0eb3c4fc6c61586a6f028a3c658ae" integrity sha512-mA5Q5ulPoGQ+e08Vts1R6xw2QU0BKEnMH/KcqoYoS7Gk6imvMTpyFPeu1g+NOZObSIoAzA3/kRzY8m96cEBA2A== +"@types/bn.js@^4.11.4": + version "4.11.5" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.5.tgz#40e36197433f78f807524ec623afcf0169ac81dc" + integrity sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng== + dependencies: + "@types/node" "*" + "@types/body-parser@*": version "1.17.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" @@ -49,6 +88,11 @@ dependencies: "@types/node" "*" +"@types/deasync@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@types/deasync/-/deasync-0.1.0.tgz#b2bd6c3fcde3cf67b8be4c2f70136ba8f157b45a" + integrity sha512-jxUH53LtGvbIL3TX2hD/XQuAgYJeATtx9kDXq5XtCZrWQABsiCQPjWi/KQXECUF+p9FuR6/tawnEDjXlEr4rFA== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -72,6 +116,11 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" +"@types/ip-regex@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/ip-regex/-/ip-regex-3.0.0.tgz#f06748a44dd47810bb24555958b4b410cfe5abab" + integrity sha512-4j26qYCikXbIaypgqdGQhhIvYfTR+40i/05jVQB8oc57RbROEkBocdIUZO7fOhyqJsx7WRY36ySW8hoUZn7Fgw== + "@types/jest@^23.0.2": version "23.3.12" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.12.tgz#7e0ced251fa94c3bc2d1023d4b84b2992fa06376" @@ -1400,7 +1449,7 @@ bluebird@^3.4.7, bluebird@^3.5.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== @@ -1634,6 +1683,14 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1724,6 +1781,11 @@ camelcase@^4.0.0, camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelcase@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -1744,6 +1806,11 @@ caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.300008 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000929.tgz#7b391b781a9c3097ecc39ea053301aea8ea16317" integrity sha512-n2w1gPQSsYyorSVYqPMqbSaz1w7o9ZC8VhOEGI9T5MfGDzp7sbopQxG6GaQmYsaq13Xfx/mkxJUWC1Dz3oZfzw== +canvas-renderer@~2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/canvas-renderer/-/canvas-renderer-2.1.1.tgz#d91fe9511ab48056ff9fa8a04514bede76535f55" + integrity sha512-/V0XetN7s1Mk3NO7x2wxPZYv0pLMQtGAhecuOuKR88beiYCUle1AbCcFZNLu+4NVzi9RVHS0rXtIgzPEaKidLw== + capture-exit@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" @@ -1785,7 +1852,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -4256,6 +4323,11 @@ ip-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-3.0.0.tgz#0a934694b4066558c46294244a23cc33116bf732" integrity sha512-T8wDtjy+Qf2TAPDQmBp0eGKJ8GavlWlUnamr3wRn6vvdZlKVuJXXMlSncYFRYgVHOM3If5NR1H4+OvVQU9Idvg== +ip-regex@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.1.0.tgz#5ad62f685a14edb421abebc2fff8db94df67b455" + integrity sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA== + ip-validator@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/ip-validator/-/ip-validator-0.0.1.tgz#659eb6001d38c35beab51455a2f751b843299eb5" @@ -4749,6 +4821,13 @@ istanbul-reports@^1.5.1: dependencies: handlebars "^4.0.3" +jdenticon@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/jdenticon/-/jdenticon-2.1.1.tgz#f9288e87b3466e2c5f05948c68db58e1c9e1b800" + integrity sha512-bFD210JMaK2RMHGSkdDXqdQzasMrVIGDfxUMXD/Uwq2t7g9Njb4T6kms5TrocsLU0CDmQCoB0laGJ6JETiprsg== + dependencies: + canvas-renderer "~2.1.1" + jest-changed-files@^22.2.0: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.4.3.tgz#8882181e022c38bd46a2e4d18d44d19d90a90fb2" @@ -6069,6 +6148,11 @@ mock-socket@^8.0.2: dependencies: url-parse "^1.2.0" +moment@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + moo@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" @@ -6473,27 +6557,33 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -oo7-react@^0.8.10: - version "0.8.10" - resolved "https://registry.yarnpkg.com/oo7-react/-/oo7-react-0.8.10.tgz#c04bd418d87f3b5bd32949cefb116eee5a4bb86c" - integrity sha512-kLP9umZt5StkWlZ2TahDIMTg9umsPzMFeXoIi5ClujwrQD+2uRqLaYWiPDprzYlSMpOZgQ0oqZtBW6tUCdG8GA== +oo7-react@^0.8.13: + version "0.8.13" + resolved "https://registry.yarnpkg.com/oo7-react/-/oo7-react-0.8.13.tgz#fbc63eac0397d72a1a5d768481fbbda533503e2e" + integrity sha512-1WoJf/pYDiZAkd+rilH9xs6FR6k4LKck/uCPVzClTnp/uFvsR8pxlbTHvNPvOqspxob76qSbstUv7IVdO/TQ7Q== dependencies: - oo7 "^0.7.9" + oo7 "^0.7.12" react "^16.5.2" -oo7-substrate@^0.4.12: - version "0.4.12" - resolved "https://registry.yarnpkg.com/oo7-substrate/-/oo7-substrate-0.4.12.tgz#f27ffa10b0143e75ba2677ddbebbaf9aa5096078" - integrity sha512-oz0UePdDViE8y9oLgWBImwhIRkElcaqHmG9dIAnHd12O1FPWGos1LHeDSKVblXfvtiAs18n2OMe5JJTNBGd6yQ== +oo7-substrate@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/oo7-substrate/-/oo7-substrate-0.8.0.tgz#690a6ec145287ae0cbb5647146f3ce76a8a28ff3" + integrity sha512-ltglsNXZNmiDsJ5q4LYx0tf0SN0CVjW5fSifwrBRe/objxG2fYXogZ4eiNdsLJrTddvskv+3o5JpvFw/D3PCUA== dependencies: + "@polkadot/util" "^0.41.1" + "@polkadot/wasm-crypto" "^0.5.1" + "@polkadot/wasm-schnorrkel" "^0.3.1" base-x "^3.0.4" bip39 "^2.5.0" blakejs "^1.1.0" bs58 "^4.0.1" + buffer "^5.2.1" change-case "^3.0.2" isomorphic-fetch "^2.2.1" isomorphic-ws "^4.0.1" - oo7 "^0.7.9" + jdenticon "^2.1.1" + oo7 "^0.7.12" + pbkdf2 "^3.0.17" ss58 "^1.0.2" text-encoding "^0.7.0" text-encoding-polyfill "^0.6.7" @@ -6501,10 +6591,10 @@ oo7-substrate@^0.4.12: ws "^6.1.2" xxhashjs "^0.2.2" -oo7@^0.7.9: - version "0.7.9" - resolved "https://registry.yarnpkg.com/oo7/-/oo7-0.7.9.tgz#ea9c14121fd3a24934b12d58b5f2a185a9609059" - integrity sha512-QcK4x8xY+rZeBBqS1HDe+kyf0g1XEdiqXcEIJl7dBxau+ICU8bGdcJ+d+POMj8/fRH6o9oyaIe2QujytxzERLg== +oo7@^0.7.12: + version "0.7.12" + resolved "https://registry.yarnpkg.com/oo7/-/oo7-0.7.12.tgz#bd7a01ba4e815c1fcde9bea2a9a8226d06ec781e" + integrity sha512-nVmxwLIiVCY4Aid6/+p2ujJ2mj3yh15zQ3xSl3UPui7U37DJJfD0KmuMjp+XOWH1HxTkKhIKDgR34eEhFHNxgA== opn@5.2.0: version "5.2.0" @@ -6792,7 +6882,7 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -pbkdf2@^3.0.3, pbkdf2@^3.0.9: +pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== @@ -6847,15 +6937,15 @@ pn@^1.1.0: resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== -polkadot-identicon@^1.1.36: - version "1.1.36" - resolved "https://registry.yarnpkg.com/polkadot-identicon/-/polkadot-identicon-1.1.36.tgz#ef14ebdc788367b20acf05a1613c806211fd44d0" - integrity sha512-wDOpqHG39t41R0mHj7PqMHnZGRgPfjtxMMBGaKTO05cp+xwOtamDUdx2e0LaG4KYZaq8KbkDXK9XKdASTGuDKw== +polkadot-identicon@^1.1.45: + version "1.1.45" + resolved "https://registry.yarnpkg.com/polkadot-identicon/-/polkadot-identicon-1.1.45.tgz#9c8f5644be15f33e47200120e81cca068e4d26ed" + integrity sha512-UFdxnfvQPHnbKadKibbCGsFrO6XfOy+OeVf+yAyp24CAnSwVujl7OiIdBxnV1V5BVSU61Cfan96grj8VznZk/w== dependencies: blake2js "^1.0.0" - oo7 "^0.7.9" - oo7-react "^0.8.10" - oo7-substrate "^0.4.12" + oo7 "^0.7.12" + oo7-react "^0.8.13" + oo7-substrate "^0.8.0" react "^16.4.2" ss58 "^1.0.0" From acd121842cc84d41ac26619b9271bb6df0c4526b Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 08:18:27 +0200 Subject: [PATCH 42/50] Update react-measure to 2.3.0 Changed version number, ran cd packages/frontend/ && npm update react-reasure && cd ../../ && yarn install --- packages/frontend/package-lock.json | 54 ++++++++++++++++++++++++++--- packages/frontend/package.json | 2 +- yarn.lock | 8 ++--- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/packages/frontend/package-lock.json b/packages/frontend/package-lock.json index d5bc10438..29ad4e73d 100644 --- a/packages/frontend/package-lock.json +++ b/packages/frontend/package-lock.json @@ -3950,7 +3950,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4315,7 +4316,8 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4363,6 +4365,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4401,11 +4404,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -4419,6 +4424,11 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, + "get-node-dimensions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz", + "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ==" + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -9326,6 +9336,37 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" }, + "react-measure": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.3.0.tgz", + "integrity": "sha512-dwAvmiOeblj5Dvpnk8Jm7Q8B4THF/f1l1HtKVi0XDecsG6LXwGvzV5R1H32kq3TW6RW64OAf5aoQxpIgLa4z8A==", + "requires": { + "@babel/runtime": "^7.2.0", + "get-node-dimensions": "^1.2.1", + "prop-types": "^15.6.2", + "resize-observer-polyfill": "^1.5.0" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "react-scripts-ts": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/react-scripts-ts/-/react-scripts-ts-2.17.0.tgz", @@ -9706,6 +9747,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 83feed4df..b17ec1e7b 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -24,7 +24,7 @@ "polkadot-identicon": "^1.1.45", "react": "16.4.0", "react-dom": "16.4.0", - "react-measure": "^2.2.4", + "react-measure": "^2.3.0", "react-scripts-ts": "2.17.0", "react-svg": "^4.1.1", "stable": "^0.1.8" diff --git a/yarn.lock b/yarn.lock index a6f033d5c..12721f9fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7618,10 +7618,10 @@ react-is@^16.6.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa" integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g== -react-measure@^2.2.4: - version "2.2.5" - resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.2.5.tgz#35f6be9a8c31d61a4cf847282f9d54c310eb1624" - integrity sha512-j1OE5U3AfX97Tk/LNkn2KSdE03hGgBOqUoQQ8QdxHoAudAvP1K1R7hvEH+S5zHILFh7ejGCKK3wWZOMDcHL3mA== +react-measure@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.3.0.tgz#75835d39abec9ae13517f35a819c160997a7a44e" + integrity sha512-dwAvmiOeblj5Dvpnk8Jm7Q8B4THF/f1l1HtKVi0XDecsG6LXwGvzV5R1H32kq3TW6RW64OAf5aoQxpIgLa4z8A== dependencies: "@babel/runtime" "^7.2.0" get-node-dimensions "^1.2.1" From f198278a35f1e7b49a55c091332b99fc6c2d059b Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:02:22 +0200 Subject: [PATCH 43/50] Improve typing by introducing partial type --- packages/frontend/src/AfgHandling.ts | 19 +++++++++---------- packages/frontend/src/App.tsx | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index fd03c74af..da2f23775 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -51,9 +51,8 @@ export class AfgHandling { voter: Types.Address, what: string, ) { - const obj = {}; - obj[what === "prevote" ? "Prevote" : "Precommit"] = true; - this.updateConsensusInfo(height, addr, voter, obj); + const data = what === "prevote" ? { Prevote: true } : { Precommit: true }; + this.updateConsensusInfo(height, addr, voter, data as Partial); const op = (i: Types.BlockNumber, view: Types.ConsensusView) => { const consensusDetail = view[addr][voter]; @@ -72,7 +71,7 @@ export class AfgHandling { finalizedHeight: Types.BlockNumber, finalizedHash: Types.BlockHash, ) { - const obj = { + const data = { Finalized: true, FinalizedHash: finalizedHash, FinalizedHeight: finalizedHeight, @@ -83,8 +82,8 @@ export class AfgHandling { // we can set them and display them in the ui. Prevote: true, Precommit: true, - }; - this.updateConsensusInfo(finalizedHeight, addr, addr, obj); + } as Types.ConsensusDetail; + this.updateConsensusInfo(finalizedHeight, addr, addr, data); } // A Prevote or Precommit on a block implicitly includes @@ -239,7 +238,7 @@ export class AfgHandling { height: Types.BlockNumber, addr: Types.Address, voter: Types.Address, - obj: object, + data: Partial, ) { const consensusInfo = this.getState().consensusInfo; this.initialiseConsensusView(consensusInfo, height, addr, voter); @@ -247,9 +246,9 @@ export class AfgHandling { const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); const [, consensusView] = consensusInfo[index]; - for (const o in obj) { - if (obj.hasOwnProperty(o)) { - consensusView[addr][voter][o] = obj[o]; + for (const o in data) { + if (data.hasOwnProperty(o)) { + consensusView[addr][voter][o] = data[o]; } } diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 80e0ccfde..8c7bf3191 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -53,7 +53,7 @@ export default class App extends React.Component<{}, State> { status: 'offline', best: 0 as Types.BlockNumber, finalized: 0 as Types.BlockNumber, - consensusInfo: new Array(), + consensusInfo: new Array() as Types.ConsensusInfo, authorities: new Array() as Types.Authorities, authoritySetId: -1 as Types.AuthoritySetId, sendFinality: false, From 5da7937061c8a5f4769b1ed2dcf63b4ee3ae5917 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:05:00 +0200 Subject: [PATCH 44/50] Reduce indexing operations --- packages/frontend/src/AfgHandling.ts | 29 +++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index da2f23775..10184ff07 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -128,19 +128,22 @@ export class AfgHandling { const [consensusView, index] = this.getConsensusView(consensusInfo, height); - consensusView[addr][voter].Finalized = true; - consensusView[addr][voter].FinalizedHeight = height; - consensusView[addr][voter].ImplicitFinalized = true; - consensusView[addr][voter].ImplicitPointer = to; - - // this is extrapolated. if this app was just started up we - // might not yet have received prevotes/precommits. but - // those are a necessary precondition for finalization, so - // we can set them and display them in the ui. - consensusView[addr][voter].Prevote = true; - consensusView[addr][voter].Precommit = true; - consensusView[addr][voter].ImplicitPrevote = true; - consensusView[addr][voter].ImplicitPrecommit = true; + const consensusDetail = { + Finalized: true, + FinalizedHeight: height, + ImplicitFinalized: true, + ImplicitPointer: to, + + // this is extrapolated. if this app was just started up we + // might not yet have received prevotes/precommits. but + // those are a necessary precondition for finalization, so + // we can set them and display them in the ui. + Prevote: true, + Precommit: true, + ImplicitPrevote: true, + ImplicitPrecommit: true, + }; + consensusView[addr][voter] = consensusDetail; if (index !== -1) { consensusInfo[index] = [height, consensusView]; From b02f72d98d25bb0b055ea84bc559a0b9825658ca Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:15:22 +0200 Subject: [PATCH 45/50] Shorten function --- packages/frontend/src/AfgHandling.ts | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index 10184ff07..a533bdf03 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -161,16 +161,15 @@ export class AfgHandling { own: Types.Address, other: Types.Address, ) { - const index = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); + const found = + consensusInfo.find(([blockNumber,]) => blockNumber === height); let consensusView; - if (index === -1) { - consensusView = {} as Types.ConsensusView; + if (found) { + [, consensusView] = found; } else { - const found = consensusInfo[index]; - const [, foundView] = found; - consensusView = foundView; + consensusView = {} as Types.ConsensusView; + consensusInfo.unshift([height, consensusView]); } if (!consensusView[own]) { @@ -180,13 +179,6 @@ export class AfgHandling { if (!consensusView[own][other]) { consensusView[own][other] = {} as Types.ConsensusDetail; } - - if (index === -1) { - // append at the beginning - consensusInfo.unshift([height, consensusView]); - } else { - consensusInfo[index] = [height, consensusView]; - } } // Fill the block cache back from the `to` number to the last block. From 12fd5c92c4ee6326e5c6fd77439c14d28d59fef8 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:19:55 +0200 Subject: [PATCH 46/50] Shorten function --- packages/frontend/src/AfgHandling.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index a533bdf03..fc1e32e7e 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -193,25 +193,14 @@ export class AfgHandling { own: Types.Address, other: Types.Address, ): Types.BlockNumber { - let cont = true; - for (const i of consensusInfo) { - const [height,] = i; + for (const [height, consensusView] of consensusInfo) { if (height >= to) { continue; } this.initialiseConsensusView(consensusInfo, height, own, other); - const index = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - if (index === -1) { - cont = false; - break; - } - - const [, consensusView] = consensusInfo[index]; - - cont = f ? f(height, consensusView) : true; + const cont = f ? f(height, consensusView) : true; if (!cont) { break; } From 770b10f0b0bec74b6cea344d858c82f2e7ff7da5 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:26:27 +0200 Subject: [PATCH 47/50] Introduce initialiseConsensusViewByRef --- packages/frontend/src/AfgHandling.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index fc1e32e7e..08e2340d8 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -172,6 +172,15 @@ export class AfgHandling { consensusInfo.unshift([height, consensusView]); } + this.initialiseConsensusViewByRef(consensusView, own, other); + } + + // Initializes the `ConsensusView` with empty objects. + private initialiseConsensusViewByRef( + consensusView: Types.ConsensusView, + own: Types.Address, + other: Types.Address, + ) { if (!consensusView[own]) { consensusView[own] = {} as Types.ConsensusState; } @@ -198,7 +207,7 @@ export class AfgHandling { continue; } - this.initialiseConsensusView(consensusInfo, height, own, other); + this.initialiseConsensusViewByRef(consensusView, own, other); const cont = f ? f(height, consensusView) : true; if (!cont) { From 0bafe84ca69c1496df716e77527eb9ddcf5cc826 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:36:37 +0200 Subject: [PATCH 48/50] Remove dead conditional branch --- packages/frontend/src/AfgHandling.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index 08e2340d8..976a3375a 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -245,12 +245,7 @@ export class AfgHandling { } } - if (index !== -1) { - consensusInfo[index] = [height, consensusView]; - } else { - // append at the beginning - consensusInfo.unshift([height, consensusView]); - } + consensusInfo[index] = [height, consensusView]; this.updateState({consensusInfo}); } From bce05760fe349814b3e8db21a0b6b9490126c86b Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 19 May 2019 20:48:23 +0200 Subject: [PATCH 49/50] Return consensusView ref from initialiseConsensusView --- packages/frontend/src/AfgHandling.ts | 35 +++++++--------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index 976a3375a..77eba522f 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -98,9 +98,7 @@ export class AfgHandling { voter: Types.Address, ) { const consensusInfo = this.getState().consensusInfo; - this.initialiseConsensusView(consensusInfo, height, addr, voter); - - const [consensusView, index] = this.getConsensusView(consensusInfo, height); + const consensusView = this.initialiseConsensusView(consensusInfo, height, addr, voter); if (what === "prevote") { consensusView[addr][voter].ImplicitPrevote = true; @@ -109,7 +107,6 @@ export class AfgHandling { } consensusView[addr][voter].ImplicitPointer = where; - consensusInfo[index] = [height, consensusView]; this.updateState({consensusInfo}); } @@ -124,9 +121,7 @@ export class AfgHandling { voter: Types.Address, ) { const consensusInfo = this.getState().consensusInfo; - this.initialiseConsensusView(consensusInfo, height, addr, voter); - - const [consensusView, index] = this.getConsensusView(consensusInfo, height); + const consensusView = this.initialiseConsensusView(consensusInfo, height, addr, voter); const consensusDetail = { Finalized: true, @@ -145,12 +140,6 @@ export class AfgHandling { }; consensusView[addr][voter] = consensusDetail; - if (index !== -1) { - consensusInfo[index] = [height, consensusView]; - } else { - consensusInfo.unshift([height, consensusView]); - } - this.updateState({consensusInfo}); } @@ -160,7 +149,7 @@ export class AfgHandling { height: Types.BlockNumber, own: Types.Address, other: Types.Address, - ) { + ) : Types.ConsensusView { const found = consensusInfo.find(([blockNumber,]) => blockNumber === height); @@ -173,6 +162,8 @@ export class AfgHandling { } this.initialiseConsensusViewByRef(consensusView, own, other); + + return consensusView; } // Initializes the `ConsensusView` with empty objects. @@ -217,16 +208,6 @@ export class AfgHandling { return to; } - private getConsensusView( - consensusInfo: Types.ConsensusInfo, - height: Types.BlockNumber, - ): [Types.ConsensusView, number] { - const index = - consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - const [, consensusView] = consensusInfo[index]; - return [consensusView, index]; - } - private updateConsensusInfo( height: Types.BlockNumber, addr: Types.Address, @@ -239,9 +220,9 @@ export class AfgHandling { const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); const [, consensusView] = consensusInfo[index]; - for (const o in data) { - if (data.hasOwnProperty(o)) { - consensusView[addr][voter][o] = data[o]; + for (const k in data) { + if (data.hasOwnProperty(k)) { + consensusView[addr][voter][k] = data[k]; } } From 44863a5c71b39a2d9c1723a848a5a2be70b88bfa Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Mon, 20 May 2019 11:42:52 +0200 Subject: [PATCH 50/50] Handle consensusView ref returned from initialiseConsensusView --- packages/frontend/src/AfgHandling.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/frontend/src/AfgHandling.ts b/packages/frontend/src/AfgHandling.ts index 77eba522f..143d9cf27 100644 --- a/packages/frontend/src/AfgHandling.ts +++ b/packages/frontend/src/AfgHandling.ts @@ -215,10 +215,7 @@ export class AfgHandling { data: Partial, ) { const consensusInfo = this.getState().consensusInfo; - this.initialiseConsensusView(consensusInfo, height, addr, voter); - - const index = consensusInfo.findIndex(([blockNumber,]) => blockNumber === height); - const [, consensusView] = consensusInfo[index]; + const consensusView = this.initialiseConsensusView(consensusInfo, height, addr, voter); for (const k in data) { if (data.hasOwnProperty(k)) { @@ -226,8 +223,6 @@ export class AfgHandling { } } - consensusInfo[index] = [height, consensusView]; - this.updateState({consensusInfo}); } }