Skip to content

Commit

Permalink
Merge pull request #210 from EpicsDAO/feature
Browse files Browse the repository at this point in the history
Added - solv harvest/transfer/epochTimer
  • Loading branch information
POPPIN-FUMI authored Jun 28, 2024
2 parents 2bdf836 + 5c1451e commit cf3fbea
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 187 deletions.
88 changes: 88 additions & 0 deletions .changeset/wild-hounds-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
'@epics-dao/solv': patch
---

## New Features - v4.2.0~v4.2.1

- Added Solana Liquid Staking Command
- Added Solana Transfer Command
- Added Auto Reward Harvest Command
- Added Epoch Timer
- Improved setup command
- Improved log command
- Added solv df command
- Migrated to ESM Module
- Added Turbo Repo

* You should set the SOLANA_RPC_URL in the .env file to use this feature effectively.

### Solana Liquid Staking Command

```bash
$ solv stake --lst
```

### Solana Transfer Command

```bash
$ solv transfer/tr
```

### Auto Reward Harvest Command

This command collects all rewards into the authority account, converts the gathered SOL to elSOL, and then transfers the elSOL to an external harvest account.

This ensures that, in the event of a node hack, assets are not held within the node. Additionally, it allows immediate staking of rewards, thereby enhancing performance.

※ To use this command, you must first set the harvest account in the solv.config.json file. During the initial execution, you can input this information interactively.

Please ensure that this account information is never stored on the validator server.

```bash
$ solv harvest/hv
```

Soon, we will be adding the ability to run the harvest command by the epochTimer.

### Epoch Timer

The epochTimer is a feature that allows you to set a specific time to run the some commands.
This feature is especially useful for those who want to stake rewards at before the epoch change.

- You need to set `DISCORD_WEBHOOK_URL` in the `.env` file to use this feature.

```bash
$ solv epochTimer
```

### Improved setup command

The setup command has been improved to allow you to set up without mounting the volume.

```bash
$ solv setup
```

### Improved log command

small bug fixes and improvements

```bash
$ solv log
```

### Added solv df command

This command shows the disk usage of the validator server.

```bash
$ solv df
```

### Migrated to ESM Module

solv has been migrated to ESM Module.

### Added Turbo Repo

We have added a Turbo Repo to manage the solv package.
2 changes: 1 addition & 1 deletion .github/workflows/solv-cli-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
run: pnpm install

- name: Build and Add Line
run: npx turbo build -F @epics-dao/solv
run: npx turbo -F @epics-dao/solv build

- name: Creating .npmrc
run: |
Expand Down
12 changes: 12 additions & 0 deletions packages/solv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ $ solv start

This will remove the snapshot and restart the Solana Validator from the new snapshot.

## New Features - v4.2.0~v4.2.1

- Added Solana Liquid Staking Command
- Added Solana Transfer Command
- Added Auto Reward Harvest Command
- Added Epoch Timer
- Improved setup command
- Improved log command
- Added solv df command
- Migrated to ESM Module
- Added Turbo Repo

## New Features - v4.0.0~v4.1.0

- Jito Relayer Setup
Expand Down
11 changes: 5 additions & 6 deletions packages/solv/src/cli/check/df/df.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { UbuntuDhParams } from '@/types/solvTypes'
import { execSync } from 'child_process'
import { convertToBytes } from '.'
import { Logger } from '@/lib/logger'

export const df = () => {
const output = execSync('df -h').toString()
Expand Down Expand Up @@ -56,11 +55,11 @@ export const df = () => {
)
.map((data) => data.Filesystem)
if (fsNames.length > 0) {
console.log(
Logger.warningHex(
`\nfileSystem might be one of ${fsNames.join(', ')} ...?`,
),
)
// console.log(
// Logger.warningHex(
// `\nfileSystem might be one of ${fsNames.join(', ')} ...?`,
// ),
// )
}
}

Expand Down
3 changes: 1 addition & 2 deletions packages/solv/src/cli/check/df/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { program } from '@/index'
import { df } from './df'
import { displayTable } from '@/lib/logger/table'
import { Logger } from '@/lib/logger'

