Skip to content

Commit

Permalink
Merge pull request #81 from shapeshift/cli-tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
kaladinlight authored Jul 25, 2024
2 parents c149033 + ab54bc5 commit a2515a2
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 60 deletions.
32 changes: 22 additions & 10 deletions cli/MultiSig.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
## Prerequisites

- Install golang: https://go.dev/doc/install
- Install golang (v1.22): https://go.dev/doc/install
- Create common rfox directory in your home directory. This is where all output files from the script will be stored and where shared files (unsigned transactions, signatures, signed transactions, etc.) should be saved.
```bash
mkdir ~/rfox
```

## Clone and Build

```bash
git clone https://gitlab.com/thorchain/thornode.git
cd thornode/cmd/thornode
cd thornode
git checkout develop
git pull
cd cmd/thornode
go build --tags cgo,ledger
```

Expand All @@ -22,8 +29,12 @@ go build --tags cgo,ledger
```
- Import signer pubkeys:
```bash
./thornode keys add {person2} --pubkey {pubkey}
./thornode keys add {person3} --pubkey {pubkey}
./thornode keys add {person2} --pubkey '{person2_pubkey}'
./thornode keys add {person3} --pubkey '{person3_pubkey}'
```
- View keys:
```bash
./thornode keys list
```
- Add multisig key:
```bash
Expand All @@ -38,29 +49,30 @@ go build --tags cgo,ledger

- Person 1 signs:
```bash
./thornode tx sign --from {person1} --multisig multisig {unsignedTx_epoch-N.json} --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --from ledger --ledger --sign-mode amino-json > signedTx_{person1}.json
./thornode tx sign --from {person1} --multisig multisig ~/rfox/unsignedTx_epoch-{N}.json --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --ledger --sign-mode amino-json > ~/rfox/signedTx_epoch-{N}_{person1}.json
```
- Person 2 signs:
```bash
./thornode tx sign --from {person2} --multisig multisig {unsignedTx_epoch-N.json} --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --from ledger --ledger --sign-mode amino-json > signedTx_{person2}.json
./thornode tx sign --from {person2} --multisig multisig ~/rfox/unsignedTx_epoch-{N}.json --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --ledger --sign-mode amino-json > ~/rfox/signedTx_epoch-{N}_{person2}.json
```
- Multisign:
```bash
./thornode tx multisign {unsignedTx_epoch-N.json} multisig signedTx_{person1}.json signedTx_{person2}.json --from multisig --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc > signedTx_multisig.json
./thornode tx multisign ~/rfox/unsignedTx_epoch-{N}.json multisig ~/rfox/signedTx_epoch-{N}_{person1}.json ~/rfox/signedTx_epoch-{N}_{person2}.json --from multisig --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc > ~/rfox/signedTx_epoch-{N}_multisig.json
```

## Send Transaction

- Simulate transaction:

```bash
./thornode tx broadcast signedTx_multisig.json --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --gas auto --dry-run > simulatedTx.json
./thornode tx broadcast ~/rfox/signedTx_epoch-{N}_multisig.json --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --dry-run > ~/rfox/simulatedTx_epoch-{N}.json
```

- Validate contents of `simulatedTx.json` for accuracy before broadcasting

- Broadcast transaction:
```bash
./thornode tx broadcast signedTx_multisig.json --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --gas auto > tx.json
./thornode tx broadcast ~/rfox/signedTx_epoch-{N}_multisig.json --chain-id thorchain-mainnet-v1 --node https://daemon.thorchain.shapeshift.com:443/rpc --gas auto > tx.json
```
- Copy the `txhash` value from `tx.json` to supply to the cli in order to continue

At this point, the cli should pick up the funding transaction and continue running the distribution from the hot wallet.
79 changes: 58 additions & 21 deletions cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { isEpochDistributionStarted } from './file'
import { IPFS } from './ipfs'
import { error, info, success, warn } from './logging'
import { create, recoverKeystore } from './mnemonic'
import { Epoch } from './types'
import { Epoch, RFOXMetadata } from './types'
import { Wallet } from './wallet'

