diff --git a/apps/1kv-backend/templates/kusama-otv-backend.yaml b/apps/1kv-backend/templates/kusama-otv-backend.yaml index 4d5ad9f95..45fd3fdbe 100644 --- a/apps/1kv-backend/templates/kusama-otv-backend.yaml +++ b/apps/1kv-backend/templates/kusama-otv-backend.yaml @@ -17,7 +17,7 @@ spec: source: repoURL: https://w3f.github.io/helm-charts/ chart: otv-backend - targetRevision: v3.1.1 + targetRevision: v3.1.2 plugin: env: - name: HELM_VALUES diff --git a/apps/1kv-backend/templates/polkadot-otv-backend.yaml b/apps/1kv-backend/templates/polkadot-otv-backend.yaml index 487d82ef6..ea9948c59 100644 --- a/apps/1kv-backend/templates/polkadot-otv-backend.yaml +++ b/apps/1kv-backend/templates/polkadot-otv-backend.yaml @@ -17,7 +17,7 @@ spec: source: repoURL: https://w3f.github.io/helm-charts/ chart: otv-backend - targetRevision: v3.1.1 + targetRevision: v3.1.2 plugin: env: - name: HELM_VALUES diff --git a/charts/otv-backend/Chart.yaml b/charts/otv-backend/Chart.yaml index a5a9e80d9..ab0998573 100644 --- a/charts/otv-backend/Chart.yaml +++ b/charts/otv-backend/Chart.yaml @@ -1,5 +1,5 @@ description: 1K Validators Backend name: otv-backend -version: v3.1.1 -appVersion: v3.1.1 +version: v3.1.2 +appVersion: v3.1.2 apiVersion: v2 diff --git a/packages/common/package.json b/packages/common/package.json index 279a28d65..a49a15382 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@1kv/common", - "version": "3.1.1", + "version": "3.1.2", "description": "Services for running the Thousand Validator Program.", "main": "build/index.js", "types": "build/index.d.ts", diff --git a/packages/common/src/nominator/nominator.ts b/packages/common/src/nominator/nominator.ts index 7da19180f..e8fe7d9fb 100644 --- a/packages/common/src/nominator/nominator.ts +++ b/packages/common/src/nominator/nominator.ts @@ -155,6 +155,7 @@ export default class Nominator extends EventEmitter { const stash = await this.stash(); const isBonded = await this.chaindata.isBonded(stash); const [bonded, err] = await this.chaindata.getDenomBondedAmount(stash); + const currentBlock = await this.chaindata.getLatestBlock(); const currentEra = (await this.chaindata.getCurrentEra()) || 0; const lastNominationEra = @@ -170,13 +171,15 @@ export default class Nominator extends EventEmitter { name = (await this.chaindata.getFormattedIdentity(target))?.name; } - const score = await queries.getLatestValidatorScore(target); + const scoreResult = await queries.getLatestValidatorScore(target); + const score = + scoreResult && scoreResult.total ? scoreResult.total : 0; return { stash: target, name: name, kyc: kyc, - score: score && score[0] && score[0].total ? score[0].total : 0, + score: score, }; }), ); @@ -193,23 +196,29 @@ export default class Nominator extends EventEmitter { let name = await queries.getIdentityName(target); if (!name) { - name = (await this.chaindata.getFormattedIdentity(target)) - ?.name; + const formattedIdentity = + await this.chaindata.getFormattedIdentity(target); + name = formattedIdentity?.name; } - const score = await queries.getLatestValidatorScore(target); + const scoreResult = await queries.getLatestValidatorScore(target); + const score = + scoreResult && scoreResult.total ? scoreResult.total : 0; return { stash: target, name: name, kyc: kyc, - score: score && score.total ? score.total : 0, + score: score, }; }), ); - + const executionMsTime = + (this._proxyDelay + currentBlock - announcement.number) * 6 * 1000; return { - namedTargets, + ...announcement, + targets: namedTargets, + executionTime: executionMsTime, }; }), ); diff --git a/packages/common/src/scorekeeper/Round.ts b/packages/common/src/scorekeeper/Round.ts index d63902688..1191caf5a 100644 --- a/packages/common/src/scorekeeper/Round.ts +++ b/packages/common/src/scorekeeper/Round.ts @@ -99,7 +99,7 @@ export const startRound = async ( ); for (const nom of filteredNominators) { const nominatorStatus: NominatorStatus = { - status: `[${index}/${allCandidates.length}] Checked Candidate ${candidate.name} ${isValid ? "✅ " : "❌"}`, + status: `[${index}/${allCandidates.length}] ${candidate.name} ${isValid ? "✅ " : "❌"}`, updated: Date.now(), stale: false, }; diff --git a/packages/core/package.json b/packages/core/package.json index 98bdb121f..a20cfd76d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@1kv/core", - "version": "3.1.1", + "version": "3.1.2", "description": "Services for running the Thousand Validator Program.", "main": "index.js", "scripts": { diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 45b06b579..922afb509 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -1,6 +1,6 @@ { "name": "@1kv/gateway", - "version": "3.1.1", + "version": "3.1.2", "description": "Services for running the Thousand Validator Program.", "main": "build/index.js", "types": "build/index.d.ts", diff --git a/packages/scorekeeper-status-ui/package.json b/packages/scorekeeper-status-ui/package.json index 65400f799..ba6471168 100644 --- a/packages/scorekeeper-status-ui/package.json +++ b/packages/scorekeeper-status-ui/package.json @@ -1,7 +1,7 @@ { "name": "@1kv/scorekeeper-status-ui", "private": true, - "version": "3.1.1", + "version": "3.1.2", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/scorekeeper-status-ui/src/App.css b/packages/scorekeeper-status-ui/src/App.css index e01c21846..ee356628a 100644 --- a/packages/scorekeeper-status-ui/src/App.css +++ b/packages/scorekeeper-status-ui/src/App.css @@ -1,11 +1,11 @@ /* Global font style */ -body, html { - font-family: 'Source Code Pro', monospace; +body, +html { + font-family: "Source Code Pro", monospace; background-color: #0f0f0f; /* Dark background for contrast */ color: #0f0; /* Hacker green text color */ } - .App { display: flex; flex-direction: column; @@ -18,7 +18,7 @@ body, html { background-image: url("https://www.transparenttextures.com/patterns/nami.png"); /* This is mostly intended for prototyping; please download the pattern and re-host for production environments. Thank you! */ /*background-blend-mode: overlay; !* Blends the texture with the gradient *!*/ - font-family: 'Source Code Pro', monospace; + font-family: "Source Code Pro", monospace; padding: 20px; box-sizing: border-box; /*display: block;*/ @@ -62,7 +62,11 @@ h1 { .progressBar { transition: width 0.5s ease-out; height: 20px; /* Set the height of the progress bar */ - background: linear-gradient(to right, rgba(0, 0, 0, 0.6), rgba(0, 255, 0, 0.6)); /* Gradient from transparent black to lighter */ + background: linear-gradient( + to right, + rgba(0, 0, 0, 0.6), + rgba(0, 255, 0, 0.6) + ); /* Gradient from transparent black to lighter */ border-radius: 3px; /* Rounded corners for the progress bar */ position: relative; overflow: hidden; @@ -76,7 +80,7 @@ h1 { .progressItem { font-size: 11px; /* Adjust the font size as needed */ - border: 1px solid #4CAF50; /* Green border */ + border: 1px solid #4caf50; /* Green border */ border-radius: 5px; /* Rounded border */ padding: 5px; /* Add padding for better appearance */ white-space: nowrap; /* Prevent wrapping of words */ @@ -86,7 +90,7 @@ h1 { } .progressBar::before { - content: ''; + content: ""; position: absolute; top: 0; left: 0; @@ -115,7 +119,7 @@ h1 { width: 100vw; /* Full viewport width */ background-color: #0f0f0f; /* Dark background */ color: #0f0; /* Hacker green text color */ - font-family: 'Source Code Pro', monospace; + font-family: "Source Code Pro", monospace; } /* Centered container for error message */ @@ -157,7 +161,12 @@ h1 { .jobItemOld { border-color: yellow; color: yellow; - background-color: rgba(255, 255, 0, 0.1); /* Yellow background with transparency */ + background-color: rgba( + 255, + 255, + 0, + 0.1 + ); /* Yellow background with transparency */ } .jobItemError { @@ -170,8 +179,12 @@ h1 { display: flex; align-items: center; justify-content: center; - border: 1px solid rgba(255, 255, 0, 0.5); /* Neon green border */ - background: linear-gradient(to right, rgba(255, 255, 0, 0.05), rgba(255, 255, 0, 0.1)); /* Gradient from transparent black to lighter */ + border: 1px solid rgba(255, 255, 0, 0.5); /* Neon green border */ + background: linear-gradient( + to right, + rgba(255, 255, 0, 0.05), + rgba(255, 255, 0, 0.1) + ); /* Gradient from transparent black to lighter */ border-radius: 3px; padding: 10px; } @@ -190,7 +203,7 @@ h1 { } .timeIcon { - color: #4CAF50; /* Default color for time icon */ + color: #4caf50; /* Default color for time icon */ margin-right: 5px; /* Add spacing between icon and text */ display: flex; align-items: center; /* Vertically center the clock icon */ @@ -243,7 +256,8 @@ h1 { font-size: 20px; /* Icon size, adjust based on your design */ /* If using an SVG or for icons, set width and height instead */ } -.healthCheckBar, .healthCheckItem { +.healthCheckBar, +.healthCheckItem { display: flex; align-items: center; /* Ensures vertical alignment is centered */ justify-content: center; /* Centers content horizontally */ @@ -278,16 +292,17 @@ h1 { font-size: 1.5rem; /* Larger icons */ } -.connected, .disconnected { +.connected, +.disconnected { flex-shrink: 0; /* Prevents icons from shrinking */ } .connected { - color: #4CAF50; /* Green for connected */ + color: #4caf50; /* Green for connected */ } .disconnected { - color: #F44336; /* Red for disconnected */ + color: #f44336; /* Red for disconnected */ } @media (max-width: 768px) { @@ -302,7 +317,8 @@ h1 { } } -.healthCheckIcon, .jobHeader svg { +.healthCheckIcon, +.jobHeader svg { transition: color 0.3s ease-in-out; /* Smooth transition for color changes */ /* Other styles remain the same */ } @@ -321,10 +337,8 @@ h1 { flex-wrap: wrap; justify-content: center; gap: 20px; /* Space between nominator items */ - } - .nominatorItem { background: rgba(0, 255, 0, 0.05); border: 1px solid #0f0; @@ -342,7 +356,6 @@ h1 { place-items: center; /* Shorthand for aligning and justifying items at the center */ height: 100%; /* Ensure the div takes up full container height, adjust as needed */ width: 100%; - } .nominatorTitle { @@ -372,8 +385,6 @@ h1 { top: 5px; } - - .nominatorInfo ul li { /* If needed, style list items here */ } @@ -388,11 +399,18 @@ h1 { align-items: center; /* Correct property for horizontal centering in a flex column */ background: rgba(0, 255, 0, 0.1); cursor: pointer; /* Indicates clickability */ - transition: background 0.3s, border-color 0.3s; /* Smooth transition for hover effects */ + transition: + background 0.3s, + border-color 0.3s; /* Smooth transition for hover effects */ } .nominatorField:hover { - background: rgba(0, 255, 0, 0.2); /* Slightly darken the background on hover */ + background: rgba( + 0, + 255, + 0, + 0.2 + ); /* Slightly darken the background on hover */ border-color: #00ff00; /* Brighten the border color on hover */ } @@ -401,11 +419,15 @@ h1 { display: flex; align-items: center; justify-content: center; - border: 1px solid rgba(255, 255, 0, 0.5); - background: linear-gradient(to right, rgba(255, 255, 0, 0.05), rgba(255, 255, 0, 0.1)); /* Gradient from transparent black to lighter */ + border: 1px solid rgba(255, 255, 0, 0.5); + background: linear-gradient( + to right, + rgba(255, 255, 0, 0.05), + rgba(255, 255, 0, 0.1) + ); /* Gradient from transparent black to lighter */ border-radius: 3px; width: 100%; - color: rgba(255, 255, 0, 1) + color: rgba(255, 255, 0, 1); } .identicon { @@ -415,16 +437,20 @@ h1 { top: 5px; } .targetField { - /*transition: background 0.3s, border 0.3s; !* Smooth transition for hover effect *!*/ - padding: 10px; /* Add some padding inside the div */ - border-radius: 5px; /* Optional: match the border-radius if needed */ - border: 1px solid transparent; /* Transparent border by default */ - + padding: 1%; + display: flex; + align-items: center; + gap: 5px; + text-decoration: none; + color: inherit; + width: 100%; + border: 1px solid transparent; } .targetField:hover { - background: rgba(0, 255, 0, 0.05); /* Slightly darken the background on hover */ - border-color:rgba(0, 255, 0, 0.4); /* Brighten the border color on hover */ + background: rgba(0, 255, 0, 0.05); + border-color: rgba(0, 255, 0, 0.4); /* Changes border color on hover */ + border-style: solid; /* Ensures the border style is solid */ } .eraStatsBar { @@ -446,8 +472,10 @@ h1 { } .targetItemWrapper { - list-style-type: none; - + display: flex; + align-items: flex-start; + justify-content: flex-start; + width: 100%; } .proxyTransactionItem { @@ -474,19 +502,30 @@ h1 { align-items: center; /* Correct property for horizontal centering in a flex column */ background: rgba(0, 255, 0, 0.1); cursor: pointer; /* Indicates clickability */ - transition: background 0.3s, border-color 0.3s; /* Smooth transition for hover effects */ + transition: + background 0.3s, + border-color 0.3s; /* Smooth transition for hover effects */ } .nominatorField:hover { - background: rgba(0, 255, 0, 0.2); /* Slightly darken the background on hover */ + background: rgba( + 0, + 255, + 0, + 0.2 + ); /* Slightly darken the background on hover */ border-color: #00ff00; /* Brighten the border color on hover */ } .proxyTransactions { - + color: rgba( + 0, + 0, + 255, + 0.5 + ); /* This will style the text inside .proxyHeader */ margin-top: 10px; width: 100%; - } } @@ -497,13 +536,3 @@ h1 { white-space: nowrap; /* Keep the text on a single line */ max-width: 70%; /* Adjust this value based on your container's width */ } - - - - - -.proxyTransactionItem p { - display: flex; - align-items: center; - gap: 5px; -} diff --git a/packages/scorekeeper-status-ui/src/App.tsx b/packages/scorekeeper-status-ui/src/App.tsx index f540cb137..543105b29 100644 --- a/packages/scorekeeper-status-ui/src/App.tsx +++ b/packages/scorekeeper-status-ui/src/App.tsx @@ -48,9 +48,7 @@ const endpoints = { const OLD_JOB_THRESHOLD_SECONDS = 120; const App = () => { - const [currentEndpoint, setCurrentEndpoint] = useState( - endpoints.KusamaStaging, - ); + const [currentEndpoint, setCurrentEndpoint] = useState(endpoints.Polkadot); const [jobs, setJobs] = useState([]); const [isLoading, setIsLoading] = useState(false); const [hasError, setHasError] = useState(false); @@ -250,6 +248,23 @@ const App = () => { } } + function formatDuration(ms: number): string { + const seconds = ms / 1000; + const minutes = seconds / 60; + const hours = minutes / 60; + const days = hours / 24; + + if (days >= 1) { + return `${Math.floor(days)} days from now`; + } else if (hours >= 1) { + return `${Math.floor(hours)} hours from now`; + } else if (minutes >= 1) { + return `${Math.floor(minutes)} mins from now`; + } else { + return `${Math.floor(seconds)} secs from now`; + } + } + return (