export const dfCommands = async () => {
program
.command('df')
.description('Disk Free Command')
.action(async () => {
.action(() => {
const dirs = df()
displayTable(dirs)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/solv/src/cli/log/tail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type TailOptions = {
export const tail = (options: TailOptions) => {
try {
const { log } = startupScriptPaths()
let cmd = `tail -f ${log}*`
let cmd = `tail -f ${log}`
if (options.error) {
cmd += ` | grep '\\(WARN\\|ERR\\)'`
} else if (options.info) {
Expand Down
14 changes: 0 additions & 14 deletions packages/solv/src/cli/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,6 @@ export enum INSTALLER_CHOICES {
}

export const server = async (solvConfig: ConfigParams) => {
const homeDir = os.homedir()
if (solvConfig.config.IS_CLIENT) {
console.log(
chalk.yellow(
`⚠️ Please run solv server from the server, not from the your local machine
Or You might need to
${chalk.white('$ su solv')}
to login as solv user...?`,
),
)
return
}
Logger.solvAA()
const { logs, installer, cmds } = solvConfig.locale
const { config } = solvConfig
Expand Down
1 change: 0 additions & 1 deletion packages/solv/src/cli/server/stake/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { delegateStake } from '@/cli/stake'
import { stakeAccountQuestion } from '@/cli/stake/stakeAccountQuestion'
import { deactivateStake } from '@/cli/stake/deactivateStake'
import { withdrawStake } from '@/cli/stake/withdrawStake'
import { updateSolvConfig } from '@/lib/updateSolvConfig'
import { delegateStakeAsk } from './delegateStakeAsk'
import { unstakeAsk } from './unstakeAsk'
import { deactivateStakeAsk } from './deactivateStakeAsk'
Expand Down
1 change: 0 additions & 1 deletion packages/solv/src/cli/setup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
readOrCreateDefaultConfig,
} from '@/lib/readOrCreateDefaultConfig'
import { createSolvKeyPairs } from '@/lib/createSolvKeys'
import { testnetSetup } from './testnetSetup'
import { setupSwap } from './setupSwap'

type SetupOptions = {
Expand Down
81 changes: 14 additions & 67 deletions packages/solv/src/cli/setup/setup.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
import { execSync, spawnSync } from 'child_process'
import { setupDirs } from '@/cli/setup/mkdirs'
import { execSync } from 'child_process'
import { setupKeys } from '@/cli/setup/setupKeys'
import { genStartupValidatorScript } from '@/cli/setup/genStartupValidatorScript'
import { Logger } from '@/lib/logger'
import chalk from 'chalk'
import { makeServices } from '@/cli/setup/makeServices'
import { setupPermissions } from '@/cli/setup/userPermissions'
import { umount } from '@/cli/check/mt/umount'
import getPreferredDisk, {
GetPreferredDisksResult,
} from '../check/mt/getLargestDisk'
import { startSolana } from '@/cli/start/startSolana'
import {
CONFIG,
DISK_TYPES,
MAINNET_TYPES,
NETWORK_TYPES,
RPC_MODE,
SOLV_TYPES,
} from '@/config/config'
import { ensureFstabEntries } from '@/cli/check/ensureMountAndFiles'
import { formatDisk } from '@/cli/setup/formatDisk'
import { CONFIG, MAINNET_TYPES, RPC_MODE, SOLV_TYPES } from '@/config/config'
import { updateSolvConfig } from '@/lib/updateSolvConfig'
import inquirer from 'inquirer'
import {
Expand All @@ -37,10 +26,11 @@ import { askJitoSetting } from './askJitoSetting'
import { readOrCreateJitoConfig } from '@/lib/readOrCreateJitoConfig'
import { updateFirewall } from './updateFirewall'
import { updateJitoSolvConfig } from '@/lib/updateJitoSolvConfig'
import { getRootFreeSpaceGB, setupSwap } from './setupSwap'
import { getRootFreeSpaceGB } from './setupSwap'
import { jitoRelayerSetup } from './jitoRelayerSetup'
import { createSymLink } from './createSymLink'
import { getSnapshot } from '../get/snapshot'
import setupMount from './setupMount'

export const setup = async (solvConfig: ConfigParams) => {
try {
Expand Down Expand Up @@ -94,7 +84,7 @@ export const setup = async (solvConfig: ConfigParams) => {
type: 'confirm',
message:
'Do you want to setup as a dummy(Inactive) node?(※For Migration)',
default: false,
default: true,
},
])
// Check if the root volume is larger than 256GB
Expand Down Expand Up @@ -175,68 +165,25 @@ export const setup = async (solvConfig: ConfigParams) => {
}
console.log(`Setting up ${solvType}...`)

// Check if there is enough disk space
const disks: GetPreferredDisksResult = getPreferredDisk()

// Skip mounting disk if there is not enough disk space
if (!disks.has400GB && !disks.has850GB && !disks.hasUsed1250GB) {
console.log(
chalk.yellow(
`⚠️ Not enough disk space to setup Solana Validator\nYou need at least 1TB disk space\nPlease add more disk space and try again!`,
`⚠️ Not enough disk space to setup Solana Validator\nYou need at least 1TB disk space\nSkip mounting disk...`,
),
)
return
}

const mountPoint = disks.disks[0].mountpoint
setupDirs()
// Detect if DISK_TYPE is DOUBLE or SINGLE
if (disks.has850GB && disks.has400GB) {
// DOUBLE
console.log('Setting up DOUBLE DISK...')

updateSolvConfig({
DISK_TYPES: DISK_TYPES.DOUBLE,
SOLV_TYPE: sType,
COMMISSION: commission,
SOLANA_NETWORK: isTest ? NETWORK_TYPES.TESTNET : NETWORK_TYPES.MAINNET,
})

const fileSystemName1 = '/dev/' + disks.disks[0].name
const fileSystemName2 = '/dev/' + disks.disks[1].name
const isDisk1Formatted = formatDisk(fileSystemName1)
const isDisk2Formatted = formatDisk(fileSystemName2)

// Swap setup
await setupSwap(askSwapsize.swapsize)

let fileSystem1 = isDisk1Formatted ? fileSystemName1 : ''
let fileSystem2 = isDisk2Formatted ? fileSystemName2 : ''
let isLatitude = false
if (fileSystem1 === '' && fileSystem2) {
fileSystem1 = fileSystem2
fileSystem2 = ''
isLatitude = true
}
ensureFstabEntries(fileSystem1, fileSystem2, isLatitude)
} else {
// SINGLE
console.log('Setting up SINGLE DISK...')
updateSolvConfig({
DISK_TYPES: DISK_TYPES.SINGLE,
SOLV_TYPE: sType,
COMMISSION: commission,
})
if (!mountPoint.includes('/mnt')) {
const fileSystem = '/dev/' + disks.disks[0].name
formatDisk(fileSystem)
ensureFstabEntries(fileSystem)
} else {
umount(mountPoint)
const fileSystem = '/dev/' + disks.disks[0].name
formatDisk(fileSystem)
ensureFstabEntries(fileSystem)
}
// Mount the disk
await setupMount(askSwapsize.swapsize, disks, sType, commission, isTest)
}

const newSolvConfig = readOrCreateDefaultConfig()
setupPermissions()

// Generate startup script
await genStartupValidatorScript(
true,
sType,
Expand Down
Loading

0 comments on commit cf3fbea

Please sign in to comment.