-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
check-in: add node spec diff tool and modal with changes
- Loading branch information
Showing
12 changed files
with
382 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import type { SelectControl, SelectTranslation } from '../nodeConfig.js'; | ||
import type { DockerExecution, NodeSpecification } from '../nodeSpec.js'; | ||
import { assert, compareObjects } from './util.js'; | ||
|
||
export type UserSpecDiff = { | ||
message: string; | ||
}; | ||
|
||
// Only time a user default would be overridden is if the user default is not in the new spec as | ||
// an option on a select config. In that case, the default should be used. So we should highlight any | ||
// removal of select options. | ||
// returns a list of changes | ||
export const calcUserSpecDiff = ( | ||
oldSpec: NodeSpecification, | ||
newSpec: NodeSpecification, | ||
): UserSpecDiff[] => { | ||
assert(oldSpec.specId === newSpec.specId, 'specId mismatch'); | ||
assert( | ||
oldSpec.version < newSpec.version, | ||
'newSpec version is not greater than oldSpec version', | ||
); | ||
|
||
const diffs: UserSpecDiff[] = []; | ||
diffs.push({ | ||
message: `Controller version: ${oldSpec.version} -> ${newSpec.version}`, | ||
}); | ||
if (oldSpec.displayName !== newSpec.displayName) { | ||
diffs.push({ | ||
message: `Name: ${oldSpec.displayName} -> ${newSpec.displayName}`, | ||
}); | ||
} | ||
|
||
/////// [start] Execution | ||
const oldSpecExecution = oldSpec.execution as DockerExecution; | ||
const newSpecExecution = newSpec.execution as DockerExecution; | ||
if (oldSpecExecution.imageName !== newSpecExecution.imageName) { | ||
diffs.push({ | ||
message: `Download URL: ${oldSpecExecution.imageName} -> ${newSpecExecution.imageName}`, | ||
}); | ||
} | ||
if (oldSpecExecution.defaultImageTag !== newSpecExecution.defaultImageTag) { | ||
diffs.push({ | ||
message: `Version: ${oldSpecExecution.defaultImageTag} -> ${newSpecExecution.defaultImageTag}`, | ||
}); | ||
} | ||
/////// [end] Execution | ||
|
||
/////// [start] System Requirements | ||
const oldSysReq = oldSpec.systemRequirements; | ||
const newSysReq = newSpec.systemRequirements; | ||
if (!compareObjects(oldSysReq, newSysReq)) { | ||
let oldSysReqString = ''; | ||
let newSysReqString = ''; | ||
if (!compareObjects(oldSysReq?.cpu, newSysReq?.cpu)) { | ||
oldSysReqString += ` CPU: ${JSON.stringify(oldSysReq?.cpu)}`; | ||
newSysReqString += ` CPU: ${JSON.stringify(newSysReq?.cpu)}`; | ||
} | ||
if (!compareObjects(oldSysReq?.memory, newSysReq?.memory)) { | ||
oldSysReqString += ` Memory: ${JSON.stringify(oldSysReq?.memory)}`; | ||
newSysReqString += ` Memory: ${JSON.stringify(newSysReq?.memory)}`; | ||
} | ||
if (!compareObjects(oldSysReq?.storage, newSysReq?.storage)) { | ||
oldSysReqString += ` Storage: ${JSON.stringify(oldSysReq?.storage)}`; | ||
newSysReqString += ` Storage: ${JSON.stringify(newSysReq?.storage)}`; | ||
} | ||
if (!compareObjects(oldSysReq?.internet, newSysReq?.internet)) { | ||
oldSysReqString += ` Internet: ${JSON.stringify(oldSysReq?.internet)}`; | ||
newSysReqString += ` Internet: ${JSON.stringify(newSysReq?.internet)}`; | ||
} | ||
|
||
diffs.push({ | ||
message: `System requirements: ${oldSysReqString} -> ${newSysReqString}`, | ||
}); | ||
} | ||
/////// [end] System Requirements | ||
|
||
/////// [start] Config Tralsations | ||
const oldTranslations = oldSpec.configTranslation ?? {}; | ||
const newTranslations = newSpec.configTranslation ?? {}; | ||
const oldTranslationKeys = Object.keys(oldTranslations); | ||
const newTranslationKeys = Object.keys(newTranslations); | ||
for (const key of oldTranslationKeys) { | ||
if (!newTranslationKeys.includes(key)) { | ||
diffs.push({ | ||
message: `Removed setting: ${oldTranslations[key]?.displayName}`, | ||
}); | ||
} else { | ||
if (oldTranslations[key]?.uiControl?.type.includes('select')) { | ||
const oldSelectOptions = ( | ||
oldTranslations[key].uiControl as SelectControl | ||
)?.controlTranslations as SelectTranslation[]; | ||
const newSelectOptions = ( | ||
newTranslations[key].uiControl as SelectControl | ||
)?.controlTranslations as SelectTranslation[]; | ||
if (!compareObjects(oldSelectOptions, newSelectOptions)) { | ||
diffs.push({ | ||
message: `Changed setting options: ${JSON.stringify( | ||
oldSelectOptions, | ||
)} -> ${JSON.stringify(newSelectOptions)}`, | ||
}); | ||
} | ||
} | ||
|
||
// else, they're the same | ||
} | ||
} | ||
for (const key of newTranslationKeys) { | ||
if (!oldTranslationKeys.includes(key)) { | ||
diffs.push({ | ||
message: `New setting: ${newTranslations[key]?.displayName}`, | ||
}); | ||
} | ||
// else, they were compared when iterating over oldTranslationKeys | ||
} | ||
/////// [end] Config Tralsations | ||
|
||
return diffs; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
export function assert(condition: boolean, message: string): asserts condition { | ||
if (!condition) { | ||
throw new Error(message); | ||
} | ||
} | ||
|
||
/** | ||
* Simple json.stringify comparison of two objects | ||
*/ | ||
export function compareObjects(obj1: any, obj2: any) { | ||
return JSON.stringify(obj1) === JSON.stringify(obj2); | ||
} | ||
|
||
export const gethv1 = { | ||
specId: 'geth', | ||
version: '1.0.0', | ||
displayName: 'Geth', | ||
execution: { | ||
executionTypes: ['docker'], | ||
defaultExecutionType: 'docker', | ||
input: { | ||
defaultConfig: { | ||
http: 'Enabled', | ||
httpCorsDomains: 'http://localhost', | ||
webSockets: 'Disabled', | ||
httpVirtualHosts: 'localhost,host.containers.internal', | ||
authVirtualHosts: 'localhost,host.containers.internal', | ||
httpAddress: '0.0.0.0', | ||
webSocketAddress: '0.0.0.0', | ||
syncMode: 'snap', | ||
}, | ||
docker: { | ||
containerVolumePath: '/root/.ethereum', | ||
raw: '', | ||
forcedRawNodeInput: | ||
'--authrpc.addr 0.0.0.0 --authrpc.jwtsecret /root/.ethereum/jwtsecret --ipcdisable', | ||
}, | ||
}, | ||
imageName: 'docker.io/ethereum/client-go', | ||
defaultImageTag: 'stable', | ||
}, | ||
category: 'L1/ExecutionClient', | ||
rpcTranslation: 'eth-l1', | ||
systemRequirements: { | ||
documentationUrl: 'https://geth.ethereum.org/docs/interface/hardware', | ||
cpu: { | ||
cores: 4, | ||
}, | ||
memory: { | ||
minSizeGBs: 16, | ||
}, | ||
storage: { | ||
minSizeGBs: 1600, | ||
ssdRequired: true, | ||
}, | ||
internet: { | ||
minDownloadSpeedMbps: 25, | ||
minUploadSpeedMbps: 10, | ||
}, | ||
docker: { | ||
required: true, | ||
}, | ||
}, | ||
configTranslation: { | ||
dataDir: { | ||
displayName: 'Data location', | ||
cliConfigPrefix: '--datadir ', | ||
defaultValue: '~/.ethereum', | ||
uiControl: { | ||
type: 'filePath', | ||
}, | ||
infoDescription: | ||
'Data directory for the databases and keystore (default: "~/.ethereum")', | ||
}, | ||
network: { | ||
displayName: 'Network', | ||
defaultValue: 'Mainnet', | ||
hideFromUserAfterStart: true, | ||
uiControl: { | ||
type: 'select/single', | ||
controlTranslations: [ | ||
{ | ||
value: 'Mainnet', | ||
config: '--mainnet', | ||
}, | ||
{ | ||
value: 'Holesky', | ||
config: '--holesky', | ||
}, | ||
{ | ||
value: 'Sepolia', | ||
config: '--sepolia', | ||
}, | ||
], | ||
}, | ||
}, | ||
webSocketsPort: { | ||
displayName: 'WebSockets JSON-RPC port', | ||
cliConfigPrefix: '--ws.port ', | ||
defaultValue: '8546', | ||
uiControl: { | ||
type: 'text', | ||
}, | ||
infoDescription: | ||
'The port (TCP) on which WebSocket JSON-RPC listens. The default is 8546. You must expose ports appropriately.', | ||
documentation: | ||
'https://geth.ethereum.org/docs/rpc/server#websocket-server', | ||
}, | ||
webSocketApis: { | ||
displayName: 'Enabled WebSocket APIs', | ||
cliConfigPrefix: '--ws.api ', | ||
defaultValue: ['eth', 'net', 'web3'], | ||
valuesJoinStr: ',', | ||
uiControl: { | ||
type: 'select/multiple', | ||
controlTranslations: [ | ||
{ | ||
value: 'eth', | ||
config: 'eth', | ||
}, | ||
{ | ||
value: 'net', | ||
config: 'net', | ||
}, | ||
{ | ||
value: 'web3', | ||
config: 'web3', | ||
}, | ||
{ | ||
value: 'debug', | ||
config: 'debug', | ||
}, | ||
|
||
{ | ||
value: 'personal', | ||
config: 'personal', | ||
}, | ||
{ | ||
value: 'admin', | ||
config: 'admin', | ||
}, | ||
], | ||
}, | ||
}, | ||
syncMode: { | ||
displayName: 'Execution Client Sync Mode', | ||
category: 'Syncronization', | ||
uiControl: { | ||
type: 'select/single', | ||
controlTranslations: [ | ||
{ | ||
value: 'snap', | ||
config: '--syncmode snap', | ||
info: '', | ||
}, | ||
{ | ||
value: 'full', | ||
config: '--syncmode full', | ||
info: '~800GB / ~2d', | ||
}, | ||
{ | ||
value: 'archive', | ||
config: '--syncmode full --gcmode archive', | ||
info: '~16TB', | ||
}, | ||
], | ||
}, | ||
addNodeFlow: 'required', | ||
defaultValue: 'snap', | ||
hideFromUserAfterStart: true, | ||
documentation: | ||
'https://geth.ethereum.org/docs/faq#how-does-ethereum-syncing-work', | ||
}, | ||
}, | ||
iconUrl: | ||
'https://clientdiversity.org/assets/img/execution-clients/geth-logo.png', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.