const processEpoch = async () => {
Expand All @@ -21,7 +21,7 @@ const processEpoch = async () => {

const month = MONTHS[new Date(metadata.epochStartTimestamp).getUTCMonth()]

info(`Processing Epoch #${metadata.epoch} for ${month} distribution.`)
info(`Processing rFOX Epoch #${metadata.epoch} for ${month} distribution.`)

const now = Date.now()
if (metadata.epochEndTimestamp > now) {
Expand Down Expand Up @@ -88,7 +88,7 @@ const processEpoch = async () => {

const nextEpochStartDate = new Date(metadata.epochEndTimestamp + 1)

await ipfs.updateMetadata(metadata, {
const hash = await ipfs.updateMetadata(metadata, {
epoch: { number: metadata.epoch, hash: epochHash },
metadata: {
epoch: metadata.epoch + 1,
Expand All @@ -97,6 +97,8 @@ const processEpoch = async () => {
},
})

if (!hash) return

success(`rFOX Epoch #${metadata.epoch} has been processed!`)

info(
Expand All @@ -107,14 +109,15 @@ const processEpoch = async () => {
const run = async () => {
const ipfs = await IPFS.new()

const epoch = await ipfs.getEpoch()
const metadata = await ipfs.getMetadata('process')
const epoch = await ipfs.getEpochFromMetadata(metadata)

if (isEpochDistributionStarted(epoch.number)) {
const confirmed = await prompts.confirm({
message: 'It looks like you have already started a distribution for this epoch. Do you want to continue? ',
})

if (confirmed) return recover(epoch)
if (confirmed) return recover(metadata)

info(`Please move or delete all existing files for epoch-${epoch.number} from ${RFOX_DIR} before re-running.`)
warn('This action should never be taken unless you are absolutely sure you know what you are doing!!!')
Expand All @@ -135,30 +138,57 @@ const run = async () => {

const wallet = await Wallet.new(mnemonic)

await processDistribution(epoch, wallet, ipfs)
await processDistribution(metadata, epoch, wallet, ipfs)
}

const recover = async (epoch?: Epoch) => {
const recover = async (metadata?: RFOXMetadata) => {
const ipfs = await IPFS.new()

if (!epoch) epoch = await ipfs.getEpoch()
if (!metadata) {
metadata = await ipfs.getMetadata('process')
}

const epoch = await ipfs.getEpochFromMetadata(metadata)

const keystoreFile = path.join(RFOX_DIR, `keystore_epoch-${epoch.number}.txt`)
const mnemonic = await recoverKeystore(keystoreFile)

const wallet = await Wallet.new(mnemonic)

await processDistribution(epoch, wallet, ipfs)
await processDistribution(metadata, epoch, wallet, ipfs)
}

const processDistribution = async (epoch: Epoch, wallet: Wallet, ipfs: IPFS) => {
await wallet.fund(epoch)
const processedEpoch = await wallet.distribute(epoch)
const update = async () => {
const ipfs = await IPFS.new()

const processedEpochHash = await ipfs.addEpoch(processedEpoch)
const metadata = await ipfs.getMetadata('update')
const hash = await ipfs.updateMetadata(metadata)

if (!hash) return

success(`rFOX metadata has been updated!`)

info(
'Please update the rFOX Wiki (https://github.com/shapeshift/rFOX/wiki/rFOX-Metadata) and notify the DAO accordingly. Thanks!',
)
}

const processDistribution = async (metadata: RFOXMetadata, epoch: Epoch, wallet: Wallet, ipfs: IPFS) => {
const epochHash = metadata.ipfsHashByEpoch[epoch.number]

await wallet.fund(epoch, epochHash)
const processedEpoch = await wallet.distribute(epoch, epochHash)

const processedEpochHash = await ipfs.addEpoch({
...processedEpoch,
distributionStatus: 'complete',
})

const metadataHash = await ipfs.updateMetadata(metadata, {
epoch: { number: processedEpoch.number, hash: processedEpochHash },
})

await ipfs.updateMetadata(metadata, { epoch: { number: processedEpoch.number, hash: processedEpochHash } })
if (!metadataHash) return

success(`rFOX reward distribution for Epoch #${processedEpoch.number} has been completed!`)

Expand All @@ -183,23 +213,28 @@ const main = async () => {
}
}

const choice = await prompts.select<'process' | 'run' | 'recover'>({
const choice = await prompts.select<'process' | 'run' | 'recover' | 'update'>({
message: 'What do you want to do?',
choices: [
{
name: 'Process rFox epoch',
name: 'Process rFOX epoch',
value: 'process',
description: 'Start here to process a completed rFox epoch',
description: 'Start here to process an rFOX epoch.',
},
{
name: 'Run rFox distribution',
name: 'Run rFOX distribution',
value: 'run',
description: 'Start here to begin running a new rFox rewards distribution',
description: 'Start here to run an rFOX rewards distribution.',
},
{
name: 'Recover rFox distribution',
name: 'Recover rFOX distribution',
value: 'recover',
description: 'Start here to recover an in progress rFox rewards distribution',
description: 'Start here to recover an rFOX rewards distribution.',
},
{
name: 'Update rFOX metadata',
value: 'update',
description: 'Start here to update an rFOX metadata.',
},
],
})
Expand All @@ -211,6 +246,8 @@ const main = async () => {
return run()
case 'recover':
return recover()
case 'update':
return update()
default:
error(`Invalid choice: ${choice}, exiting.`)
process.exit(1)
Expand Down
Loading

0 comments on commit a2515a2

Please sign in to comment.