├── .github
└── workflows
│ ├── deploy-stader-node.yml
│ └── go.yml
├── .gitignore
├── .golangci.yml
├── .idea
├── .gitignore
├── modules.xml
├── stader-node.iml
└── vcs.xml
├── LICENSE
├── README.md
├── abis
├── NodeElRewardVault.abi.json
├── OperatorRewardsCollector.abi.json
├── Penalty.abi.json
├── PermissionlessNodeRegistry.abi.json
├── PermissionlessPool.abi.json
├── PoolUtils.abi.json
├── SDUtilityPool.abi.json
├── SdCollateral.abi.json
├── SocializingPool.abi.json
├── StaderConfig.abi.json
├── StakePoolManager.abi.json
├── ValidatorWithdrawVault.abi.json
└── VaultFactory.abi.json
├── add-gplv3.sh
├── build-builder.sh
├── build-ec-migrate.sh
├── build-release.sh
├── daemon-build.sh
├── daemon-local.sh
├── docker
├── stader-dockerfile
├── stader-ec-migrator
├── stader-node-builder
└── stader-prune-provision
├── go.mod
├── go.sum
├── install.sh
├── install
├── addons
│ └── gww
│ │ └── .ignoreme
├── grafana-prometheus-datasource.yml
├── override
│ ├── addons
│ │ └── gww
│ │ │ └── addon_gww.yml
│ ├── api.yml
│ ├── eth1.yml
│ ├── eth2.yml
│ ├── exporter.yml
│ ├── grafana.yml
│ ├── guardian.yml
│ ├── mev-boost.yml
│ ├── node.yml
│ ├── prometheus.yml
│ └── validator.yml
├── prometheus.tmpl
├── scripts
│ ├── NethermindPruneStarter
│ │ ├── NethermindPruneStarter.deps.json
│ │ ├── NethermindPruneStarter.dll
│ │ ├── NethermindPruneStarter.runtimeconfig.json
│ │ └── Newtonsoft.Json.dll
│ ├── restart-vc.sh
│ ├── start-bn.sh
│ ├── start-ec.sh
│ ├── start-mev-boost.sh
│ ├── start-vc.sh
│ └── stop-validator.sh
└── templates
│ ├── addons
│ └── gww
│ │ └── addon_gww.tmpl
│ ├── api.tmpl
│ ├── eth1.tmpl
│ ├── eth2.tmpl
│ ├── exporter.tmpl
│ ├── grafana-prometheus-datasource.tmpl
│ ├── grafana.tmpl
│ ├── guardian.tmpl
│ ├── mev-boost.tmpl
│ ├── node.tmpl
│ ├── prometheus.tmpl
│ └── validator.tmpl
├── license-short.txt
├── shared
├── services
│ ├── bc-manager.go
│ ├── beacon
│ │ ├── client.go
│ │ └── client
│ │ │ ├── std-http-client.go
│ │ │ └── types.go
│ ├── config
│ │ ├── besu-params.go
│ │ ├── bitfly-beaconchain-config.go
│ │ ├── config-legacy.go
│ │ ├── consensus-common-config.go
│ │ ├── dev-presign-public-key.txt
│ │ ├── execution-common-config.go
│ │ ├── exporter-config.go
│ │ ├── external-configs.go
│ │ ├── fallback-configs.go
│ │ ├── geth-params.go
│ │ ├── grafana-config.go
│ │ ├── lighthouse-config.go
│ │ ├── lodestar-config.go
│ │ ├── mev-boost-config.go
│ │ ├── native-config.go
│ │ ├── nethermind-params.go
│ │ ├── nimbus-config.go
│ │ ├── prod-presign-public-key.txt
│ │ ├── prometheus-config.go
│ │ ├── prysm-config.go
│ │ ├── stader-config.go
│ │ ├── stadernode-config.go
│ │ ├── stage-presign-public-key.txt
│ │ └── teku-config.go
│ ├── contracts
│ │ └── beacon-deposit.go
│ ├── ec-manager.go
│ ├── eth1.go
│ ├── gas
│ │ ├── etherchain
│ │ │ └── etherchain.go
│ │ ├── etherscan
│ │ │ └── etherscan.go
│ │ └── gas.go
│ ├── passwords
│ │ └── manager.go
│ ├── requirements.go
│ ├── services.go
│ ├── stader
│ │ ├── api.go
│ │ ├── client.go
│ │ ├── command.go
│ │ ├── external-urls.go
│ │ ├── fee-recipient.go
│ │ ├── gas.go
│ │ ├── legacy-client.go
│ │ ├── node.go
│ │ ├── service.go
│ │ └── wallet.go
│ ├── state
│ │ ├── manager.go
│ │ └── network-state.go
│ └── wallet
│ │ ├── keystore
│ │ ├── keystore.go
│ │ ├── lighthouse
│ │ │ └── keystore.go
│ │ ├── lodestar
│ │ │ └── keystore.go
│ │ ├── nimbus
│ │ │ └── keystore.go
│ │ ├── prysm
│ │ │ └── keystore.go
│ │ └── teku
│ │ │ └── keystore.go
│ │ ├── node.go
│ │ ├── validator.go
│ │ └── wallet.go
├── types
│ ├── api
│ │ ├── api.go
│ │ ├── node.go
│ │ ├── service.go
│ │ └── wallet.go
│ ├── config
│ │ ├── parameter.go
│ │ └── types.go
│ ├── eth2
│ │ ├── types.go
│ │ └── types_encoding.go
│ └── stader-backend
│ │ ├── merkle-proofs.go
│ │ ├── node-diversity.go
│ │ └── pre-sign.go
├── utils
│ ├── api
│ │ ├── response.go
│ │ └── utils.go
│ ├── arr-utils
│ │ └── arr.go
│ ├── cli
│ │ ├── check_client_status.go
│ │ ├── prompt.go
│ │ ├── prompt_unix.go
│ │ ├── prompt_windows.go
│ │ ├── utils.go
│ │ └── validation.go
│ ├── crypto
│ │ ├── base64.go
│ │ └── rsa.go
│ ├── eth1
│ │ └── eth1.go
│ ├── eth2
│ │ └── eth2.go
│ ├── hex
│ │ └── hex.go
│ ├── log
│ │ ├── colors.go
│ │ └── logger.go
│ ├── math
│ │ └── math.go
│ ├── net
│ │ ├── http.go
│ │ └── net.go
│ ├── stader
│ │ ├── merkle-proof-download.go
│ │ ├── node-diversity.go
│ │ └── pre-signed-flows.go
│ ├── stdr
│ │ ├── config.go
│ │ ├── fee-recipient.go
│ │ └── validator-state.go
│ ├── string-utils
│ │ └── str-convs.go
│ ├── sys
│ │ └── cpu-flags.go
│ ├── term
│ │ ├── term_unix.go
│ │ └── term_windows.go
│ ├── validator
│ │ ├── bls.go
│ │ ├── deposit-data.go
│ │ ├── fee-recipient.go
│ │ └── voluntary-exit.go
│ └── wallet
│ │ └── recover-keys.go
└── version.go
├── sszgen.sh
├── stader-cli
├── build.sh
├── node
│ ├── approve-sd.go
│ ├── claim-rewards.go
│ ├── claim-sp-rewards.go
│ ├── commands.go
│ ├── deposit-sd.go
│ ├── download-sp-merkle-proofs.go
│ ├── get-contracts-info.go
│ ├── register.go
│ ├── repay-sd.go
│ ├── send-el-rewards.go
│ ├── send.go
│ ├── sign-message.go
│ ├── status.go
│ ├── sync.go
│ ├── update-operator-name.go
│ ├── update-operator-reward-address.go
│ ├── update-socialize-el.go
│ ├── utilize-sd.go
│ └── withdraw-sd.go
├── service
│ ├── commands.go
│ ├── config.go
│ ├── configConsensus.go
│ ├── configExecution.go
│ ├── configFallback.go
│ ├── configMEVBoost.go
│ ├── configMonitoring.go
│ ├── guardian.tmpl
│ ├── migration.go
│ └── service.go
├── stader-cli.go
├── validator
│ ├── commands.go
│ ├── deposit.go
│ ├── exit-validator.go
│ ├── export.go
│ ├── send-cl-rewards.go
│ └── status.go
└── wallet
│ ├── bip39
│ └── mnemonic-validator.go
│ ├── commands.go
│ ├── export.go
│ ├── init.go
│ ├── purge.go
│ ├── recover.go
│ ├── status.go
│ └── utils.go
├── stader-lib
├── README.md
├── contracts
│ ├── erc20.go
│ ├── node-el-reward-vault.go
│ ├── operator-rewards-collector.go
│ ├── penalty.go
│ ├── permissionless-node-registry.go
│ ├── permissionless-pool.go
│ ├── pool-utils.go
│ ├── sd-collateral.go
│ ├── sd-utility.go
│ ├── socializing-pool.go
│ ├── stader-config.go
│ ├── stake-pool-manager.go
│ ├── validator-withdraw-vault.go
│ ├── vault-factory.go
│ └── vault-proxy.go
├── node
│ ├── node.go
│ ├── operator.go
│ └── validator.go
├── penalty-tracker
│ └── penalty-tracker.go
├── pool-utils
│ └── pool-utils.go
├── sd-collateral
│ └── sd-deposit.go
├── sdutility
│ └── sd-utility.go
├── socializing-pool
│ └── rewards.go
├── stader-config
│ └── stader-config.go
├── stader
│ ├── abi.go
│ ├── contract.go
│ ├── ec-interface.go
│ └── stader.go
├── stake-pool-manager
│ └── stake-pool-manager.go
├── tokens
│ ├── erc20.go
│ └── native.go
├── types
│ ├── beacon.go
│ ├── operator.go
│ ├── pool-utils.go
│ ├── sd-collateral.go
│ ├── socializing-pool.go
│ └── validator.go
└── utils
│ ├── eth
│ ├── transactions.go
│ └── units.go
│ ├── json
│ └── json.go
│ ├── sd
│ └── sd.go
│ └── wait.go
├── stader
├── api
│ ├── api.go
│ ├── node
│ │ ├── claim-rewards.go
│ │ ├── claim-sp-rewards.go
│ │ ├── commands.go
│ │ ├── deposit-sd.go
│ │ ├── download-sp-merkle-proofs.go
│ │ ├── get-contracts-info.go
│ │ ├── register.go
│ │ ├── repay-sd.go
│ │ ├── sd-status.go
│ │ ├── send-el-rewards.go
│ │ ├── send.go
│ │ ├── sign-message.go
│ │ ├── sign.go
│ │ ├── status.go
│ │ ├── sync.go
│ │ ├── update-operator-name.go
│ │ ├── update-operator-reward-address.go
│ │ ├── update-socialize-el.go
│ │ ├── utility-sd.go
│ │ └── withdraw-sd.go
│ ├── service
│ │ ├── commands.go
│ │ ├── status.go
│ │ └── terminate.go
│ ├── validator
│ │ ├── commands.go
│ │ ├── deposit.go
│ │ ├── exit.go
│ │ └── send-cl-rewards.go
│ └── wallet
│ │ ├── commands.go
│ │ ├── export.go
│ │ ├── init.go
│ │ ├── purge.go
│ │ ├── recover.go
│ │ ├── set-password.go
│ │ └── status.go
├── build.sh
├── ec_migrate multi.sh
├── ec_migrate.sh
├── guardian
│ ├── collector
│ │ ├── beacon-chain-collector.go
│ │ ├── constants.go
│ │ ├── network-collector.go
│ │ ├── operator-collector.go
│ │ └── state-locker.go
│ ├── guardian.go
│ └── metrics-exporter.go
├── node
│ ├── manage-fee-recipient.go
│ ├── merkle-proofs-download.go
│ ├── node.go
│ └── node_test.go
├── prune_provision.sh
└── stader.go
├── update-abis.sh
└── update_package.sh
/.github/workflows/deploy-stader-node.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Stader Node
2 | on:
3 | workflow_dispatch:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | permissions:
9 | id-token: write
10 | contents: read
11 |
12 | jobs:
13 | BUILD_AND_PUBLISH_STADER_PERMISSIONLESS_CLI_NODE:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | env:
18 | AWS_REGION : "us-east-1"
19 |
20 | steps:
21 |
22 | - name: Install binaries to build stader node
23 | uses: awalsh128/cache-apt-pkgs-action@latest
24 | with:
25 | packages: qemu-user-static binfmt-support
26 |
27 | - name: Initializing multiarch build environment.
28 | run: |
29 | docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
30 |
31 | - uses: actions/checkout@v3
32 |
33 | - name: Docker meta
34 | id: meta
35 | uses: yuya-takeyama/docker-tag-from-github-ref-action@v1
36 | with:
37 | remove-version-tag-prefix: false
38 |
39 | - name: Prepare to upload binaries to s3
40 | uses: aws-actions/configure-aws-credentials@v1
41 | with:
42 | role-to-assume: ${{ secrets.ETHX_STADER_NODE_PUBLISH_ROLE_ARN }}
43 | role-duration-seconds: 1200
44 | role-session-name: githubActionsSession
45 | aws-region: ${{ env.AWS_REGION }}
46 |
47 | - name: Login to Docker Hub
48 | uses: docker/login-action@v2
49 | with:
50 | username: ${{ secrets.DOCKERHUB_USERNAME }}
51 | password: ${{ secrets.DOCKERHUB_TOKEN }}
52 |
53 | - name: Build & Release Stader Node CLI
54 | run: |
55 | ./build-release.sh -a -v ${{ steps.meta.outputs.tag }}
56 |
--------------------------------------------------------------------------------
/.github/workflows/go.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a golang project
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
3 |
4 | name: Go
5 |
6 | on:
7 | push:
8 | branches: ["main"]
9 | pull_request:
10 | branches: ["main"]
11 |
12 | jobs:
13 | lint:
14 | name: Lint
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v4
19 |
20 | - name: Set up Go 1.21
21 | uses: actions/setup-go@v5
22 | with:
23 | go-version: '1.21'
24 | cache: false
25 |
26 | - name: Golangci-lint
27 | uses: golangci/golangci-lint-action@v4
28 | with:
29 | version: latest
30 | args: --timeout 3m --verbose --config=.golangci.yml --out-${NO_FUTURE}format colored-line-number
31 | only-new-issues: true
32 | build:
33 | name: Build
34 | runs-on: ubuntu-latest
35 | steps:
36 | - name: Set up Go 1.x
37 | uses: actions/setup-go@v5
38 | with:
39 | go-version: '1.21'
40 | cache: false
41 |
42 | - name: Check out code into the Go module directory
43 | uses: actions/checkout@v4
44 |
45 | - name: Get dependencies
46 | run: |
47 | go get -v -t -d ./...
48 | - name: Test
49 | run: go test -v ./...
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.so
5 | *.dylib
6 |
7 | # Test binary, built with `go test -c`
8 | *.test
9 |
10 | .idea
11 |
12 | # Output of the go coverage tool, specifically when used with LiteIDE
13 | *.out
14 | /build
15 | # Dependency directories (remove the comment below to include it)
16 | # vendor/
17 | #stader
18 | #stader-cli
19 | #.vscode
20 | .DS_Store
21 | #stader-cli/stader-cli
22 |
23 | *.log
24 |
25 | .vscode/launch.json
26 | stader-cli/stader-cli
27 | stader/__debug_bin
28 |
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | linters-settings:
2 | errcheck:
3 | check-type-assertions: true
4 | goconst:
5 | min-len: 2
6 | min-occurrences: 3
7 | gocritic:
8 | enabled-tags:
9 | - diagnostic
10 | - experimental
11 | - opinionated
12 | - performance
13 | - style
14 | govet:
15 | check-shadowing: true
16 | nolintlint:
17 | require-explanation: true
18 | require-specific: true
19 |
20 | linters:
21 | disable-all: true
22 | enable:
23 | - bodyclose
24 | - unused
25 | - dogsled
26 | - dupl
27 | - errcheck
28 | - exportloopref
29 | - exhaustive
30 | - goconst
31 | - gocritic
32 | - gofmt
33 | - goimports
34 | # - gocyclo
35 | - gosec
36 | - gosimple
37 | - govet
38 | - ineffassign
39 | - misspell
40 | - nolintlint
41 | - nakedret
42 | - prealloc
43 | - predeclared
44 | - revive
45 | - staticcheck
46 | - thelper
47 | - tparallel
48 | - typecheck
49 | - unconvert
50 | - unparam
51 | - whitespace
52 | - wsl
53 | issues:
54 | new-from-rev: 934d61944a2565b9e099f2cef2702c0937d743ad
55 | run:
56 | issues-exit-code: 0
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/stader-node.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Stader Node and EthX
2 |
3 | ETHx is an innovative liquid staking token developed by Stader, designed to revolutionize Ethereum staking. Our vision for ETHx is to transform the staking experience, providing users with the unprecedented freedom to move and utilize their staked ETH while continuing to earn rewards and engage with the growing DeFi ecosystem.
4 |
5 | ETHx is built to reduce technical and capital barriers to running nodes on Ethereum and empowering smaller node operators is of the highest importance for Stader. Stader’s ETHx permissionless pool lets anyone operate a node with 4.4 ETH of asset collateral [4 ETH + 0.4ETH worth of SD (Stader’s governance token)].
6 |
7 | This repo contains code for the stader-cli which allows users to easily join EthX permissionless pool and become a crucial part in Stader's missions to revolutionize Ethereum Staking!
8 |
9 | ## Documentation
10 |
11 | NOs can find documentation w.r.t setting a system requirements, how to set a node up, the latest binaries etc here https://staderlabs.gitbook.io/ethereum/
12 |
13 | ## Integration testing
14 |
15 | Upcoming
16 |
--------------------------------------------------------------------------------
/abis/NodeElRewardVault.abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "inputs": [
9 | {
10 | "internalType": "address",
11 | "name": "recipient",
12 | "type": "address"
13 | },
14 | {
15 | "internalType": "uint256",
16 | "name": "amount",
17 | "type": "uint256"
18 | }
19 | ],
20 | "name": "ETHTransferFailed",
21 | "type": "error"
22 | },
23 | {
24 | "inputs": [],
25 | "name": "NotEnoughRewardToWithdraw",
26 | "type": "error"
27 | },
28 | {
29 | "inputs": [],
30 | "name": "TransferFailed",
31 | "type": "error"
32 | },
33 | {
34 | "anonymous": false,
35 | "inputs": [
36 | {
37 | "indexed": true,
38 | "internalType": "address",
39 | "name": "sender",
40 | "type": "address"
41 | },
42 | {
43 | "indexed": false,
44 | "internalType": "uint256",
45 | "name": "amount",
46 | "type": "uint256"
47 | }
48 | ],
49 | "name": "ETHReceived",
50 | "type": "event"
51 | },
52 | {
53 | "anonymous": false,
54 | "inputs": [
55 | {
56 | "indexed": false,
57 | "internalType": "address",
58 | "name": "staderConfig",
59 | "type": "address"
60 | }
61 | ],
62 | "name": "UpdatedStaderConfig",
63 | "type": "event"
64 | },
65 | {
66 | "anonymous": false,
67 | "inputs": [
68 | {
69 | "indexed": false,
70 | "internalType": "uint256",
71 | "name": "protocolAmount",
72 | "type": "uint256"
73 | },
74 | {
75 | "indexed": false,
76 | "internalType": "uint256",
77 | "name": "operatorAmount",
78 | "type": "uint256"
79 | },
80 | {
81 | "indexed": false,
82 | "internalType": "uint256",
83 | "name": "userAmount",
84 | "type": "uint256"
85 | }
86 | ],
87 | "name": "Withdrawal",
88 | "type": "event"
89 | },
90 | {
91 | "inputs": [],
92 | "name": "withdraw",
93 | "outputs": [],
94 | "stateMutability": "nonpayable",
95 | "type": "function"
96 | },
97 | {
98 | "stateMutability": "payable",
99 | "type": "receive"
100 | }
101 | ]
--------------------------------------------------------------------------------
/add-gplv3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | for i in $(git ls-files | grep "\.go$" ); do
4 | echo "Adding GPL3 header to $i"
5 | cat license-short.txt | sed "s/{open}/\/*/g" | sed "s/{close}/*\//g" | cat - $i > /tmp/temp && mv /tmp/temp $i
6 | done
7 |
--------------------------------------------------------------------------------
/build-builder.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | # Print usage
22 | usage() {
23 | echo "Usage: build-release.sh -v "
24 | echo "This script builds the Stader node builder image used to build the daemon binaries."
25 | exit 0
26 | }
27 |
28 | # =================
29 | # === Main Body ===
30 | # =================
31 |
32 | # Get the version
33 | while getopts "admv:" FLAG; do
34 | case "$FLAG" in
35 | v) VERSION="$OPTARG" ;;
36 | *) usage ;;
37 | esac
38 | done
39 | if [ -z "$VERSION" ]; then
40 | usage
41 | fi
42 |
43 | echo -n "Building Docker image... "
44 | docker build -t staderdev/stader-node-builder:$VERSION -f docker/stader-node-builder .
45 | docker tag staderdev/stader-node-builder:$VERSION staderdev/stader-node-builder:latest
46 | docker push staderdev/stader-node-builder:$VERSION
47 | docker push staderdev/stader-node-builder:latest
48 | echo "done!"
--------------------------------------------------------------------------------
/build-ec-migrate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | # Print usage
22 | usage() {
23 | echo "Usage: build-ec-migrate.sh -v "
24 | echo "This script builds the EC Migrator image."
25 | exit 0
26 | }
27 |
28 | # =================
29 | # === Main Body ===
30 | # =================
31 |
32 | # Get the version
33 | while getopts "admv:" FLAG; do
34 | case "$FLAG" in
35 | v) VERSION="$OPTARG" ;;
36 | *) usage ;;
37 | esac
38 | done
39 | if [ -z "$VERSION" ]; then
40 | usage
41 | fi
42 |
43 | echo -n "Building Docker image... "
44 | echo "Building Docker EC Migrator image..."
45 | docker buildx build --platform=linux/amd64 -t staderdev/ec-migrator:$VERSION-amd64 -f docker/stader-ec-migrator --load . || fail "Error building amd64 Docker ec-migrator image."
46 | docker buildx build --platform=linux/arm64 -t staderdev/ec-migrator:$VERSION-arm64 -f docker/stader-ec-migrator --load . || fail "Error building arm64 Docker ec-migrator image."
47 | echo "done!"
48 |
49 | echo -n "Pushing to Docker Hub... "
50 | docker push staderdev/ec-migrator:$VERSION-amd64 || fail "Error pushing amd64 Docker EC Migrator image to Docker Hub."
51 | docker push staderdev/ec-migrator:$VERSION-arm64 || fail "Error pushing arm Docker EC Migrator image to Docker Hub."
52 | echo "done!"
53 |
54 | echo -n "Building Docker manifest... "
55 | rm -f ~/.docker/manifests/docker.io_staderdev_ec-migrator-$VERSION
56 | docker manifest create staderdev/ec-migrator:$VERSION --amend staderdev/ec-migrator:$VERSION-amd64 --amend staderdev/ec-migrator:$VERSION-arm64
57 | echo "done!"
58 |
59 | echo -n "Pushing to Docker Hub... "
60 | docker manifest push --purge staderdev/ec-migrator:$VERSION
61 | echo "done!"
--------------------------------------------------------------------------------
/daemon-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | # Get the platform type and run the build script if possible
22 | PLATFORM=$(uname -s)
23 | if [ "$PLATFORM" = "Linux" ]; then
24 | docker run --rm -v $PWD:/stader-node staderdev/stader-node-builder:latest /stader-node/stader/build.sh
25 | else
26 | echo "Platform ${PLATFORM} is not supported by this script, please build the daemon manually."
27 | exit 1
28 | fi
29 |
--------------------------------------------------------------------------------
/daemon-local.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Print usage
4 | usage() {
5 | echo "Usage: daemon-local.sh -v "
6 | exit 0
7 | }
8 |
9 | DOCKER_ACCOUNT=staderlabs
10 | # Parse arguments
11 | while getopts "acpdnlrfv:" FLAG; do
12 | case "$FLAG" in
13 | v) VERSION="$OPTARG" ;;
14 | *) usage ;;
15 | esac
16 | done
17 | if [ -z "$VERSION" ]; then
18 | usage
19 | fi
20 |
21 | # Get CPU architecture
22 | UNAME_VAL=$(uname -m)
23 | ARCH=""
24 | case $UNAME_VAL in
25 | x86_64) ARCH="amd64" ;;
26 | aarch64) ARCH="arm64" ;;
27 | arm64) ARCH="arm64" ;;
28 | *) fail "CPU architecture not supported: $UNAME_VAL" ;;
29 | esac
30 |
31 |
32 | echo "Start buiding: " $VERSION
33 |
34 | docker run --rm -v $PWD:/stader-node staderdev/stader-node-builder:latest /stader-node/stader/build.sh
35 |
36 | cp stader/stader-daemon-* build/$VERSION
37 |
38 | echo "done!"
39 |
40 | docker buildx build --platform=linux/$ARCH -t $DOCKER_ACCOUNT/stader-permissionless:$VERSION -f docker/stader-dockerfile --load . || fail "Error building $ARCH Docker Stader Daemon image."
41 |
42 | echo "done!"
43 |
--------------------------------------------------------------------------------
/docker/stader-dockerfile:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | FROM debian:bookworm-slim
20 |
21 | ARG TARGETARCH
22 | COPY ./stader/stader-daemon-linux-${TARGETARCH} /go/bin/stader
23 |
24 | RUN apt update && apt install ca-certificates -y
25 |
26 | # Container entry point
27 | ENTRYPOINT ["/go/bin/stader"]
28 |
--------------------------------------------------------------------------------
/docker/stader-ec-migrator:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Start from Alpine image
20 | FROM alpine:latest
21 |
22 | # Install rsync
23 | RUN apk add rsync
24 |
25 | # Copy the provisioning script
26 | COPY stader/ec_migrate.sh /srv
27 |
28 | # Container entry point
29 | ENTRYPOINT ["/srv/ec_migrate.sh"]
30 |
--------------------------------------------------------------------------------
/docker/stader-node-builder:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # This image is used to build the Stader and related artifacts
20 |
21 | FROM golang:1.21.10-bookworm
22 |
23 | # Install build tools
24 | RUN dpkg --add-architecture arm64
25 | RUN apt update && apt install -y \
26 | build-essential \
27 | gcc-aarch64-linux-gnu \
28 | libc6-dev-arm64-cross\
29 | g++-aarch64-linux-gnu \
30 | wget
31 |
32 | # Cache go dependencies
33 | ADD go.mod /src/go.mod
34 | ADD go.sum /src/go.sum
35 | WORKDIR /src
36 | RUN go mod download all
37 | WORKDIR /
38 | RUN rm -rf /src
39 |
--------------------------------------------------------------------------------
/docker/stader-prune-provision:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Start from Alpine image
20 | FROM alpine:latest
21 |
22 | # Copy the provisioning script
23 | COPY stader/prune_provision.sh /srv
24 |
25 | # Container entry point
26 | ENTRYPOINT ["/srv/prune_provision.sh"]
27 |
--------------------------------------------------------------------------------
/install/addons/gww/.ignoreme:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stader-labs/stader-node/2fd5eddab6360b15017ee77d53ab2964ab58d781/install/addons/gww/.ignoreme
--------------------------------------------------------------------------------
/install/grafana-prometheus-datasource.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | apiVersion: 1
20 |
21 | deleteDatasources:
22 | - name: Prometheus
23 | orgId: 1
24 |
25 | datasources:
26 | - name: Prometheus
27 | type: prometheus
28 | access: proxy
29 | orgId: 1
30 | url: http://prometheus:9091
31 | basicAuth: false
32 | isDefault: true
33 | version: 1
34 | editable: true
35 |
--------------------------------------------------------------------------------
/install/override/addons/gww/addon_gww.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the Graffiti Wall Addon container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | addon_gww:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/api.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the API container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | api:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/eth1.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the eth1 container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | eth1:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/eth2.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the eth2 container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | eth2:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/exporter.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the node exporter container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | node-exporter:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/grafana.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the Grafana container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | grafana:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/guardian.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the guardian container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | guardian:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/mev-boost.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the MEV Boost container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | mev-boost:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/node.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the node container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | node:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/override/prometheus.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the Prometheus container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | prometheus:
27 | x-comment: Add your customizations below this line
28 | networks:
29 | # Bridge so node-exporter can get the real NIC details
30 | # See https://stackoverflow.com/a/66689508 for more info
31 | monitor-net:
32 | driver: bridge
33 | ipam:
34 | driver: default
35 | config:
36 | - subnet: 172.23.0.0/16
37 | ip_range: 172.23.5.0/24
38 | gateway: 172.23.5.254
--------------------------------------------------------------------------------
/install/override/validator.yml:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Enter your own customizations for the validator container here. These changes will persist after upgrades, so you only need to do them once.
20 | #
21 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
22 | # for more information on overriding specific parameters of docker-compose files.
23 |
24 | version: "3.7"
25 | services:
26 | validator:
27 | x-comment: Add your customizations below this line
28 |
--------------------------------------------------------------------------------
/install/prometheus.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Default Prometheus configuration for Stader
20 |
21 | global:
22 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
23 | scrape_timeout: 12s # Timeout must be shorter than the interval
24 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
25 |
26 | scrape_configs:
27 | - job_name: 'prometheus'
28 | static_configs:
29 | - targets: ['localhost:${PROMETHEUS_PORT:-9091}']
30 |
31 | - job_name: 'node'
32 | static_configs:
33 | # node-exporter is on the host network so it can get access to the actual machine's network info
34 | # We have to use 'hosts.docker.internal' to refer to it due to this configuration
35 | - targets: ['host.docker.internal:${EXPORTER_METRICS_PORT:-9103}']
36 |
37 | - job_name: 'geth'
38 | static_configs:
39 | - targets: ['${EC_HOSTNAME:-eth1}:${EC_METRICS_PORT:-9105}']
40 | metrics_path: /debug/metrics/prometheus
41 |
42 | - job_name: 'eth1'
43 | static_configs:
44 | - targets: ['${EC_HOSTNAME:-eth1}:${EC_METRICS_PORT:-9105}']
45 |
46 | - job_name: 'eth2'
47 | static_configs:
48 | - targets: ['${CC_HOSTNAME:-eth2}:${BN_METRICS_PORT:-9100}']
49 |
50 | - job_name: 'validator'
51 | static_configs:
52 | - targets: ['validator:${VC_METRICS_PORT:-9101}']
53 |
54 | - job_name: 'stader'
55 | scrape_interval: 5m
56 | scrape_timeout: 5m
57 | static_configs:
58 | - targets: ['guardian:${NODE_METRICS_PORT:-9104}']
59 |
--------------------------------------------------------------------------------
/install/scripts/NethermindPruneStarter/NethermindPruneStarter.deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeTarget": {
3 | "name": ".NETCoreApp,Version=v8.0",
4 | "signature": ""
5 | },
6 | "compilationOptions": {},
7 | "targets": {
8 | ".NETCoreApp,Version=v8.0": {
9 | "NethermindPruneStarter/1.0.1": {
10 | "dependencies": {
11 | "Newtonsoft.Json": "13.0.2"
12 | },
13 | "runtime": {
14 | "NethermindPruneStarter.dll": {}
15 | }
16 | },
17 | "Newtonsoft.Json/13.0.2": {
18 | "runtime": {
19 | "lib/net6.0/Newtonsoft.Json.dll": {
20 | "assemblyVersion": "13.0.0.0",
21 | "fileVersion": "13.0.2.27524"
22 | }
23 | }
24 | }
25 | }
26 | },
27 | "libraries": {
28 | "NethermindPruneStarter/1.0.1": {
29 | "type": "project",
30 | "serviceable": false,
31 | "sha512": ""
32 | },
33 | "Newtonsoft.Json/13.0.2": {
34 | "type": "package",
35 | "serviceable": true,
36 | "sha512": "sha512-R2pZ3B0UjeyHShm9vG+Tu0EBb2lC8b0dFzV9gVn50ofHXh9Smjk6kTn7A/FdAsC8B5cKib1OnGYOXxRBz5XQDg==",
37 | "path": "newtonsoft.json/13.0.2",
38 | "hashPath": "newtonsoft.json.13.0.2.nupkg.sha512"
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/install/scripts/NethermindPruneStarter/NethermindPruneStarter.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stader-labs/stader-node/2fd5eddab6360b15017ee77d53ab2964ab58d781/install/scripts/NethermindPruneStarter/NethermindPruneStarter.dll
--------------------------------------------------------------------------------
/install/scripts/NethermindPruneStarter/NethermindPruneStarter.runtimeconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "tfm": "net8.0",
4 | "framework": {
5 | "name": "Microsoft.NETCore.App",
6 | "version": "8.0.2"
7 | },
8 | "configProperties": {
9 | "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/install/scripts/NethermindPruneStarter/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stader-labs/stader-node/2fd5eddab6360b15017ee77d53ab2964ab58d781/install/scripts/NethermindPruneStarter/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/install/scripts/restart-vc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # This work is licensed and released under GNU GPL v3 or any other later versions.
3 | # The full text of the license is below/ found at
4 |
5 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 |
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 |
20 | # This script is used to restart your Validator Client service.
21 | # It is run in Native Mode only when the Stader node needs to restart your Validator Client (for example, to load new validator keys).
22 | # It is not used in standard (docker-based) Stader setups.
23 |
24 | # The command below is an example only.
25 | # Replace it with your own commands to restart your Validator Client service.
26 |
27 | #sudo systemctl restart lighthouse-validator
28 |
--------------------------------------------------------------------------------
/install/scripts/start-mev-boost.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This work is licensed and released under GNU GPL v3 or any other later versions.
3 | # The full text of the license is below/ found at
4 |
5 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 |
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 |
20 |
21 | # Set up the network-based flag
22 | if [ "$NETWORK" = "mainnet" ]; then
23 | MEV_NETWORK="mainnet"
24 | elif [ "$NETWORK" = "devnet" ]; then
25 | MEV_NETWORK="holesky"
26 | elif [ "$NETWORK" = "holesky" ]; then
27 | MEV_NETWORK="holesky"
28 | else
29 | echo "Unknown network [$NETWORK]"
30 | exit 1
31 | fi
32 |
33 | # Run MEV-boost
34 | exec /app/mev-boost -${MEV_NETWORK} -addr 0.0.0.0:${MEV_BOOST_PORT} -relay-check -relays ${MEV_BOOST_RELAYS}
--------------------------------------------------------------------------------
/install/scripts/stop-validator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # This work is licensed and released under GNU GPL v3 or any other later versions.
3 | # The full text of the license is below/ found at
4 |
5 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 |
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see .
19 |
20 | # This script is used to stop your Validator Client service.
21 | # It is run in Native Mode only when the Stader Node needs to stop your Validator Client because of a misconfiguration or other error.
22 | # It is not used in Docker Mode or Hybrid Mode.
23 |
24 | # The command below is an example only.
25 | # Replace it with your own command to stop your Validator Client service.
26 |
27 | #sudo systemctl stop lighthouse-validator
28 |
--------------------------------------------------------------------------------
/install/templates/addons/gww/addon_gww.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/api.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | addon_gww:
29 | image: ${ADDON_GWW_CONTAINER_TAG}
30 | user: root
31 | container_name: ${COMPOSE_PROJECT_NAME}_addon_gww
32 | restart: unless-stopped
33 | volumes:
34 | - ${STADER_FOLDER}/addons/gww:/gww
35 | networks:
36 | - net
37 | entrypoint:
38 | - /go/bin/drawer
39 | - --output_file=/gww/graffiti.txt
40 | - --input_url=${ADDON_GWW_INPUT_URL}
41 | - --consensus_client=${CC_CLIENT}
42 | - --nimbus_url=http://${CC_HOSTNAME:-eth2}:${BN_API_PORT:-5052}
43 | - --graffiti_prefix=${GRAFFITI_PREFIX}
44 | - --network=${NETWORK}
45 | - --update_wall_time=${ADDON_GWW_UPDATE_WALL_TIME}
46 | - --update_input_time=${ADDON_GWW_UPDATE_INPUT_TIME}
47 | - --update_pixel_time=${ADDON_GWW_UPDATE_PIXEL_TIME}
48 | cap_drop:
49 | - all
50 | security_opt:
51 | - no-new-privileges
52 | networks:
53 | net:
--------------------------------------------------------------------------------
/install/templates/api.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/api.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | api:
29 | image: ${STADER_NODE_IMAGE}
30 | container_name: ${COMPOSE_PROJECT_NAME}_api
31 | restart: unless-stopped
32 | stop_signal: SIGKILL
33 | stop_grace_period: 1s
34 | volumes:
35 | - /var/run/docker.sock:/var/run/docker.sock
36 | - ${STADER_FOLDER}:/.stader
37 | - ${STADER_DATA_FOLDER}:/.stader/data
38 | networks:
39 | - net
40 | entrypoint: /bin/sleep
41 | command: "infinity"
42 | cap_drop:
43 | - all
44 | cap_add:
45 | - dac_override
46 | security_opt:
47 | - no-new-privileges
48 | networks:
49 | net:
--------------------------------------------------------------------------------
/install/templates/exporter.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/exporter.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | node-exporter:
29 | image: ${EXPORTER_CONTAINER_TAG}
30 | container_name: ${COMPOSE_PROJECT_NAME}_exporter
31 | cap_drop:
32 | - ALL
33 | user: "65534:65534"
34 | restart: unless-stopped
35 | command: [ "--path.procfs=/host/proc", "--path.sysfs=/host/sys", "--collector.textfile.directory=/host/textfile_collector", "--web.listen-address=:${EXPORTER_METRICS_PORT:-9103}"${EXPORTER_ROOTFS_COMMAND}${EXPORTER_ADDITIONAL_FLAGS} ]
36 | volumes: [ "/proc:/host/proc:ro,rslave", "/sys:/host/sys:ro,rslave", "/var/lib/node_exporter/textfile_collector:/host/textfile_collector:ro"${EXPORTER_ROOTFS_VOLUME} ]
37 | network_mode: host
38 | networks:
39 | net:
--------------------------------------------------------------------------------
/install/templates/grafana-prometheus-datasource.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | apiVersion: 1
20 |
21 | deleteDatasources:
22 | - name: Prometheus
23 | orgId: 1
24 |
25 | datasources:
26 | - name: Prometheus
27 | type: prometheus
28 | access: proxy
29 | orgId: 1
30 | url: http://prometheus:9091
31 | basicAuth: false
32 | isDefault: true
33 | version: 1
34 | editable: true
35 |
--------------------------------------------------------------------------------
/install/templates/grafana.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/grafana.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | grafana:
29 | image: ${GRAFANA_CONTAINER_TAG}
30 | container_name: ${COMPOSE_PROJECT_NAME}_grafana
31 | restart: unless-stopped
32 | environment:
33 | - GF_SERVER_HTTP_PORT=${GRAFANA_PORT:-3100}
34 | ports:
35 | - "${GRAFANA_PORT:-3100}:${GRAFANA_PORT:-3100}/tcp"
36 | volumes:
37 | - "${STADER_FOLDER}/grafana-prometheus-datasource.yml:/etc/grafana/provisioning/datasources/prometheus.yml"
38 | - "grafana-storage:/var/lib/grafana"
39 | networks:
40 | - net
41 | networks:
42 | net:
43 | volumes:
44 | grafana-storage:
--------------------------------------------------------------------------------
/install/templates/guardian.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/guardian.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | guardian:
29 | image: ${STADER_NODE_IMAGE}
30 | container_name: ${COMPOSE_PROJECT_NAME}_guardian
31 | restart: unless-stopped
32 | ports: [${GUARDIAN_OPEN_PORTS}]
33 | volumes:
34 | - ${STADER_FOLDER}:/.stader
35 | - ${STADER_DATA_FOLDER}:/.stader/data
36 | networks:
37 | - net
38 | command: "-m 0.0.0.0 -r ${NODE_METRICS_PORT:-9104} guardian"
39 | cap_drop:
40 | - all
41 | cap_add:
42 | - dac_override
43 | security_opt:
44 | - no-new-privileges
45 | networks:
46 | net:
--------------------------------------------------------------------------------
/install/templates/mev-boost.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/mev-boost.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | mev-boost:
29 | image: ${MEV_BOOST_CONTAINER_TAG}
30 | container_name: ${COMPOSE_PROJECT_NAME}_mev-boost
31 | restart: unless-stopped
32 | ports: [${MEV_BOOST_OPEN_API_PORT}]
33 | volumes:
34 | - ${STADER_FOLDER}/scripts:/setup:ro
35 | networks:
36 | - net
37 | environment:
38 | - NETWORK=${NETWORK}
39 | - MEV_BOOST_PORT=${MEV_BOOST_PORT}
40 | - MEV_BOOST_RELAYS=${MEV_BOOST_RELAYS}
41 | entrypoint: sh
42 | command: "/setup/start-mev-boost.sh"
43 | cap_drop:
44 | - all
45 | cap_add:
46 | - dac_override
47 | security_opt:
48 | - no-new-privileges
49 | networks:
50 | net:
--------------------------------------------------------------------------------
/install/templates/node.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/node.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | node:
29 | image: ${STADER_NODE_IMAGE}
30 | container_name: ${COMPOSE_PROJECT_NAME}_node
31 | restart: unless-stopped
32 | volumes:
33 | - /var/run/docker.sock:/var/run/docker.sock
34 | - ${STADER_FOLDER}:/.stader
35 | - ${STADER_DATA_FOLDER}:/.stader/data
36 | networks:
37 | - net
38 | command: "node"
39 | cap_drop:
40 | - all
41 | cap_add:
42 | - dac_override
43 | security_opt:
44 | - no-new-privileges
45 | networks:
46 | net:
--------------------------------------------------------------------------------
/install/templates/prometheus.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/prometheus.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | prometheus:
29 | image: ${PROMETHEUS_CONTAINER_TAG}
30 | container_name: ${COMPOSE_PROJECT_NAME}_prometheus
31 | restart: unless-stopped
32 | command: [ "--web.listen-address=:${PROMETHEUS_PORT:-9091}", "--config.file=/etc/prometheus/prometheus.yml"${PROMETHEUS_ADDITIONAL_FLAGS} ]
33 | ports: [${PROMETHEUS_OPEN_PORTS}]
34 | volumes:
35 | - "${STADER_FOLDER}/prometheus.yml:/etc/prometheus/prometheus.yml"
36 | - "prometheus-data:/prometheus"
37 | networks:
38 | - net
39 | - monitor-net
40 | extra_hosts:
41 | - "host.docker.internal:host-gateway"
42 | networks:
43 | # Bridge so node-exporter can get the real NIC details
44 | # See https://stackoverflow.com/a/66689508 for more info
45 | monitor-net:
46 | driver: bridge
47 | ipam:
48 | driver: default
49 | config:
50 | - subnet: 172.23.0.0/16
51 | ip_range: 172.23.5.0/24
52 | gateway: 172.23.5.254
53 | net:
54 | volumes:
55 | prometheus-data:
--------------------------------------------------------------------------------
/license-short.txt:
--------------------------------------------------------------------------------
1 | {open}
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | {close}
20 |
--------------------------------------------------------------------------------
/shared/services/config/dev-presign-public-key.txt:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF5RTJYV055bW5idEhsTHVhTndyWgpLWG1BcEMvM1JWaVpJSTNhVnhVbzg5T3NjblNxTTdQUmxVbjlSR29BZUdPcVBkVFpRRzliUWRZckxWYXRpTU9QCkRuOU1wT01NcEszRCtpOVcvUC9Fdjc4cGE5MnV3WGR3UTM3Y2F2RmI0ZVFwOU0zR2p5eGlCVjlybzVEVGtmTk8KS1dBWnVnaklGZHFyNXNWVDJiQnhORzJBeTYzQnMzTVVhcGtMNFpYRk1NSEdZa0RWV1pnalE2OEtKc0c1NWdkSgp5RkVFWmUwdGpMSHVzaGszZVlQVzA4S0NRQ25uR1dDYUV4SEFEcnMwU3E0ekJQeEJWMExjV0l4cCt6dHFBVGUyCnYvbSs2RDVKVkFIN0w3S01ZUGZNWXVPUkN1RSsvUkxNU2hXZFp6czErSjI3MWI1b3pUZVhIQTJ6VG5ES3JqNWwKVXZNK0h0dEFQdXpXUTNsTThudG1Ra1JLR3NwekY5bWtkZy95cVNSQ3B2bEtFSjJ3andXTGxjNzA3SldkQXRwbApaU1JiREorYkZMVUZRRy85SnMwSjMzeE96a1RjTmdFNmw0dUFIT1I1OTMvSHU4MzRBbzRub2xHbVpiVjVpNUdRCmo4TTlWdnlEM0JLcExWRTgrYjEzYTc1TXpoZVFTeVlJakRmbjNHZE9ma0tWaGpzWnFSNzRONWRnNE5sejc5amoKazZ3Lzg3bllVTmZMV3NYT1hvTk5aaW82cW1oNXk4ZWZxU0xNbG1YMzRrMHhiNlJ4Z1ArTWwvYkhXMHJqTmRPQgpXbU1lbVcrWk9TOWFQWjA5anpxRkpBcG8wTnF4UGlyMFhHU00yS1c3aG5VM3ZZd1E3NVBGamZuc0cvOVhjQmtaCmxBTHIya21aUEZSNGFQcmpjZ2c5SmxVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
--------------------------------------------------------------------------------
/shared/services/config/prod-presign-public-key.txt:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFtWHlrVHZ0R0pXZEovR2IxWERxdQpxZWczK3FhbzRjclBYeE12K2xIV0hxbWtERllPaGJYbS82UmI4eVd2WW9VNExnZjhuaHA4UGhFTkdId2lUeks1CjFmL2Y0TzQzUzF3SUxDbE5LVVExNlR1N0ZWRU9Id2V0dXZHTzJFTEtVUHJMRStaWVZIRGF4eGJYZjE0SysxK0gKalh1L0FwMUFzSEJTSCtlbWZ2all4cnNoVUxFRXJXcHZqbWtZZDJVRE1oeUNqUk9zMU9qdThqeU1WODh3M3Z0NwpJYlhIbythNkpNbFRNSXpaWkNVWVhCOXdrOFRVd3ZTbEJ1QzFPU1JjTVFldVpLVU1NVGxzU0JzdXZmM2dwbFFLCnViekRrUlZ6Nk5QeU5zUHBVT2h3bzQvenBFbjk3QlVLUU8wNm1YaEg4SWFKaWtHUmxsZk1OTklGcWd1QXYrangKRzlhbVY5MGNsU1BoaUpoMmJ4TUZQaEJUcThUYVJqelBVZXYvSU1rS0xMVTN5Ukh1LzUyckpUTnl4bnNBZ0s0cwpCK0draXBBbSs0cHROaGFtOHVSOEZhMDQ3czQ5OGJ5ek5PaERHaUJiM0dJM21mZld2T0pNN05KdGpGd0tCOCtrCkx6bEtMMzZjbHUvY2Y2bDJ0OVh1RndIZmhYUWZPZktkSjdzWitsZkJzb1VPcE5pUFpaNzNrSWlnV0sxQi9XVnAKelh0Undic1Fhdkd5em9CVHN5L3VCL054Sm8zaUJVVG1zS1VLa1hLb3loaU5lY2FXbUd1U1lpeTBXRmlpQ3hhRgo0aTExSFYzSk8vcGhyZXpoRHpxK24wWWN5RktEL3BhSE5kTm9EUDFnTEU1eVRpN24rRG1lU2x3aVlRS0g1SVg5CmFiTlZONnRYTlh6b0NLWVVnNklnU2dzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
--------------------------------------------------------------------------------
/shared/services/config/stage-presign-public-key.txt:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUE0T2I4VDZsVmxSRzVhcTZtVGlMUQpCSlNaM0pYQy9xNVVGRnNCc3k2NVVDMlJvUzVDaWdkcWh5SDZPVkJJTVJBVmxqQ3hFQldaeVlRbkNVSHluaXh5CjcrUWhsUFRxZVNwYURnOTZaOWp6NE96RjNEUXpLSkpiZkRlSUp2cGdzblZPU25kWE5tMnlFZzNGL3FGeTdXakUKVHNjb1RRN3hITnB6SzF0elM2SFpodHZUY2hZOXpXaHhzN3htbSttd1FRWnEyZXRsc3l0S1FqT1dvaFdyUzBLcgo1UkNNUXRON0Iva2RJYlljZW5HRlhJSy9IVGhPaDZEdVg2dmlTUDZPclQvSmtRbkEwWTMydzRzWG9mQXNBSHR4Ci9uMVBOUE14SnJvQ08xcTZMVnVuN3QrZEd6Q294bzBCcFZaczk0NHlWQVdrNm5wMmo2UG15NkRMcmpjVndDSTcKdFBlWkRwU0Z3My82ZUg0WGdOT2NHeURqVmFBY3A1VWc3bTE1NU10cElFdG94M21IYk0wWUVVRHVJN0VkK3ZwSApabDdzQmlDbFN5K1pmMTJhb1ZVVWhFVzN4OFM0UnQ2aHlVeWxUV1FmWHFDWE1CS2kzcW5JWkZPYzFQYmNxNTJrCklQZ0d1eFJuN211L1BhaHBFV1U4S3ZmZXJId1BjSEJqdGdrOVZ5YWNOcjZCK0Q3eGYvVFVabC9VNnowRDJyUTgKaG9GTjdueThZWk9GUGczOWFQRUQxR0JMUW5sNmowUVJYSWJQd0svOUxvT1lDSnhiOG5LQ0xPbmxNKzcyQzhLSwpydWpDWk93aXBJY0dvc041M3lNOXdRUzVUVWloWTk2NTB1N0hIbU9nSUJ3Y1BOOEdYVWQwWUVwZWRzQXFYTlRsCmFZNjRvRkRQZThUR3owSGhLand0WWJzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
--------------------------------------------------------------------------------
/shared/services/eth1.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package services
21 |
22 | import (
23 | "context"
24 |
25 | "github.com/stader-labs/stader-node/stader-lib/stader"
26 | )
27 |
28 | func GetEthClientLatestBlockTimestamp(ec stader.ExecutionClient) (uint64, error) {
29 | // Get latest block
30 | header, err := ec.HeaderByNumber(context.Background(), nil)
31 | if err != nil {
32 | return 0, err
33 | }
34 |
35 | // Return block timestamp
36 | return header.Time, nil
37 | }
38 |
--------------------------------------------------------------------------------
/shared/services/stader/api.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package stader
21 |
22 | import (
23 | "encoding/json"
24 | "fmt"
25 |
26 | "github.com/ethereum/go-ethereum/common"
27 |
28 | "github.com/stader-labs/stader-node/shared/types/api"
29 | )
30 |
31 | // Wait for a transaction
32 | func (c *Client) WaitForTransaction(txHash common.Hash) (api.APIResponse, error) {
33 | responseBytes, err := c.callAPI(fmt.Sprintf("wait %s", txHash.String()))
34 | if err != nil {
35 | return api.APIResponse{}, fmt.Errorf("Error waiting for tx: %w", err)
36 | }
37 | var response api.APIResponse
38 | if err := json.Unmarshal(responseBytes, &response); err != nil {
39 | return api.APIResponse{}, fmt.Errorf("Error decoding wait response: %w", err)
40 | }
41 | if response.Error != "" {
42 | return api.APIResponse{}, fmt.Errorf("Error waiting for tx: %s", response.Error)
43 | }
44 | return response, nil
45 | }
46 |
--------------------------------------------------------------------------------
/shared/services/stader/external-urls.go:
--------------------------------------------------------------------------------
1 | package stader
2 |
3 | const PreSignSendApi = "https://stage-ethx-offchain.staderlabs.click/presign"
4 | const PreSignCheckApi = "https://stage-ethx-offchain.staderlabs.click/msgSubmitted"
5 | const PublicKeyApi = "https://stage-ethx-offchain.staderlabs.click/publicKey"
6 | const MerkleProofAggregateGetterApi = "https://stage-ethx-offchain.staderlabs.click/merklesForElRewards/proofs/%s"
7 |
--------------------------------------------------------------------------------
/shared/services/stader/gas.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package stader
21 |
22 | import (
23 | "fmt"
24 | )
25 |
26 | const (
27 | colorReset string = "\033[0m"
28 | colorYellow string = "\033[33m"
29 | )
30 |
31 | // Print a warning about the gas estimate for operations that have multiple transactions
32 | func (sd *Client) PrintMultiTxWarning() {
33 | fmt.Printf("%sNOTE: This operation requires multiple transactions.\n%s",
34 | colorYellow,
35 | colorReset)
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/shared/services/stader/legacy-client.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package stader
21 |
22 | import (
23 | "fmt"
24 | "os"
25 |
26 | "github.com/alessio/shellescape"
27 | "github.com/mitchellh/go-homedir"
28 | "github.com/stader-labs/stader-node/shared/services/config"
29 | )
30 |
31 | // Config
32 | const (
33 | LegacyGlobalConfigFile = "config.yml"
34 | LegacyUserConfigFile = "settings.yml"
35 | LegacyComposeFile = "docker-compose.yml"
36 | LegacyMetricsComposeFile = "docker-compose-metrics.yml"
37 | LegacyFallbackComposeFile = "docker-compose-fallback.yml"
38 | )
39 |
40 | // Load the global config
41 | func (c *Client) LoadGlobalConfig_Legacy(globalConfigPath string) (config.LegacyStaderConfig, error) {
42 | return c.loadConfig_Legacy(globalConfigPath)
43 | }
44 |
45 | // Load/save the user config
46 | func (c *Client) LoadUserConfig_Legacy(userConfigPath string) (config.LegacyStaderConfig, error) {
47 | return c.loadConfig_Legacy(userConfigPath)
48 | }
49 |
50 | // Load the merged global & user config
51 | func (c *Client) LoadMergedConfig_Legacy(globalConfigPath string, userConfigPath string) (config.LegacyStaderConfig, error) {
52 | globalConfig, err := c.LoadGlobalConfig_Legacy(globalConfigPath)
53 | if err != nil {
54 | return config.LegacyStaderConfig{}, err
55 | }
56 | userConfig, err := c.LoadUserConfig_Legacy(userConfigPath)
57 | if err != nil {
58 | return config.LegacyStaderConfig{}, err
59 | }
60 | return config.Merge(&globalConfig, &userConfig)
61 | }
62 |
63 | // Load a config file
64 | func (c *Client) loadConfig_Legacy(path string) (config.LegacyStaderConfig, error) {
65 | expandedPath, err := homedir.Expand(path)
66 | if err != nil {
67 | return config.LegacyStaderConfig{}, err
68 | }
69 | configBytes, err := os.ReadFile(expandedPath)
70 | if err != nil {
71 | return config.LegacyStaderConfig{}, fmt.Errorf("Could not read Stader config at %s: %w", shellescape.Quote(path), err)
72 | }
73 | return config.Parse(configBytes)
74 | }
75 |
--------------------------------------------------------------------------------
/shared/services/stader/service.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package stader
21 |
22 | import (
23 | "encoding/json"
24 | "fmt"
25 |
26 | "github.com/stader-labs/stader-node/shared/types/api"
27 | )
28 |
29 | // Deletes the data folder including the wallet file, password file, and all validator keys.
30 | // Don't use this unless you have a very good reason to do it (such as switching from Prater to Mainnet).
31 | func (c *Client) TerminateDataFolder() (api.TerminateDataFolderResponse, error) {
32 | responseBytes, err := c.callAPI("service terminate-data-folder")
33 | if err != nil {
34 | return api.TerminateDataFolderResponse{}, fmt.Errorf("Could not delete data folder: %w", err)
35 | }
36 | var response api.TerminateDataFolderResponse
37 | if err := json.Unmarshal(responseBytes, &response); err != nil {
38 | return api.TerminateDataFolderResponse{}, fmt.Errorf("Could not decode terminate-data-folder response: %w", err)
39 | }
40 | if response.Error != "" {
41 | return api.TerminateDataFolderResponse{}, fmt.Errorf("Could not delete data folder: %s", response.Error)
42 | }
43 | return response, nil
44 | }
45 |
46 | // Gets the status of the configured Execution and Beacon clients
47 | func (c *Client) GetClientStatus() (api.ClientStatusResponse, error) {
48 | responseBytes, err := c.callAPI("service get-client-status")
49 |
50 | if err != nil {
51 | return api.ClientStatusResponse{}, fmt.Errorf("Could not get client status: %w", err)
52 | }
53 | var response api.ClientStatusResponse
54 | if err := json.Unmarshal(responseBytes, &response); err != nil {
55 | return api.ClientStatusResponse{}, fmt.Errorf("Could not decode client status response: %w", err)
56 | }
57 | if response.Error != "" {
58 | return api.ClientStatusResponse{}, fmt.Errorf("Could not get client status: %s", response.Error)
59 | }
60 | return response, nil
61 | }
62 |
--------------------------------------------------------------------------------
/shared/services/wallet/keystore/keystore.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package keystore
21 |
22 | import (
23 | "github.com/sethvargo/go-password/password"
24 | eth2types "github.com/wealdtech/go-eth2-types/v2"
25 | )
26 |
27 | // Generates a random password
28 | func GenerateRandomPassword() (string, error) {
29 |
30 | // Generate a random 32-character password
31 | password, err := password.Generate(32, 6, 6, false, false)
32 | if err != nil {
33 | return "", err
34 | }
35 |
36 | return password, nil
37 | }
38 |
39 | // Validator keystore interface
40 | type Keystore interface {
41 | StoreValidatorKey(key *eth2types.BLSPrivateKey, derivationPath string) error
42 | GetKeystoreDir() string
43 | }
44 |
--------------------------------------------------------------------------------
/shared/types/api/api.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package api
21 |
22 | type APIResponse struct {
23 | Status string `json:"status"`
24 | Error string `json:"error"`
25 | }
26 |
--------------------------------------------------------------------------------
/shared/types/api/service.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package api
21 |
22 | import "github.com/ethereum/go-ethereum/common"
23 |
24 | type TerminateDataFolderResponse struct {
25 | Status string `json:"status"`
26 | Error string `json:"error"`
27 | FolderExisted bool `json:"folderExisted"`
28 | }
29 |
30 | type CreateFeeRecipientFileResponse struct {
31 | Status string `json:"status"`
32 | Error string `json:"error"`
33 | Distributor common.Address `json:"distributor"`
34 | }
35 |
36 | // This is a wrapper for the EC status report
37 | type ClientStatus struct {
38 | IsWorking bool `json:"isWorking"`
39 | IsSynced bool `json:"isSynced"`
40 | SyncProgress float64 `json:"syncProgress"`
41 | NetworkId uint `json:"networkId"`
42 | Error string `json:"error"`
43 | }
44 |
45 | // This is a wrapper for the manager's overall status report
46 | type ClientManagerStatus struct {
47 | PrimaryClientStatus ClientStatus `json:"primaryEcStatus"`
48 | FallbackEnabled bool `json:"fallbackEnabled"`
49 | FallbackClientStatus ClientStatus `json:"fallbackEcStatus"`
50 | }
51 |
52 | type ClientStatusResponse struct {
53 | Status string `json:"status"`
54 | Error string `json:"error"`
55 | EcManagerStatus ClientManagerStatus `json:"ecManagerStatus"`
56 | BcManagerStatus ClientManagerStatus `json:"bcManagerStatus"`
57 | }
58 |
--------------------------------------------------------------------------------
/shared/types/eth2/types.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package eth2
21 |
22 | // Deposit data (with no signature field)
23 | type DepositDataNoSignature struct {
24 | PublicKey []byte `json:"pubkey" ssz-size:"48"`
25 | WithdrawalCredentials []byte `json:"withdrawal_credentials" ssz-size:"32"`
26 | Amount uint64 `json:"amount"`
27 | }
28 |
29 | // Deposit data (including signature)
30 | type DepositData struct {
31 | PublicKey []byte `json:"pubkey" ssz-size:"48"`
32 | WithdrawalCredentials []byte `json:"withdrawal_credentials" ssz-size:"32"`
33 | Amount uint64 `json:"amount"`
34 | Signature []byte `json:"signature" ssz-size:"96"`
35 | }
36 |
37 | // BLS signing root with domain
38 | type SigningRoot struct {
39 | ObjectRoot []byte `json:"object_root" ssz-size:"32"`
40 | Domain []byte `json:"domain" ssz-size:"32"`
41 | }
42 |
43 | // Voluntary exit transaction
44 | type VoluntaryExit struct {
45 | Epoch uint64 `json:"epoch"`
46 | ValidatorIndex uint64 `json:"validator_index"`
47 | }
48 |
49 | // Withdrawal creds change message
50 | type WithdrawalCredentialsChange struct {
51 | ValidatorIndex uint64 `json:"validator_index"`
52 | FromBLSPubkey [48]byte `json:"from_bls_pubkey" ssz-size:"48"`
53 | ToExecutionAddress [20]byte `json:"to_execution_address" ssz-size:"20"`
54 | }
55 |
--------------------------------------------------------------------------------
/shared/types/stader-backend/merkle-proofs.go:
--------------------------------------------------------------------------------
1 | package stader_backend
2 |
3 | type CycleMerkleProofs struct {
4 | Root string `json:"root"`
5 | Eth string `json:"eth"`
6 | Sd string `json:"sd"`
7 | Proof []string `json:"proof"`
8 | Cycle int64 `json:"cycle"`
9 | }
10 |
--------------------------------------------------------------------------------
/shared/types/stader-backend/node-diversity.go:
--------------------------------------------------------------------------------
1 | package stader_backend
2 |
3 | type NodeDiversityRequest struct {
4 | Signature string `json:"signature"`
5 | Message *NodeDiversity `json:"message"`
6 | }
7 |
8 | type NodeDiversity struct {
9 | ExecutionClient string `json:"executionClient"`
10 | ConsensusClient string `json:"consensusClient"`
11 | ValidatorClient string `json:"validatorClient"`
12 | TotalNonTerminalKeys uint64 `json:"totalNonTerminalKeys"`
13 | NodeAddress string `json:"nodeAddress"`
14 | NodePublicKey string `json:"nodePublicKey"`
15 | Relays string `json:"relays"`
16 | }
17 |
18 | type NodeDiversityResponseType struct {
19 | Success bool `json:"success"`
20 | Error string `json:"error"`
21 | }
22 |
--------------------------------------------------------------------------------
/shared/types/stader-backend/pre-sign.go:
--------------------------------------------------------------------------------
1 | package stader_backend
2 |
3 | import "github.com/stader-labs/stader-node/stader-lib/types"
4 |
5 | type PreSignCheckApiRequestType struct {
6 | ValidatorPublicKey string `json:"validatorPublicKey"`
7 | }
8 |
9 | type PreSignCheckApiResponseType struct {
10 | Value bool `json:"value"`
11 | }
12 |
13 | type PreSignSendApiResponseType struct {
14 | Success bool `json:"success"`
15 | Error string `json:"error"`
16 | }
17 |
18 | type PreSignSendApiRequestType struct {
19 | Message struct {
20 | Epoch string `json:"epoch"`
21 | ValidatorIndex string `json:"validator_index"`
22 | } `json:"message"`
23 | Signature string `json:"signature"`
24 | ValidatorPublicKey string `json:"validatorPublicKey"`
25 | }
26 |
27 | type BulkPreSignSendApiRequestType = []PreSignSendApiRequestType
28 | type BulkPreSignSendApiResponseType = map[string]PreSignSendApiResponseType
29 |
30 | type BulkPreSignCheckApiRequestType struct {
31 | ValidatorPubKeys []types.ValidatorPubkey `json:"pubkeys"`
32 | }
33 |
34 | type BulkPreSignCheckApiResponseType = map[string]bool
35 |
36 | type PublicKeyApiResponse struct {
37 | Value string `json:"value"`
38 | }
39 |
--------------------------------------------------------------------------------
/shared/utils/api/response.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package api
21 |
22 | import (
23 | "encoding/json"
24 | "errors"
25 | "fmt"
26 | "reflect"
27 |
28 | "github.com/stader-labs/stader-node/shared/types/api"
29 | )
30 |
31 | // Print an API response
32 | // response must be a pointer to a struct type with Error and Status string fields
33 | func PrintResponse(response interface{}, responseError error) {
34 |
35 | // Check response type
36 | r := reflect.ValueOf(response)
37 | if !(r.Kind() == reflect.Ptr && r.Type().Elem().Kind() == reflect.Struct) {
38 | PrintErrorResponse(errors.New("Invalid API response"))
39 | return
40 | }
41 |
42 | // Create zero response value if nil
43 | if r.IsNil() {
44 | response = reflect.New(r.Type().Elem()).Interface()
45 | r = reflect.ValueOf(response)
46 | }
47 |
48 | // Get and check response fields
49 | sf := r.Elem().FieldByName("Status")
50 | ef := r.Elem().FieldByName("Error")
51 | if !(sf.IsValid() && sf.CanSet() && sf.Kind() == reflect.String && ef.IsValid() && ef.CanSet() && ef.Kind() == reflect.String) {
52 | PrintErrorResponse(errors.New("Invalid API response"))
53 | return
54 | }
55 |
56 | // Populate error
57 | if responseError != nil {
58 | ef.SetString(responseError.Error())
59 | }
60 |
61 | // Set status
62 | if ef.String() == "" {
63 | sf.SetString("success")
64 | } else {
65 | sf.SetString("error")
66 | }
67 |
68 | // Encode
69 | responseBytes, err := json.Marshal(response)
70 | if err != nil {
71 | PrintErrorResponse(fmt.Errorf("Could not encode API response: %w", err))
72 | return
73 | }
74 |
75 | // Print
76 | fmt.Println(string(responseBytes))
77 |
78 | }
79 |
80 | // Print an API error response
81 | func PrintErrorResponse(err error) {
82 | PrintResponse(&api.APIResponse{}, err)
83 | }
84 |
--------------------------------------------------------------------------------
/shared/utils/arr-utils/arr.go:
--------------------------------------------------------------------------------
1 | package arr_utils
2 |
3 | func ElementExistsInNumArray(arr []int64, element int64) bool {
4 | for _, v := range arr {
5 | if v == element {
6 | return true
7 | }
8 | }
9 | return false
10 | }
11 |
--------------------------------------------------------------------------------
/shared/utils/cli/prompt_unix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | /*
5 | This work is licensed and released under GNU GPL v3 or any other later versions.
6 | The full text of the license is below/ found at
7 |
8 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU General Public License for more details.
19 |
20 | You should have received a copy of the GNU General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | package cli
25 |
26 | import (
27 | "fmt"
28 | "regexp"
29 | "syscall"
30 |
31 | "golang.org/x/term"
32 | )
33 |
34 | // Prompt for password input
35 | func PromptPassword(initialPrompt string, expectedFormat string, incorrectFormatPrompt string) string {
36 |
37 | // Print initial prompt
38 | fmt.Println(initialPrompt)
39 |
40 | // Get valid user input
41 | var input string
42 | var init bool
43 | for !init || !regexp.MustCompile(expectedFormat).MatchString(input) {
44 |
45 | // Incorrect format
46 | if init {
47 | fmt.Println("")
48 | fmt.Println(incorrectFormatPrompt)
49 | } else {
50 | init = true
51 | }
52 |
53 | // Read password
54 | if bytes, err := term.ReadPassword(syscall.Stdin); err != nil {
55 | fmt.Println(fmt.Errorf("Could not read password: %w", err))
56 | } else {
57 | input = string(bytes)
58 | }
59 |
60 | }
61 | fmt.Println("")
62 |
63 | // Return user input
64 | return input
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/shared/utils/cli/prompt_windows.go:
--------------------------------------------------------------------------------
1 | //go:build windows
2 | // +build windows
3 |
4 | /*
5 | This work is licensed and released under GNU GPL v3 or any other later versions.
6 | The full text of the license is below/ found at
7 |
8 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU General Public License for more details.
19 |
20 | You should have received a copy of the GNU General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | package cli
25 |
26 | // Prompt for password input
27 | func PromptPassword(initialPrompt string, expectedFormat string, incorrectFormatPrompt string) string {
28 | return Prompt(initialPrompt, expectedFormat, incorrectFormatPrompt)
29 | }
30 |
--------------------------------------------------------------------------------
/shared/utils/crypto/base64.go:
--------------------------------------------------------------------------------
1 | package crypto
2 |
3 | import (
4 | "encoding/base64"
5 | )
6 |
7 | func DecodeBase64(data string) ([]byte, error) {
8 | res, err := base64.StdEncoding.DecodeString(data)
9 | if err != nil {
10 | return nil, err
11 | }
12 |
13 | return res, nil
14 | }
15 |
16 | func EncodeBase64(data []byte) string {
17 | return base64.StdEncoding.EncodeToString(data)
18 | }
19 |
--------------------------------------------------------------------------------
/shared/utils/crypto/rsa.go:
--------------------------------------------------------------------------------
1 | package crypto
2 |
3 | import (
4 | "crypto/rand"
5 | "crypto/rsa"
6 | "crypto/sha256"
7 | "crypto/x509"
8 | "encoding/pem"
9 | "fmt"
10 | )
11 |
12 | func BytesToPublicKey(pub []byte) (*rsa.PublicKey, error) {
13 | block, _ := pem.Decode(pub)
14 | if block == nil {
15 | return nil, fmt.Errorf("failed to parse PEM block containing the key")
16 | }
17 | b := block.Bytes
18 | var err error
19 |
20 | key, err := x509.ParsePKIXPublicKey(b)
21 | if err != nil {
22 | fmt.Printf("Error using x509.ParsePKIXPublicKey %v\n", err)
23 | return nil, err
24 | }
25 |
26 | return key.(*rsa.PublicKey), nil
27 | }
28 |
29 | func EncryptUsingPublicKey(data []byte, publicKey *rsa.PublicKey) ([]byte, error) {
30 | exitMsgEncrypted, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, data, nil)
31 | if err != nil {
32 | return nil, err
33 | }
34 |
35 | return exitMsgEncrypted, nil
36 | }
37 |
--------------------------------------------------------------------------------
/shared/utils/hex/hex.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package hex
21 |
22 | import (
23 | "github.com/ethereum/go-ethereum/common/hexutil"
24 | )
25 |
26 | // Add a prefix to a hex string if not present
27 | func AddPrefix(value string) string {
28 | if len(value) < 2 || value[0:2] != "0x" {
29 | return "0x" + value
30 | }
31 | return value
32 | }
33 |
34 | // Remove a prefix from a hex string if present
35 | func RemovePrefix(value string) string {
36 | if len(value) >= 2 && value[0:2] == "0x" {
37 | return value[2:]
38 | }
39 | return value
40 | }
41 |
42 | func Decode(value string) ([]byte, error) {
43 | return hexutil.Decode(value)
44 | }
45 |
--------------------------------------------------------------------------------
/shared/utils/log/colors.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package log
21 |
22 | const (
23 | ColorBlue string = "\033[36m"
24 | ColorReset string = "\033[0m"
25 | ColorRed string = "\033[31m"
26 | ColorGreen string = "\033[32m"
27 | ColorYellow string = "\033[33m"
28 | )
29 |
--------------------------------------------------------------------------------
/shared/utils/log/logger.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package log
21 |
22 | import (
23 | "log"
24 |
25 | "github.com/fatih/color"
26 | )
27 |
28 | // Logger with ANSI color output
29 | type ColorLogger struct {
30 | Color color.Attribute
31 | sprintFunc func(a ...interface{}) string
32 | sprintfFunc func(format string, a ...interface{}) string
33 | }
34 |
35 | // Create new color logger
36 | func NewColorLogger(colorAttr color.Attribute) ColorLogger {
37 | return ColorLogger{
38 | Color: colorAttr,
39 | sprintFunc: color.New(colorAttr).SprintFunc(),
40 | sprintfFunc: color.New(colorAttr).SprintfFunc(),
41 | }
42 | }
43 |
44 | // Print values
45 | func (l *ColorLogger) Print(v ...interface{}) {
46 | log.Print(l.sprintFunc(v...))
47 | }
48 |
49 | // Print values with a newline
50 | func (l *ColorLogger) Println(v ...interface{}) {
51 | log.Println(l.sprintFunc(v...))
52 | }
53 |
54 | // Print a formatted string
55 | func (l *ColorLogger) Printf(format string, v ...interface{}) {
56 | log.Print(l.sprintfFunc(format, v...))
57 | }
58 |
59 | // Print a formatted string with a newline
60 | func (l *ColorLogger) Printlnf(format string, v ...interface{}) {
61 | log.Println(l.sprintfFunc(format, v...))
62 | }
63 |
--------------------------------------------------------------------------------
/shared/utils/math/math.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package math
21 |
22 | import (
23 | "math"
24 | )
25 |
26 | // Round a float64 down to a number of places
27 | func RoundDown(val float64, places int) float64 {
28 | return math.Floor(val*math.Pow10(places)) / math.Pow10(places)
29 | }
30 |
31 | // Round a float64 up to a number of places
32 | func RoundUp(val float64, places int) float64 {
33 | return math.Ceil(val*math.Pow10(places)) / math.Pow10(places)
34 | }
35 |
--------------------------------------------------------------------------------
/shared/utils/net/http.go:
--------------------------------------------------------------------------------
1 | package net
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "net/http"
8 | "net/url"
9 | )
10 |
11 | func MakePostRequest(requestUrl string, requestBody interface{}) (*http.Response, error) {
12 | requestBodyBytes, err := json.Marshal(requestBody)
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | req, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(requestBodyBytes))
18 | if err != nil {
19 | return nil, err
20 | }
21 |
22 | req.Header.Set("Content-Type", "application/json")
23 |
24 | client := &http.Client{}
25 | resp, err := client.Do(req)
26 | if err != nil {
27 | return nil, err
28 | }
29 |
30 | return resp, nil
31 | }
32 |
33 | func MakeGetRequest(requestUrl string, queryParameters interface{}) (*http.Response, error) {
34 | queryValues := url.Values{}
35 | queryParamsJSON, err := json.Marshal(queryParameters)
36 | if err != nil {
37 | return nil, err
38 | }
39 |
40 | err = json.Unmarshal(queryParamsJSON, &queryValues)
41 | if err != nil {
42 | return nil, err
43 | }
44 |
45 | req, err := http.NewRequest("GET", fmt.Sprintf("%s?%s", requestUrl, queryValues.Encode()), nil)
46 | if err != nil {
47 | return nil, err
48 | }
49 |
50 | client := &http.Client{}
51 | resp, err := client.Do(req)
52 | if err != nil {
53 | return nil, err
54 | }
55 |
56 | return resp, nil
57 | }
58 |
--------------------------------------------------------------------------------
/shared/utils/net/net.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package net
21 |
22 | import (
23 | "fmt"
24 | "regexp"
25 | )
26 |
27 | // Add a default port to a host address
28 | func DefaultPort(host string, port string) string {
29 | if !regexp.MustCompile(":\\d+$").MatchString(host) {
30 | return fmt.Sprintf("%s:%s", host, port)
31 | }
32 | return host
33 | }
34 |
--------------------------------------------------------------------------------
/shared/utils/stader/merkle-proof-download.go:
--------------------------------------------------------------------------------
1 | package stader
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "github.com/ethereum/go-ethereum/common"
7 | "github.com/stader-labs/stader-node/shared/services"
8 | stader_backend "github.com/stader-labs/stader-node/shared/types/stader-backend"
9 | "github.com/stader-labs/stader-node/shared/utils/net"
10 | "github.com/urfave/cli"
11 | "net/http"
12 | )
13 |
14 | func GetAllMerkleProofsForOperator(c *cli.Context, operator common.Address) ([]*stader_backend.CycleMerkleProofs, error) {
15 | config, err := services.GetConfig(c)
16 | if err != nil {
17 | return nil, err
18 | }
19 |
20 | res, err := net.MakeGetRequest(fmt.Sprintf(config.StaderNode.GetMerkleProofApi(), operator.Hex()), struct{}{})
21 | if err != nil {
22 | return nil, err
23 | }
24 | defer res.Body.Close()
25 | if res.StatusCode == http.StatusBadRequest {
26 | return []*stader_backend.CycleMerkleProofs{}, nil
27 | }
28 | if res.StatusCode != http.StatusOK {
29 | return nil, fmt.Errorf("error while getting all merkle proofs for operator %s", operator.Hex())
30 | }
31 |
32 | var allMerkleProofs []*stader_backend.CycleMerkleProofs
33 | err = json.NewDecoder(res.Body).Decode(&allMerkleProofs)
34 | if err != nil {
35 | return nil, err
36 | }
37 | return allMerkleProofs, nil
38 | }
39 |
--------------------------------------------------------------------------------
/shared/utils/stader/node-diversity.go:
--------------------------------------------------------------------------------
1 | package stader
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 |
7 | "github.com/stader-labs/stader-node/shared/services"
8 | stader_backend "github.com/stader-labs/stader-node/shared/types/stader-backend"
9 | "github.com/stader-labs/stader-node/shared/utils/net"
10 | "github.com/urfave/cli"
11 | )
12 |
13 | func SendNodeDiversityResponseType(
14 | c *cli.Context,
15 | request *stader_backend.NodeDiversityRequest,
16 | ) (*stader_backend.NodeDiversityResponseType, error) {
17 | config, err := services.GetConfig(c)
18 | if err != nil {
19 | return nil, err
20 | }
21 |
22 | res, err := net.MakePostRequest(config.StaderNode.GetNodeDiversityApi(), request)
23 | if err != nil {
24 | return nil, fmt.Errorf("request to GetNodeDiversityApi %w", err)
25 | }
26 | defer res.Body.Close()
27 |
28 | var resp stader_backend.NodeDiversityResponseType
29 | err = json.NewDecoder(res.Body).Decode(&resp)
30 |
31 | if err != nil {
32 | return nil, fmt.Errorf("decode NodeDiversityResponseType %w", err)
33 | }
34 |
35 | return &resp, nil
36 | }
37 |
--------------------------------------------------------------------------------
/shared/utils/stdr/fee-recipient.go:
--------------------------------------------------------------------------------
1 | package stdr
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
5 | "github.com/ethereum/go-ethereum/common"
6 | "github.com/stader-labs/stader-node/stader-lib/node"
7 | "github.com/stader-labs/stader-node/stader-lib/stader"
8 | stader_config "github.com/stader-labs/stader-node/stader-lib/stader-config"
9 | )
10 |
11 | type FeeRecipientInfo struct {
12 | SocializingPoolAddress common.Address `json:"socializingPoolAddress"`
13 | FeeDistributorAddress common.Address `json:"feeDistributorAddress"`
14 | IsInSocializingPool bool `json:"isInSocializingPool"`
15 | }
16 |
17 | func GetFeeRecipientInfo(prn *stader.PermissionlessNodeRegistryContractManager, vf *stader.VaultFactoryContractManager, sdcfg *stader.StaderConfigContractManager, nodeAddress common.Address, opts *bind.CallOpts) (*FeeRecipientInfo, error) {
18 | feeRecipientInfo := FeeRecipientInfo{
19 | SocializingPoolAddress: common.Address{},
20 | FeeDistributorAddress: common.Address{},
21 | IsInSocializingPool: false,
22 | }
23 |
24 | operatorId, err := node.GetOperatorId(prn, nodeAddress, opts)
25 | if err != nil {
26 | return nil, err
27 | }
28 | operatorInfo, err := node.GetOperatorInfo(prn, operatorId, opts)
29 | if err != nil {
30 | return nil, err
31 | }
32 |
33 | if operatorInfo.OptedForSocializingPool {
34 | feeRecipientInfo.IsInSocializingPool = true
35 | socializingPoolAddress, err := stader_config.GetSocializingPoolContractAddress(sdcfg, nil)
36 | if err != nil {
37 | return nil, err
38 | }
39 | feeRecipientInfo.SocializingPoolAddress = socializingPoolAddress
40 | } else {
41 | nodeElRewardAddress, err := node.GetNodeElRewardAddress(prn, 1, operatorId, opts)
42 | if err != nil {
43 | return nil, err
44 | }
45 | feeRecipientInfo.FeeDistributorAddress = nodeElRewardAddress
46 | }
47 |
48 | return &feeRecipientInfo, nil
49 | }
50 |
--------------------------------------------------------------------------------
/shared/utils/string-utils/str-convs.go:
--------------------------------------------------------------------------------
1 | package string_utils
2 |
3 | import (
4 | "fmt"
5 | "math/big"
6 | "strings"
7 | )
8 |
9 | func StringifyArray(arr []*big.Int) string {
10 | var strArr []string
11 | for _, v := range arr {
12 | strArr = append(strArr, v.String())
13 | }
14 | return strings.Join(strArr, ",")
15 | }
16 |
17 | // write a method given a comma seperated value of string numbers, get the big Ints back
18 | func DestringifyArray(arr string) ([]*big.Int, error) {
19 | var intArr []*big.Int
20 | for _, v := range strings.Split(arr, ",") {
21 | i, ok := new(big.Int).SetString(v, 10)
22 | if !ok {
23 | return nil, fmt.Errorf("could not parse string to big int: %s", v)
24 | }
25 | intArr = append(intArr, i)
26 | }
27 | return intArr, nil
28 | }
29 |
--------------------------------------------------------------------------------
/shared/utils/sys/cpu-flags.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package sys
21 |
22 | import (
23 | "runtime"
24 | "sort"
25 |
26 | "github.com/klauspost/cpuid/v2"
27 | )
28 |
29 | // Returns the CPU features that are required to run "modern" images but are not present on the node's CPU
30 | func GetMissingModernCpuFeatures() []string {
31 | var features map[cpuid.FeatureID]string
32 | switch runtime.GOARCH {
33 | case "amd64":
34 | features = map[cpuid.FeatureID]string{
35 | cpuid.ADX: "adx",
36 | //cpuid.AESNI: "aes",
37 | cpuid.AVX: "avx",
38 | cpuid.AVX2: "avx2",
39 | cpuid.BMI1: "bmi1",
40 | cpuid.BMI2: "bmi2",
41 | cpuid.CLMUL: "clmul",
42 | cpuid.MMX: "mmx",
43 | cpuid.SSE: "sse",
44 | cpuid.SSE2: "sse2",
45 | cpuid.SSSE3: "ssse3",
46 | cpuid.SSE4: "sse4.1",
47 | cpuid.SSE42: "sse4.2",
48 | }
49 | default:
50 | features = map[cpuid.FeatureID]string{}
51 | }
52 |
53 | unsupportedFeatures := []string{}
54 | for feature, name := range features {
55 | if !cpuid.CPU.Supports(feature) {
56 | unsupportedFeatures = append(unsupportedFeatures, name)
57 | }
58 | }
59 |
60 | sort.Strings(unsupportedFeatures)
61 | return unsupportedFeatures
62 | }
63 |
--------------------------------------------------------------------------------
/shared/utils/term/term_unix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | /*
5 | This work is licensed and released under GNU GPL v3 or any other later versions.
6 | The full text of the license is below/ found at
7 |
8 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU General Public License for more details.
19 |
20 | You should have received a copy of the GNU General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | package term
25 |
26 | import (
27 | "os"
28 | "os/exec"
29 | )
30 |
31 | // Clear terminal output
32 | func Clear() error {
33 | cmd := exec.Command("clear")
34 | cmd.Stdout = os.Stdout
35 | return cmd.Run()
36 | }
37 |
--------------------------------------------------------------------------------
/shared/utils/term/term_windows.go:
--------------------------------------------------------------------------------
1 | //go:build windows
2 | // +build windows
3 |
4 | /*
5 | This work is licensed and released under GNU GPL v3 or any other later versions.
6 | The full text of the license is below/ found at
7 |
8 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU General Public License for more details.
19 |
20 | You should have received a copy of the GNU General Public License
21 | along with this program. If not, see .
22 | */
23 |
24 | package term
25 |
26 | import (
27 | "os"
28 | "os/exec"
29 | )
30 |
31 | // Clear terminal output
32 | func Clear() error {
33 | cmd := exec.Command("cmd", "/c", "cls")
34 | cmd.Stdout = os.Stdout
35 | return cmd.Run()
36 | }
37 |
--------------------------------------------------------------------------------
/shared/utils/validator/bls.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package validator
21 |
22 | // BLS signing root with domain
23 | type signingRoot struct {
24 | ObjectRoot []byte `ssz-size:"32"`
25 | Domain []byte `ssz-size:"32"`
26 | }
27 |
--------------------------------------------------------------------------------
/shared/utils/validator/deposit-data.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package validator
21 |
22 | import (
23 | "github.com/ethereum/go-ethereum/common"
24 | "github.com/stader-labs/stader-node/shared/types/eth2"
25 | eth2types "github.com/wealdtech/go-eth2-types/v2"
26 |
27 | "github.com/stader-labs/stader-node/shared/services/beacon"
28 | )
29 |
30 | // Get deposit data & root for a given validator key and withdrawal credentials
31 | func GetDepositData(validatorKey *eth2types.BLSPrivateKey, withdrawalCredentials common.Hash, eth2Config beacon.Eth2Config, amount uint64) (eth2.DepositData, common.Hash, error) {
32 | // Build deposit data
33 | dd := eth2.DepositDataNoSignature{
34 | PublicKey: validatorKey.PublicKey().Marshal(),
35 | WithdrawalCredentials: withdrawalCredentials[:],
36 | Amount: amount,
37 | }
38 |
39 | // Get signing root
40 | or, err := dd.HashTreeRoot()
41 | if err != nil {
42 | return eth2.DepositData{}, common.Hash{}, err
43 | }
44 |
45 | sr := eth2.SigningRoot{
46 | ObjectRoot: or[:],
47 | Domain: eth2types.Domain(eth2types.DomainDeposit, eth2Config.GenesisForkVersion, eth2types.ZeroGenesisValidatorsRoot),
48 | }
49 |
50 | // Get signing root with domain
51 | srHash, err := sr.HashTreeRoot()
52 | if err != nil {
53 | return eth2.DepositData{}, common.Hash{}, err
54 | }
55 |
56 | // Build deposit data struct (with signature)
57 | var depositData = eth2.DepositData{
58 | PublicKey: dd.PublicKey,
59 | WithdrawalCredentials: dd.WithdrawalCredentials,
60 | Amount: dd.Amount,
61 | Signature: validatorKey.Sign(srHash[:]).Marshal(),
62 | }
63 |
64 | // Get deposit data root
65 | depositDataRoot, err := depositData.HashTreeRoot()
66 | if err != nil {
67 | return eth2.DepositData{}, common.Hash{}, err
68 | }
69 |
70 | // Return
71 | return depositData, depositDataRoot, nil
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/shared/utils/validator/voluntary-exit.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package validator
21 |
22 | import (
23 | "github.com/stader-labs/stader-node/shared/types/eth2"
24 | "github.com/stader-labs/stader-node/stader-lib/types"
25 | eth2types "github.com/wealdtech/go-eth2-types/v2"
26 | )
27 |
28 | // Get a voluntary exit message signature for a given validator key and index
29 | func GetSignedExitMessage(validatorKey *eth2types.BLSPrivateKey, validatorIndex uint64, epoch uint64, signatureDomain []byte) (types.ValidatorSignature, [32]byte, error) {
30 |
31 | // Build voluntary exit message
32 | exitMessage := eth2.VoluntaryExit{
33 | Epoch: epoch,
34 | ValidatorIndex: validatorIndex,
35 | }
36 |
37 | // Get object root
38 | or, err := exitMessage.HashTreeRoot()
39 | if err != nil {
40 | return types.ValidatorSignature{}, [32]byte{}, err
41 | }
42 |
43 | // Get signing root
44 | sr := eth2.SigningRoot{
45 | ObjectRoot: or[:],
46 | Domain: signatureDomain,
47 | }
48 |
49 | srHash, err := sr.HashTreeRoot()
50 | if err != nil {
51 | return types.ValidatorSignature{}, [32]byte{}, err
52 | }
53 |
54 | // Sign message
55 | signature := validatorKey.Sign(srHash[:]).Marshal()
56 |
57 | // Return
58 | return types.BytesToValidatorSignature(signature), srHash, nil
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/shared/utils/wallet/recover-keys.go:
--------------------------------------------------------------------------------
1 | package wallet
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/ethereum/go-ethereum/common"
7 | "github.com/stader-labs/stader-node/shared/services/wallet"
8 | "github.com/stader-labs/stader-node/shared/utils/stdr"
9 | "github.com/stader-labs/stader-node/stader-lib/node"
10 | "github.com/stader-labs/stader-node/stader-lib/stader"
11 | "github.com/stader-labs/stader-node/stader-lib/types"
12 | )
13 |
14 | const (
15 | pageSize uint = 20
16 | pageLimit uint = 2000
17 | )
18 |
19 | func RecoverStaderKeys(pnr *stader.PermissionlessNodeRegistryContractManager, address common.Address, w *wallet.Wallet, testOnly bool) ([]types.ValidatorPubkey, error) {
20 | recoveredKeys := []types.ValidatorPubkey{}
21 | operatorId, err := node.GetOperatorId(pnr, address, nil)
22 | if err != nil {
23 | return nil, err
24 | }
25 | // Get node's validating pubkeys
26 | allOperatorValidators, _, err := stdr.GetAllValidatorsRegisteredWithOperator(pnr, operatorId, address, nil)
27 | if err != nil {
28 | return nil, err
29 | }
30 |
31 | // Recover conventionally generated keys
32 | pageStart := uint(0)
33 | for {
34 | if pageStart >= pageLimit {
35 | return nil, fmt.Errorf("attempt limit exceeded (%d keys)", pageLimit)
36 | }
37 | pageEnd := pageStart + pageSize
38 | if pageEnd > pageLimit {
39 | pageEnd = pageLimit
40 | }
41 |
42 | // Get the keys for this bucket
43 | keys, err := w.GetValidatorKeys(pageStart, pageEnd-pageStart)
44 | if err != nil {
45 | return nil, err
46 | }
47 | for _, validatorKey := range keys {
48 | _, exists := allOperatorValidators[validatorKey.PublicKey]
49 | if exists {
50 | // Found one!
51 | delete(allOperatorValidators, validatorKey.PublicKey)
52 | if !testOnly {
53 | err := w.SaveValidatorKey(validatorKey)
54 | if err != nil {
55 | return nil, fmt.Errorf("error recovering validator keys: %w", err)
56 | }
57 | recoveredKeys = append(recoveredKeys, validatorKey.PublicKey)
58 | }
59 | }
60 | }
61 |
62 | if len(allOperatorValidators) == 0 {
63 | // All keys recovered!
64 | break
65 | }
66 |
67 | // Run another iteration with the next bucket
68 | pageStart = pageEnd
69 | }
70 |
71 | return recoveredKeys, nil
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/shared/version.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without eve n the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package shared
21 |
22 | const BinaryBucket string = "/stader-node-build/permissionless"
23 | const DockerAccount string = "staderlabs"
24 | const StaderVersion string = "1.6.5"
25 |
26 | const Logo string = `
27 | _____ _ _ _ _
28 | / ____| | | | | | | |
29 | | (___ | |_ __ _ __| | ___ _ __ | | __ _| |__ ___
30 | \___ \| __/ _' |/ _' |/ _ \ '__| | | / _' | '_ \/ __|
31 | ____) | || (_| | (_| | __/ | | |___| (_| | |_) \__ \
32 | |_____/ \__\__,_|\__,_|\___|_| |______\__,_|_.__/|___/`
33 |
--------------------------------------------------------------------------------
/sszgen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | # Generates the ssz encoding methods for eth2 types with fastssz
22 | # Install sszgen with `go get github.com/ferranbt/fastssz/sszgen`
23 | rm -f ./shared/types/eth2/types_encoding.go
24 | sszgen --path ./shared/types/eth2
--------------------------------------------------------------------------------
/stader-cli/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | export CGO_ENABLED=0
22 | cd /stader-node/stader-cli
23 |
24 | # Build x64 version
25 | GOOS=linux GOARCH=amd64 go build -o stader-cli-linux-amd64 stader-cli.go
26 | GOOS=darwin GOARCH=amd64 go build -o stader-cli-darwin-amd64 stader-cli.go
27 |
28 | # Build the arm64 version
29 | GOOS=linux GOARCH=arm64 go build -o stader-cli-linux-arm64 stader-cli.go
30 | GOOS=darwin GOARCH=arm64 go build -o stader-cli-darwin-arm64 stader-cli.go
31 |
--------------------------------------------------------------------------------
/stader-cli/node/download-sp-merkle-proofs.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "fmt"
5 | "github.com/stader-labs/stader-node/shared/services/stader"
6 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
7 | "github.com/urfave/cli"
8 | )
9 |
10 | func downloadSPMerkleProofs(c *cli.Context) error {
11 |
12 | staderClient, err := stader.NewClientFromCtx(c)
13 | if err != nil {
14 | return err
15 | }
16 | defer staderClient.Close()
17 |
18 | // Check and assign the EC status
19 | err = cliutils.CheckClientStatus(staderClient)
20 | if err != nil {
21 | return err
22 | }
23 |
24 | canDownloadSpMerkleProofs, err := staderClient.CanDownloadSpMerkleProofs()
25 | if err != nil {
26 | return err
27 | }
28 | if canDownloadSpMerkleProofs.NoMissingCycles {
29 | fmt.Println("There are no missing cycles to download! All proofs are up to date!")
30 | return nil
31 | }
32 |
33 | fmt.Printf("Following cycles are missing: %v\n", canDownloadSpMerkleProofs.MissingCycles)
34 |
35 | // Prompt for confirmation
36 | if !(c.Bool("yes") || cliutils.Confirm(fmt.Sprintf(
37 | "Are you sure you want to download the missing merkle proofs?"))) {
38 | fmt.Println("Cancelled.")
39 | return nil
40 | }
41 |
42 | fmt.Println("Downloading missing merkle proofs.....")
43 |
44 | res, err := staderClient.DownloadSpMerkleProofs()
45 | if err != nil {
46 | return err
47 | }
48 |
49 | fmt.Printf("Successfully downloaded the merkle proofs for cycles: %v\n", res.DownloadedCycles)
50 |
51 | return nil
52 | }
53 |
--------------------------------------------------------------------------------
/stader-cli/node/get-contracts-info.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/stader-labs/stader-node/shared/services/stader"
7 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
8 | "github.com/stader-labs/stader-node/shared/utils/log"
9 | "github.com/urfave/cli"
10 | )
11 |
12 | func getContractsInfo(c *cli.Context) error {
13 | staderClient, err := stader.NewClientFromCtx(c)
14 | if err != nil {
15 | return err
16 | }
17 | defer staderClient.Close()
18 |
19 | // Check and assign the EC status
20 | err = cliutils.CheckClientStatus(staderClient)
21 | if err != nil {
22 | return err
23 | }
24 |
25 | // Get node fee
26 | response, err := staderClient.GetContractsInfo()
27 | if err != nil {
28 | return err
29 | }
30 |
31 | fmt.Printf("%s=== Beacon Network Contract Details ===%s\n", log.ColorGreen, log.ColorReset)
32 | fmt.Printf("Beacon Network: %d\n\n", response.BeaconNetwork)
33 | fmt.Printf("Beacon Deposit Contract: %s\n\n", response.BeaconDepositContract)
34 |
35 | fmt.Printf("%s=== Stader Network Contract Details ===%s\n", log.ColorGreen, log.ColorReset)
36 | fmt.Printf("Network: %d\n\n", response.Network)
37 | fmt.Printf("Stader Config: %s\n\n", response.StaderConfig)
38 | fmt.Printf("Permissionless Node Registry: %s\n\n", response.PermissionlessNodeRegistry)
39 | fmt.Printf("Vault Factory: %s\n\n", response.VaultFactory)
40 | fmt.Printf("Sd Collateral Lock: %s\n\n", response.SdCollateralContract)
41 | fmt.Printf("EthX Token: %s\n\n", response.EthxToken)
42 | fmt.Printf("Sd Token: %s\n\n", response.SdToken)
43 | fmt.Printf("Socializing Pool: %s\n\n", response.SocializingPoolContract)
44 | fmt.Printf("Permissionless Pool: %s\n\n", response.PermisionlessPool)
45 | fmt.Printf("Stader Oracle: %s\n\n", response.StaderOracle)
46 | fmt.Printf("Sd Utility Pool: %s\n\n", response.SdUtilityContract)
47 | fmt.Printf("Pre-sign encryption key is %s\n\n", response.EncryptionKey)
48 |
49 | return nil
50 | }
51 |
--------------------------------------------------------------------------------
/stader-cli/node/send-el-rewards.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/stader-labs/stader-node/shared/services/gas"
7 | "github.com/stader-labs/stader-node/shared/services/stader"
8 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
9 | "github.com/stader-labs/stader-node/stader-lib/utils/eth"
10 | "github.com/urfave/cli"
11 | )
12 |
13 | func SendElRewards(c *cli.Context) error {
14 | staderClient, err := stader.NewClientFromCtx(c)
15 | if err != nil {
16 | return err
17 | }
18 | defer staderClient.Close()
19 |
20 | // Check and assign the EC status
21 | err = cliutils.CheckClientStatus(staderClient)
22 | if err != nil {
23 | return err
24 | }
25 |
26 | // Print what network we're on
27 | err = cliutils.PrintNetwork(staderClient)
28 |
29 | // Check if we can Withdraw El Rewards
30 | canClaimElRewardsResponse, err := staderClient.CanSendElRewards()
31 | if err != nil {
32 | return err
33 | }
34 | if canClaimElRewardsResponse.NoElRewards {
35 | fmt.Printf("No El Rewards to withdraw\n")
36 | return nil
37 | }
38 |
39 | err = gas.AssignMaxFeeAndLimit(canClaimElRewardsResponse.GasInfo, staderClient, c.Bool("yes"))
40 | if err != nil {
41 | return err
42 | }
43 |
44 | // Prompt for confirmation
45 | if !(c.Bool("yes") || cliutils.Confirm(fmt.Sprintf(
46 | "Are you sure you want to send El Rewards to claim vault?"))) {
47 | fmt.Println("Cancelled.")
48 | return nil
49 | }
50 |
51 | res, err := staderClient.SendElRewards()
52 | if err != nil {
53 | return err
54 | }
55 |
56 | fmt.Printf("Sending %s EL Rewards to Claim Vault\n\n", eth.DisplayAmountInUnits(res.ElRewardsAmount, "eth"))
57 | cliutils.PrintTransactionHash(staderClient, res.TxHash)
58 |
59 | if _, err = staderClient.WaitForTransaction(res.TxHash); err != nil {
60 | return err
61 | }
62 |
63 | // Log & return
64 | fmt.Printf("Sent %s EL Rewards to Claim Vault\n\n", eth.DisplayAmountInUnits(res.ElRewardsAmount, "eth"))
65 | return nil
66 | }
67 |
--------------------------------------------------------------------------------
/stader-cli/node/sign-message.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package node
21 |
22 | import (
23 | "fmt"
24 |
25 | "encoding/json"
26 |
27 | "github.com/ethereum/go-ethereum/common"
28 | "github.com/urfave/cli"
29 |
30 | "github.com/stader-labs/stader-node/shared/services/stader"
31 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
32 | )
33 |
34 | const signatureVersion = 1
35 |
36 | type PersonalSignature struct {
37 | Address common.Address `json:"address"`
38 | Message string `json:"msg"`
39 | Signature string `json:"sig"`
40 | Version string `json:"version"` // beaconcha.in expects a string
41 | }
42 |
43 | func signMessage(c *cli.Context) error {
44 |
45 | staderClient, err := stader.NewClientFromCtx(c)
46 | if err != nil {
47 | return err
48 | }
49 | defer staderClient.Close()
50 |
51 | // Get & check wallet status
52 | status, err := staderClient.WalletStatus()
53 | if err != nil {
54 | return err
55 | }
56 |
57 | if !status.WalletInitialized {
58 | fmt.Println("The node wallet is not initialized.")
59 | return nil
60 | }
61 |
62 | message := c.String("message")
63 | for message == "" {
64 | message = cliutils.Prompt("Please enter the message you want to sign: (EIP-191 personal_sign)", "^.+$", "Please enter the message you want to sign: (EIP-191 personal_sign)")
65 | }
66 |
67 | response, err := staderClient.SignMessage(message)
68 | if err != nil {
69 | return err
70 | }
71 |
72 | // Print the signature
73 | formattedSignature := PersonalSignature{
74 | Address: status.AccountAddress,
75 | Message: message,
76 | Signature: response.SignedData,
77 | Version: fmt.Sprint(signatureVersion),
78 | }
79 | bytes, err := json.MarshalIndent(formattedSignature, "", " ")
80 | if err != nil {
81 | return err
82 | }
83 |
84 | fmt.Printf("Signed Error:\n\n%s\n", string(bytes))
85 |
86 | return nil
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/stader-cli/node/update-operator-name.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "fmt"
5 | "github.com/stader-labs/stader-node/shared/services/gas"
6 | "github.com/stader-labs/stader-node/shared/services/stader"
7 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
8 | "github.com/urfave/cli"
9 | )
10 |
11 | func updateOperatorName(c *cli.Context, operatorName string) error {
12 |
13 | staderClient, err := stader.NewClientFromCtx(c)
14 | if err != nil {
15 | return err
16 | }
17 | defer staderClient.Close()
18 |
19 | // check if we can update the el
20 | res, err := staderClient.CanUpdateOperatorName(operatorName)
21 | if err != nil {
22 | return err
23 | }
24 | if res.OperatorNotActive {
25 | fmt.Println("Operator not active")
26 | return nil
27 | }
28 | if res.OperatorNameTooLong {
29 | fmt.Println("Operator name too long")
30 | return nil
31 | }
32 | if res.NothingToUpdate {
33 | fmt.Println("Nothing to update")
34 | return nil
35 | }
36 | if res.IsPermissionlessNodeRegistryPaused {
37 | fmt.Println("Permissionless Node Registry is paused.")
38 | return nil
39 | }
40 |
41 | err = gas.AssignMaxFeeAndLimit(res.GasInfo, staderClient, c.Bool("yes"))
42 | if err != nil {
43 | return err
44 | }
45 |
46 | if !(c.Bool("yes") || cliutils.Confirm(fmt.Sprintf(
47 | "Are you sure you want to update your operator name?"))) {
48 | fmt.Println("Cancelled.")
49 | return nil
50 | }
51 |
52 | // update the socializing pool el
53 | response, err := staderClient.UpdateOperatorName(operatorName)
54 | if err != nil {
55 | return err
56 | }
57 |
58 | fmt.Println("Updating operator name...")
59 |
60 | cliutils.PrintTransactionHash(staderClient, response.TxHash)
61 | _, err = staderClient.WaitForTransaction(response.TxHash)
62 | if err != nil {
63 | return err
64 | }
65 |
66 | fmt.Println("Operator name updated!")
67 |
68 | return nil
69 | }
70 |
--------------------------------------------------------------------------------
/stader-cli/service/configFallback.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package service
21 |
22 | import (
23 | stdCf "github.com/stader-labs/stader-node/shared/services/config"
24 | "github.com/stader-labs/stader-node/shared/types/config"
25 | )
26 |
27 | func setUIFallbackClient(cfg *stdCf.StaderConfig, newSettings map[string]interface{}) error {
28 | newSettings[keys.Fc_use_fallback_clients] = cfg.UseFallbackClients.Value.(bool)
29 | newSettings[keys.Fc_true_reconnect_delay] = cfg.ReconnectDelay.Value
30 |
31 | selectedCC, _ := cfg.GetSelectedConsensusClientConfig()
32 | switch selectedCC.GetName() {
33 | case string(config.ConsensusClient_Prysm):
34 | newSettings[keys.Fc_true_execution_client_url] = cfg.FallbackPrysm.EcHttpUrl.Value
35 | newSettings[keys.Fc_true_beacon_node_url] = cfg.FallbackPrysm.CcHttpUrl.Value
36 | default:
37 | newSettings[keys.Fc_true_execution_client_url] = cfg.FallbackNormal.EcHttpUrl.Value
38 | newSettings[keys.Fc_true_beacon_node_url] = cfg.FallbackNormal.CcHttpUrl.Value
39 | }
40 |
41 | newSettings[keys.Fc_true_beacon_node_json_rpc_url] = cfg.FallbackPrysm.JsonRpcUrl.Value
42 | return nil
43 | }
44 |
45 | func updateFallbackClient(cfg *stdCf.StaderConfig, newSettings map[string]interface{}) error {
46 | cfg.UseFallbackClients.Value = newSettings[keys.Fc_use_fallback_clients]
47 |
48 | if cfg.UseFallbackClients.Value.(bool) {
49 | cfg.ReconnectDelay.Value = newSettings[keys.Fc_true_reconnect_delay]
50 | cfg.FallbackNormal.EcHttpUrl.Value = newSettings[keys.Fc_true_execution_client_url]
51 | cfg.FallbackNormal.CcHttpUrl.Value = newSettings[keys.Fc_true_beacon_node_url]
52 |
53 | cfg.FallbackPrysm.EcHttpUrl.Value = newSettings[keys.Fc_true_execution_client_url]
54 | cfg.FallbackPrysm.CcHttpUrl.Value = newSettings[keys.Fc_true_beacon_node_url]
55 | cfg.FallbackPrysm.JsonRpcUrl.Value = newSettings[keys.Fc_true_beacon_node_json_rpc_url]
56 | }
57 | return nil
58 | }
59 |
--------------------------------------------------------------------------------
/stader-cli/service/guardian.tmpl:
--------------------------------------------------------------------------------
1 | # This work is licensed and released under GNU GPL v3 or any other later versions.
2 | # The full text of the license is below/ found at
3 |
4 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
5 |
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | # Autogenerated - DO NOT MODIFY THIS FILE DIRECTLY
20 | # If you want to overwrite some of these values with your own customizations,
21 | # please add them to `override/guardian.yml`.
22 | #
23 | # See https://docs.docker.com/compose/extends/#adding-and-overriding-configuration
24 | # for more information on overriding specific parameters of docker-compose files.
25 |
26 | version: "3.7"
27 | services:
28 | guardian:
29 | image: ${STADER_NODE_IMAGE}
30 | container_name: ${COMPOSE_PROJECT_NAME}_guardian
31 | restart: unless-stopped
32 | ports: [${GUARDIAN_OPEN_PORTS}]
33 | volumes:
34 | - ${STADER_FOLDER}:/.stader
35 | - ${STADER_DATA_FOLDER}:/.stader/data
36 | networks:
37 | - net
38 | command: "-m 0.0.0.0 -r ${NODE_METRICS_PORT:-9104} guardian"
39 | cap_drop:
40 | - all
41 | cap_add:
42 | - dac_override
43 | security_opt:
44 | - no-new-privileges
45 | networks:
46 | net:
--------------------------------------------------------------------------------
/stader-cli/validator/exit-validator.go:
--------------------------------------------------------------------------------
1 | package validator
2 |
3 | import (
4 | "fmt"
5 | "github.com/stader-labs/stader-node/shared/services/stader"
6 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
7 | "github.com/stader-labs/stader-node/stader-lib/types"
8 | "github.com/urfave/cli"
9 | )
10 |
11 | func ExitValidator(c *cli.Context, validatorPubKey types.ValidatorPubkey) error {
12 | staderClient, err := stader.NewClientFromCtx(c)
13 | if err != nil {
14 | return err
15 | }
16 | defer staderClient.Close()
17 |
18 | // Check and assign the EC status
19 | err = cliutils.CheckClientStatus(staderClient)
20 | if err != nil {
21 | return err
22 | }
23 |
24 | // check canExit
25 | response, err := staderClient.CanExitValidator(validatorPubKey)
26 | if err != nil {
27 | return err
28 | }
29 | if response.ValidatorNotRegistered {
30 | fmt.Println("Validator not registered!")
31 | return nil
32 | }
33 | if response.ValidatorTooYoung {
34 | fmt.Println("Validator too young!")
35 | return nil
36 | }
37 | if response.ValidatorExiting {
38 | fmt.Println("Validator already exiting!")
39 | return nil
40 | }
41 | if response.ValidatorNotActive {
42 | fmt.Println("Validator not active!")
43 | return nil
44 | }
45 |
46 | // Prompt for confirmation
47 | if !(c.Bool("yes") || cliutils.Confirm(fmt.Sprintf(
48 | "Are you sure you want to exit validator %s?", validatorPubKey))) {
49 | fmt.Println("Cancelled.")
50 | return nil
51 | }
52 |
53 | // now exit
54 | exitResponse, err := staderClient.ExitValidator(validatorPubKey)
55 | if err != nil {
56 | return err
57 | }
58 |
59 | fmt.Printf("Exiting validator %s, you check check the validator status at %s\n", validatorPubKey, fmt.Sprintf("%s/validator/%s#withdrawals", exitResponse.BeaconChainUrl, validatorPubKey))
60 |
61 | return nil
62 | }
63 |
--------------------------------------------------------------------------------
/stader-cli/validator/send-cl-rewards.go:
--------------------------------------------------------------------------------
1 | package validator
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/stader-labs/stader-node/shared/services/gas"
7 |
8 | "github.com/stader-labs/stader-node/shared/services/stader"
9 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
10 | "github.com/stader-labs/stader-node/stader-lib/types"
11 | "github.com/stader-labs/stader-node/stader-lib/utils/eth"
12 | "github.com/urfave/cli"
13 | )
14 |
15 | func SendClRewards(c *cli.Context, validatorPubKey types.ValidatorPubkey) error {
16 | staderClient, err := stader.NewClientFromCtx(c)
17 | if err != nil {
18 | return err
19 | }
20 | defer staderClient.Close()
21 |
22 | // Check and assign the EC status
23 | err = cliutils.CheckClientStatus(staderClient)
24 | if err != nil {
25 | return err
26 | }
27 |
28 | // Print what network we're on
29 | err = cliutils.PrintNetwork(staderClient)
30 |
31 | canClaimClRewardsResponse, err := staderClient.CanSendClRewards(validatorPubKey)
32 | if err != nil {
33 | return err
34 | }
35 | if canClaimClRewardsResponse.NoClRewards {
36 | fmt.Printf("No CL rewards to withdraw for validator %s\n", validatorPubKey.String())
37 | return nil
38 | }
39 | if canClaimClRewardsResponse.TooManyClRewards {
40 | fmt.Printf("Too many CL rewards to withdraw for validator %s.\n", validatorPubKey.String())
41 | fmt.Printf("If you have exited the validator, Please wait for Stader Oracles to settle your funds!\n")
42 | fmt.Printf("If you have not exited the validator, Please reach out to the Stader Team on discord!\n")
43 | return nil
44 | }
45 | if canClaimClRewardsResponse.ValidatorNotFound {
46 | fmt.Printf("Validator %s not found\n", validatorPubKey.String())
47 | return nil
48 | }
49 | if canClaimClRewardsResponse.VaultAlreadySettled {
50 | fmt.Printf("Vault for validator %s has already been settled\n", validatorPubKey.String())
51 | return nil
52 | }
53 |
54 | err = gas.AssignMaxFeeAndLimit(canClaimClRewardsResponse.GasInfo, staderClient, c.Bool("yes"))
55 | if err != nil {
56 | return err
57 | }
58 |
59 | // Prompt for confirmation
60 | if !(c.Bool("yes") || cliutils.Confirm(fmt.Sprintf(
61 | "Are you sure you want to send CL rewards for validator %s to claim vault?", validatorPubKey))) {
62 | fmt.Println("Cancelled.")
63 | return nil
64 | }
65 |
66 | res, err := staderClient.SendClRewards(validatorPubKey)
67 | if err != nil {
68 | return err
69 | }
70 |
71 | fmt.Printf("Sending %s CL Rewards to Claim vault\n\n", eth.DisplayAmountInUnits(res.ClRewardsAmount, "eth"))
72 | cliutils.PrintTransactionHash(staderClient, res.TxHash)
73 | if _, err = staderClient.WaitForTransaction(res.TxHash); err != nil {
74 | return err
75 | }
76 |
77 | // Log & return
78 | fmt.Printf("Sent %s CL Rewards to Claim vault\n\n", eth.DisplayAmountInUnits(res.ClRewardsAmount, "eth"))
79 |
80 | return nil
81 | }
82 |
--------------------------------------------------------------------------------
/stader-cli/wallet/bip39/mnemonic-validator.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package bip39
21 |
22 | import (
23 | "errors"
24 | "sort"
25 | "strings"
26 |
27 | "github.com/tyler-smith/go-bip39"
28 | )
29 |
30 | type MnemonicValidator struct {
31 | mnemonic []string
32 | }
33 |
34 | func Create(length int) *MnemonicValidator {
35 |
36 | if length <= 0 {
37 | return nil
38 | }
39 |
40 | out := &MnemonicValidator{}
41 |
42 | out.mnemonic = make([]string, 0, length)
43 |
44 | return out
45 | }
46 |
47 | func (mv *MnemonicValidator) AddWord(input string) error {
48 | wordList := bip39.GetWordList()
49 |
50 | idx := sort.SearchStrings(wordList, input)
51 | if idx >= len(wordList) {
52 | return errors.New("Invalid word")
53 | }
54 |
55 | if wordList[idx] != input && (len(input) < 4 || wordList[idx][:4] != input[:4]) {
56 | return errors.New("Invalid word")
57 | }
58 |
59 | mv.mnemonic = append(mv.mnemonic, wordList[idx])
60 | return nil
61 | }
62 |
63 | func (mv *MnemonicValidator) Filled() bool {
64 | return len(mv.mnemonic) == cap(mv.mnemonic)
65 | }
66 |
67 | func (mv *MnemonicValidator) Finalize() (string, error) {
68 |
69 | if mv.Filled() == false {
70 | return "", errors.New("Not enough words were entered.")
71 | }
72 |
73 | mnemonic := strings.Join(mv.mnemonic, " ")
74 | if bip39.IsMnemonicValid(mnemonic) {
75 | return mnemonic, nil
76 | }
77 |
78 | return "", errors.New("Invalid mnemonic")
79 | }
80 |
--------------------------------------------------------------------------------
/stader-cli/wallet/export.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "fmt"
24 | "os"
25 |
26 | "github.com/urfave/cli"
27 |
28 | "github.com/stader-labs/stader-node/shared/services/stader"
29 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
30 | )
31 |
32 | func exportWallet(c *cli.Context) error {
33 |
34 | staderCLient, err := stader.NewClientFromCtx(c)
35 | if err != nil {
36 | return err
37 | }
38 | defer staderCLient.Close()
39 |
40 | // Get & check wallet status
41 | status, err := staderCLient.WalletStatus()
42 | if err != nil {
43 | return err
44 | }
45 | if !status.WalletInitialized {
46 | fmt.Println("The node wallet is not initialized.")
47 | return nil
48 | }
49 |
50 | if !c.GlobalBool("secure-session") {
51 | // Check if stdout is interactive
52 | stat, err := os.Stdout.Stat()
53 | if err != nil {
54 | fmt.Fprintf(os.Stderr, "An error occurred while determining whether or not the output is a tty: %s\n"+
55 | "Use \"stader-cli --secure-session wallet export\" to bypass.\n", err.Error())
56 | os.Exit(1)
57 | }
58 |
59 | if (stat.Mode()&os.ModeCharDevice) == os.ModeCharDevice &&
60 | !cliutils.ConfirmSecureSession("Exporting a wallet will print sensitive information to your screen.") {
61 | return nil
62 | }
63 | }
64 |
65 | // Export wallet
66 | export, err := staderCLient.ExportWallet()
67 | if err != nil {
68 | return err
69 | }
70 |
71 | // Print wallet & return
72 | fmt.Println("Node account private key:")
73 | fmt.Println("")
74 | fmt.Println(export.AccountPrivateKey)
75 | fmt.Println("")
76 | fmt.Println("Wallet password:")
77 | fmt.Println("")
78 | fmt.Println(export.Password)
79 | fmt.Println("")
80 | fmt.Println("Wallet file:")
81 | fmt.Println("============")
82 | fmt.Println("")
83 | fmt.Println(export.Wallet)
84 | fmt.Println("")
85 | fmt.Println("============")
86 | return nil
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/stader-cli/wallet/status.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "fmt"
24 |
25 | "github.com/stader-labs/stader-node/shared/services/stader"
26 | "github.com/urfave/cli"
27 |
28 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
29 | )
30 |
31 | func getStatus(c *cli.Context) error {
32 |
33 | staderClient, err := stader.NewClientFromCtx(c)
34 | if err != nil {
35 | return err
36 | }
37 | defer staderClient.Close()
38 |
39 | // Print what network we're on
40 | err = cliutils.PrintNetwork(staderClient)
41 | if err != nil {
42 | return err
43 | }
44 |
45 | // Get wallet status
46 | status, err := staderClient.WalletStatus()
47 | if err != nil {
48 | return err
49 | }
50 |
51 | // Print status & return
52 | if status.WalletInitialized {
53 | fmt.Println("The node wallet is initialized.")
54 | fmt.Printf("Node account: %s\n", status.AccountAddress.Hex())
55 | fmt.Printf("Current Nonce: %d\n", status.CurrentNonce)
56 | fmt.Printf("Pending Nonce: %d\n", status.PendingNonce)
57 | } else {
58 | fmt.Println("The node wallet has not been initialized.")
59 | }
60 | return nil
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/stader-lib/README.md:
--------------------------------------------------------------------------------
1 | # Stader-node-go
2 | A Golang library for interacting with the stader node network. Parts of this code leverage opensource code from the ethereum community.
3 |
--------------------------------------------------------------------------------
/stader-lib/node/node.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
5 | "github.com/stader-labs/stader-node/stader-lib/stader"
6 | )
7 |
8 | func IsPermissionlessNodeRegistryPaused(pnr *stader.PermissionlessNodeRegistryContractManager, opts *bind.CallOpts) (bool, error) {
9 | return pnr.PermissionlessNodeRegistry.Paused(opts)
10 | }
11 |
--------------------------------------------------------------------------------
/stader-lib/penalty-tracker/penalty-tracker.go:
--------------------------------------------------------------------------------
1 | package penalty_tracker
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
5 | "github.com/stader-labs/stader-node/stader-lib/stader"
6 | "github.com/stader-labs/stader-node/stader-lib/types"
7 | "math/big"
8 | )
9 |
10 | func GetCumulativeValidatorPenalty(pt *stader.PenaltyTrackerContractManager, validatorPubKey types.ValidatorPubkey, opts *bind.CallOpts) (*big.Int, error) {
11 | return pt.Penalty.TotalPenaltyAmount(opts, validatorPubKey.Bytes())
12 | }
13 |
--------------------------------------------------------------------------------
/stader-lib/pool-utils/pool-utils.go:
--------------------------------------------------------------------------------
1 | package pool_utils
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
5 | "github.com/ethereum/go-ethereum/common"
6 | "github.com/stader-labs/stader-node/stader-lib/stader"
7 | "github.com/stader-labs/stader-node/stader-lib/types"
8 | "math/big"
9 | )
10 |
11 | func CalculateRewardShare(pool_utils *stader.PoolUtilsContractManager, poolId uint8, totalRewards *big.Int, opts *bind.CallOpts) (types.RewardShare, error) {
12 | return pool_utils.PoolUtils.CalculateRewardShare(opts, poolId, totalRewards)
13 | }
14 |
15 | func IsExistingOperator(pool_utils *stader.PoolUtilsContractManager, operatorAddress common.Address, opts *bind.CallOpts) (bool, error) {
16 | return pool_utils.PoolUtils.IsExistingOperator(opts, operatorAddress)
17 | }
18 |
--------------------------------------------------------------------------------
/stader-lib/stader/abi.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package stader
21 |
22 | import (
23 | "bytes"
24 | "compress/zlib"
25 | "encoding/base64"
26 | "fmt"
27 |
28 | "github.com/ethereum/go-ethereum/accounts/abi"
29 | )
30 |
31 | // Decode, decompress and parse a zlib-compressed, base64-encoded ABI
32 | func DecodeAbi(abiEncoded string) (*abi.ABI, error) {
33 |
34 | // base64 decode
35 | abiCompressed, err := base64.StdEncoding.DecodeString(abiEncoded)
36 | if err != nil {
37 | return nil, fmt.Errorf("Could not decode base64 data: %w", err)
38 | }
39 |
40 | // zlib decompress
41 | byteReader := bytes.NewReader(abiCompressed)
42 | zlibReader, err := zlib.NewReader(byteReader)
43 | if err != nil {
44 | return nil, fmt.Errorf("Could not decompress zlib data: %w", err)
45 | }
46 | defer func() {
47 | _ = zlibReader.Close()
48 | }()
49 |
50 | // Parse ABI
51 | abiParsed, err := abi.JSON(zlibReader)
52 | if err != nil {
53 | return nil, fmt.Errorf("Could not parse JSON: %w", err)
54 | }
55 |
56 | // Return
57 | return &abiParsed, nil
58 |
59 | }
60 |
61 | // zlib-compress and base64-encode an ABI JSON string
62 | func EncodeAbiStr(abiStr string) (string, error) {
63 |
64 | // zlib compress
65 | var abiCompressed bytes.Buffer
66 | zlibWriter := zlib.NewWriter(&abiCompressed)
67 | if _, err := zlibWriter.Write([]byte(abiStr)); err != nil {
68 | return "", fmt.Errorf("Could not zlib-compress ABI string: %w", err)
69 | }
70 | if err := zlibWriter.Flush(); err != nil {
71 | return "", fmt.Errorf("Could not zlib-compress ABI string: %w", err)
72 | }
73 | if err := zlibWriter.Close(); err != nil {
74 | return "", fmt.Errorf("Could not zlib-compress ABI string: %w", err)
75 | }
76 |
77 | // base64 encode & return
78 | return base64.StdEncoding.EncodeToString(abiCompressed.Bytes()), nil
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/stader-lib/stake-pool-manager/stake-pool-manager.go:
--------------------------------------------------------------------------------
1 | package stake_pool_manager
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
5 | "github.com/stader-labs/stader-node/stader-lib/stader"
6 | "math/big"
7 | )
8 |
9 | func GetTotalAssets(spm *stader.StakePoolManagerContractManager, opts *bind.CallOpts) (*big.Int, error) {
10 | return spm.StakePoolManager.TotalAssets(opts)
11 | }
12 |
--------------------------------------------------------------------------------
/stader-lib/tokens/native.go:
--------------------------------------------------------------------------------
1 | package tokens
2 |
3 | import (
4 | "context"
5 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
6 | "github.com/ethereum/go-ethereum/common"
7 | "github.com/stader-labs/stader-node/stader-lib/stader"
8 | "math/big"
9 | )
10 |
11 | func GetEthBalance(client stader.ExecutionClient, address common.Address, opts *bind.CallOpts) (*big.Int, error) {
12 | var blockNumber *big.Int
13 | if opts != nil {
14 | blockNumber = opts.BlockNumber
15 | }
16 |
17 | ethBalance, err := client.BalanceAt(context.Background(), address, blockNumber)
18 | if err != nil {
19 | return nil, err
20 | }
21 |
22 | return ethBalance, nil
23 | }
24 |
--------------------------------------------------------------------------------
/stader-lib/types/operator.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "github.com/ethereum/go-ethereum/common"
4 |
5 | type OperatorInfo struct {
6 | Active bool
7 | OptedForSocializingPool bool
8 | OperatorName string
9 | OperatorRewardAddress common.Address
10 | OperatorAddress common.Address
11 | }
12 |
--------------------------------------------------------------------------------
/stader-lib/types/pool-utils.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "math/big"
4 |
5 | type RewardShare struct {
6 | UserShare *big.Int
7 | OperatorShare *big.Int
8 | ProtocolShare *big.Int
9 | }
10 |
--------------------------------------------------------------------------------
/stader-lib/types/sd-collateral.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "math/big"
4 |
5 | type PoolThresholdInfo struct {
6 | MinThreshold *big.Int
7 | MaxThreshold *big.Int
8 | WithdrawThreshold *big.Int
9 | Units string
10 | }
11 |
12 | type OperatorWithdrawInfo struct {
13 | LastWithdrawReqTimestamp *big.Int
14 | TotalSDWithdrawReqAmount *big.Int
15 | }
16 |
--------------------------------------------------------------------------------
/stader-lib/types/socializing-pool.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "math/big"
4 |
5 | type RewardCycleDetails struct {
6 | CurrentIndex *big.Int
7 | CurrentStartBlock *big.Int
8 | CurrentEndBlock *big.Int
9 | }
10 |
11 | type CurrentRewardCycleDetails struct {
12 | StartBlock *big.Int
13 | EndBlock *big.Int
14 | }
15 |
--------------------------------------------------------------------------------
/stader-lib/types/validator.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/common"
5 | "math/big"
6 | )
7 |
8 | type ValidatorContractInfo struct {
9 | Status uint8
10 | Pubkey []byte
11 | PreDepositSignature []byte
12 | DepositSignature []byte
13 | WithdrawVaultAddress common.Address
14 | OperatorId *big.Int
15 | DepositBlock *big.Int
16 | WithdrawnBlock *big.Int
17 | }
18 |
--------------------------------------------------------------------------------
/stader-lib/utils/eth/units.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package eth
21 |
22 | import (
23 | "math/big"
24 | "strconv"
25 | )
26 |
27 | // Conversion factors
28 | const (
29 | WeiPerEth float64 = 1e18
30 | WeiPerGwei float64 = 1e9
31 | Decimal = 18
32 | BaseAmountInEth = 4
33 | Threshold = 1e12
34 | )
35 |
36 | func DisplayAmountInUnits(wei *big.Int, denom string) string {
37 | gweiDenom := " gwei"
38 | if denom == "sd" {
39 | gweiDenom = " gwei SD"
40 | }
41 |
42 | regDenom := " ETH"
43 | if denom == "sd" {
44 | regDenom = " SD"
45 | }
46 |
47 | if wei == nil {
48 | return ""
49 | }
50 |
51 | if wei.Cmp(big.NewInt(Threshold)) < 0 && wei.Cmp(big.NewInt(0)) != 0 {
52 | return strconv.FormatFloat(WeiToGwei(wei), 'f', 6, 64) + gweiDenom
53 | }
54 |
55 | return strconv.FormatFloat(WeiToEth(wei), 'f', 6, 64) + regDenom
56 | }
57 |
58 | // Convert wei to eth
59 | func WeiToEth(wei *big.Int) float64 {
60 | var weiFloat big.Float
61 | var eth big.Float
62 | weiFloat.SetInt(wei)
63 | eth.Quo(&weiFloat, big.NewFloat(WeiPerEth))
64 | eth64, _ := eth.Float64()
65 | return eth64
66 | }
67 |
68 | // Convert eth to wei
69 | func EthToWei(eth float64) *big.Int {
70 | var ethFloat big.Float
71 | var weiFloat big.Float
72 | var wei big.Int
73 | ethFloat.SetString(strconv.FormatFloat(eth, 'f', -1, 64))
74 | weiFloat.Mul(ðFloat, big.NewFloat(WeiPerEth))
75 | weiFloat.Int(&wei)
76 | return &wei
77 | }
78 |
79 | // Convert wei to gigawei
80 | func WeiToGwei(wei *big.Int) float64 {
81 | var weiFloat big.Float
82 | var gwei big.Float
83 | weiFloat.SetInt(wei)
84 | gwei.Quo(&weiFloat, big.NewFloat(WeiPerGwei))
85 | gwei64, _ := gwei.Float64()
86 | return gwei64
87 | }
88 |
89 | // Convert gigawei to wei
90 | func GweiToWei(gwei float64) *big.Int {
91 | var gweiFloat big.Float
92 | var weiFloat big.Float
93 | var wei big.Int
94 | gweiFloat.SetString(strconv.FormatFloat(gwei, 'f', -1, 64))
95 | weiFloat.Mul(&gweiFloat, big.NewFloat(WeiPerGwei))
96 | weiFloat.Int(&wei)
97 | return &wei
98 | }
99 |
--------------------------------------------------------------------------------
/stader-lib/utils/json/json.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package json
21 |
22 | import (
23 | "encoding/json"
24 | "fmt"
25 | )
26 |
27 | func Marshal(v interface{}) ([]byte, error) {
28 | return json.Marshal(v)
29 | }
30 |
31 | func Unmarshal(data []byte, v interface{}) error {
32 | err := json.Unmarshal(data, v)
33 | if err != nil {
34 | return fmt.Errorf("%w\nUnable to Unmarshal JSON string %s", err, string(data))
35 | }
36 |
37 | return nil
38 | }
39 |
--------------------------------------------------------------------------------
/stader-lib/utils/sd/sd.go:
--------------------------------------------------------------------------------
1 | package sd
2 |
3 | import (
4 | "fmt"
5 | "math/big"
6 | "strconv"
7 |
8 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
9 | "github.com/stader-labs/stader-node/stader-lib/utils/eth"
10 | )
11 |
12 | const (
13 | SDFloatStringEqualityThreshold = 0.1
14 | )
15 |
16 | var SDWeiEqualityThreshold = eth.EthToWei(SDFloatStringEqualityThreshold)
17 |
18 | func WeiAlmostEqual(lhs, rhs *big.Int) bool {
19 | diversity := new(big.Int).Sub(lhs, rhs)
20 |
21 | return diversity.CmpAbs(SDWeiEqualityThreshold) <= 0
22 | }
23 |
24 | func PromptChooseSDWithMaxMin(msg, errMsg string, min, max *big.Int) (*big.Int, error) {
25 | var utilityAmountWei *big.Int
26 |
27 | var errParse error
28 |
29 | for {
30 | s := cliutils.Prompt(
31 | msg,
32 | `^[0-9]\d*(\.\d+)?$`,
33 | errMsg)
34 |
35 | var utilityAmountFloat float64
36 | utilityAmountFloat, errParse = strconv.ParseFloat(s, 64)
37 |
38 | if errParse != nil {
39 | fmt.Println(errMsg)
40 | continue
41 | }
42 |
43 | utilityAmountWei = eth.EthToWei(utilityAmountFloat)
44 |
45 | if utilityAmountWei.Cmp(min) < 0 || utilityAmountWei.Cmp(max) > 0 || utilityAmountWei.Cmp(big.NewInt(0)) == 0 {
46 | fmt.Println(errMsg)
47 | continue
48 | }
49 |
50 | break
51 | }
52 |
53 | return utilityAmountWei, errParse
54 | }
55 |
--------------------------------------------------------------------------------
/stader-lib/utils/wait.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package utils
21 |
22 | import (
23 | "context"
24 | "errors"
25 | "fmt"
26 | "time"
27 |
28 | "github.com/ethereum/go-ethereum/accounts/abi/bind"
29 | "github.com/ethereum/go-ethereum/common"
30 | "github.com/ethereum/go-ethereum/core/types"
31 | "github.com/stader-labs/stader-node/stader-lib/stader"
32 | )
33 |
34 | // Wait for a transaction to get mined
35 | func WaitForTransaction(client stader.ExecutionClient, hash common.Hash) (*types.Receipt, error) {
36 |
37 | var tx *types.Transaction
38 | var err error
39 |
40 | // Get the transaction from its hash, retrying for 30 sec if it wasn't found
41 | for i := 0; i < 30; i++ {
42 | if i == 29 {
43 | return nil, fmt.Errorf("Transaction not found after 30 seconds.")
44 | }
45 |
46 | tx, _, err = client.TransactionByHash(context.Background(), hash)
47 | if err != nil {
48 | if err.Error() == "not found" {
49 | time.Sleep(1 * time.Second)
50 | continue
51 | }
52 | return nil, err
53 | } else {
54 | break
55 | }
56 | }
57 |
58 | // Wait for transaction to be mined
59 | txReceipt, err := bind.WaitMined(context.Background(), client, tx)
60 | if err != nil {
61 | return nil, err
62 | }
63 |
64 | // Check transaction status
65 | if txReceipt.Status == 0 {
66 | return txReceipt, errors.New("Transaction failed with status 0")
67 | }
68 |
69 | // Return
70 | return txReceipt, nil
71 | }
72 |
--------------------------------------------------------------------------------
/stader/api/node/get-contracts-info.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/urfave/cli"
7 |
8 | "github.com/stader-labs/stader-node/shared/services"
9 | "github.com/stader-labs/stader-node/shared/types/api"
10 | )
11 |
12 | func getContractsInfo(c *cli.Context) (*api.ContractsInfoResponse, error) {
13 | // Response
14 | response := api.ContractsInfoResponse{}
15 |
16 | // Get the ETH1 network ID
17 | config, err := services.GetConfig(c)
18 | if err != nil {
19 | return nil, fmt.Errorf("Error getting configuration: %w", err)
20 | }
21 |
22 | response.Network = uint64(config.StaderNode.GetChainID())
23 | response.EncryptionKey = config.StaderNode.GetPresignEncryptionKey()
24 |
25 | // Get the Beacon Client info
26 | bc, err := services.GetBeaconClient(c)
27 | if err != nil {
28 | return nil, fmt.Errorf("Error getting beacon client: %w", err)
29 | }
30 |
31 | eth2DepositContract, err := bc.GetEth2DepositContract()
32 | if err != nil {
33 | return nil, fmt.Errorf("Error getting beacon client deposit contract: %w", err)
34 | }
35 |
36 | response.BeaconNetwork = eth2DepositContract.ChainID
37 | response.BeaconDepositContract = eth2DepositContract.Address
38 |
39 | response.SdCollateralContract, err = services.GetSdCollateralAddress(c)
40 | if err != nil {
41 | return nil, err
42 | }
43 | response.StaderConfig = config.StaderNode.GetStaderConfigAddress()
44 |
45 | response.EthxToken, err = services.GetEthxTokenAddress(c)
46 | if err != nil {
47 | return nil, err
48 | }
49 |
50 | response.SdToken, err = services.GetSdTokenAddress(c)
51 | if err != nil {
52 | return nil, err
53 | }
54 |
55 | response.PermissionlessNodeRegistry, err = services.GetPermissionlessNodeRegistryAddress(c)
56 | if err != nil {
57 | return nil, err
58 | }
59 |
60 | response.VaultFactory, err = services.GetVaultFactoryAddress(c)
61 | if err != nil {
62 | return nil, err
63 | }
64 |
65 | response.SocializingPoolContract, err = services.GetSocializingPoolAddress(c)
66 | if err != nil {
67 | return nil, err
68 | }
69 |
70 | response.PermisionlessPool, err = services.GetPermissionlessPoolAddress(c)
71 | if err != nil {
72 | return nil, err
73 | }
74 |
75 | response.StaderOracle, err = services.GetStaderOracleAddress(c)
76 | if err != nil {
77 | return nil, err
78 | }
79 |
80 | response.StakePoolManager, err = services.GetStakePoolManagerAddress(c)
81 | if err != nil {
82 | return nil, err
83 | }
84 |
85 | response.SdUtilityContract, err = services.GetSdUtilityAddress(c)
86 | if err != nil {
87 | return nil, err
88 | }
89 |
90 | // Return response
91 | return &response, nil
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/stader/api/node/repay-sd.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "math/big"
5 |
6 | "github.com/ethereum/go-ethereum/accounts/abi"
7 | "github.com/ethereum/go-ethereum/core/types"
8 | "github.com/stader-labs/stader-node/stader-lib/sdutility"
9 | "github.com/stader-labs/stader-node/stader-lib/stader"
10 |
11 | "github.com/urfave/cli"
12 |
13 | "github.com/stader-labs/stader-node/shared/services"
14 | "github.com/stader-labs/stader-node/shared/types/api"
15 | )
16 |
17 | func canRepaySD(c *cli.Context, amountWei *big.Int) (*api.CanRepaySDResponse, error) {
18 | // Get services
19 | if err := services.RequireNodeWallet(c); err != nil {
20 | return nil, err
21 | }
22 |
23 | w, err := services.GetWallet(c)
24 | if err != nil {
25 | return nil, err
26 | }
27 |
28 | // Response
29 | response := api.CanRepaySDResponse{}
30 |
31 | sdu, err := services.GetSdUtilityContract(c)
32 | if err != nil {
33 | return nil, err
34 | }
35 |
36 | isAmountMaxUint256 := amountWei.Cmp(abi.MaxUint256) == 0
37 |
38 | // Get gas estimates
39 | opts, err := w.GetNodeAccountTransactor()
40 | if err != nil {
41 | return nil, err
42 | }
43 |
44 | var gasInfo stader.GasInfo
45 |
46 | if isAmountMaxUint256 {
47 | gasInfo, err = sdutility.EstimateRepayFullAmount(sdu, opts)
48 | if err != nil {
49 | return nil, err
50 | }
51 | } else {
52 | gasInfo, err = sdutility.EstimateRepay(sdu, amountWei, opts)
53 | if err != nil {
54 | return nil, err
55 | }
56 | }
57 |
58 | response.GasInfo = gasInfo
59 |
60 | return &response, nil
61 | }
62 |
63 | func repaySD(c *cli.Context, amountWei *big.Int) (*api.NodeRepaySDResponse, error) {
64 | // Get services
65 | if err := services.RequireNodeWallet(c); err != nil {
66 | return nil, err
67 | }
68 |
69 | w, err := services.GetWallet(c)
70 | if err != nil {
71 | return nil, err
72 | }
73 |
74 | sdu, err := services.GetSdUtilityContract(c)
75 | if err != nil {
76 | return nil, err
77 | }
78 |
79 | // Get gas estimates
80 | opts, err := w.GetNodeAccountTransactor()
81 | if err != nil {
82 | return nil, err
83 | }
84 |
85 | isAmountMaxUint256 := amountWei.Cmp(abi.MaxUint256) == 0
86 |
87 | // Response
88 | response := api.NodeRepaySDResponse{}
89 |
90 | var tx *types.Transaction
91 | if isAmountMaxUint256 {
92 | tx, err = sdutility.RepayFullAmount(sdu, opts)
93 | if err != nil {
94 | return nil, err
95 | }
96 | } else {
97 | tx, err = sdutility.Repay(sdu, amountWei, opts)
98 | if err != nil {
99 | return nil, err
100 | }
101 | }
102 |
103 | response.TxHash = tx.Hash()
104 |
105 | return &response, nil
106 | }
107 |
--------------------------------------------------------------------------------
/stader/api/node/sd-status.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "math/big"
5 |
6 | "github.com/stader-labs/stader-node/stader-lib/node"
7 | sd_collateral "github.com/stader-labs/stader-node/stader-lib/sd-collateral"
8 | "github.com/stader-labs/stader-node/stader/api/validator"
9 |
10 | "github.com/urfave/cli"
11 |
12 | "github.com/stader-labs/stader-node/shared/services"
13 | "github.com/stader-labs/stader-node/shared/types/api"
14 | )
15 |
16 | func getSDStatus(c *cli.Context, numValidators *big.Int) (*api.GetSdStatusResponse, error) {
17 | sdc, err := services.GetSdCollateralContract(c)
18 | if err != nil {
19 | return nil, err
20 | }
21 |
22 | sdt, err := services.GetSdTokenContract(c)
23 | if err != nil {
24 | return nil, err
25 | }
26 |
27 | sdu, err := services.GetSdUtilityContract(c)
28 | if err != nil {
29 | return nil, err
30 | }
31 |
32 | w, err := services.GetWallet(c)
33 | if err != nil {
34 | return nil, err
35 | }
36 |
37 | // Get node account
38 | nodeAccount, err := w.GetNodeAccount()
39 | if err != nil {
40 | return nil, err
41 | }
42 |
43 | prn, err := services.GetPermissionlessNodeRegistry(c)
44 | if err != nil {
45 | return nil, err
46 | }
47 |
48 | operatorID, err := node.GetOperatorId(prn, nodeAccount.Address, nil)
49 | if err != nil {
50 | return nil, err
51 | }
52 |
53 | totalValidatorKeys, err := node.GetTotalValidatorKeys(prn, operatorID, nil)
54 | if err != nil {
55 | return nil, err
56 | }
57 |
58 | totalValidatorNonTerminalKeys, err := node.GetTotalNonTerminalValidatorKeys(prn, nodeAccount.Address, totalValidatorKeys, nil)
59 | if err != nil {
60 | return nil, err
61 | }
62 |
63 | numValidatorsPostAdd := new(big.Int).Add(numValidators, big.NewInt(int64(totalValidatorNonTerminalKeys)))
64 |
65 | sdStatus, err := validator.GetSDStatus(sdc, sdu, sdt, nodeAccount.Address, numValidatorsPostAdd)
66 | if err != nil {
67 | return nil, err
68 | }
69 |
70 | hasEnoughSdCollateral, err := sd_collateral.HasEnoughSdCollateral(sdc, nodeAccount.Address, 1, numValidatorsPostAdd, nil)
71 | if err != nil {
72 | return nil, err
73 | }
74 |
75 | sdStatus.NotEnoughSdCollateral = !hasEnoughSdCollateral
76 |
77 | return &api.GetSdStatusResponse{
78 | SDStatus: sdStatus,
79 | }, nil
80 | }
81 |
--------------------------------------------------------------------------------
/stader/api/node/sign-message.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package node
21 |
22 | import (
23 | "encoding/hex"
24 | "fmt"
25 | _ "time/tzdata"
26 |
27 | "github.com/urfave/cli"
28 |
29 | "github.com/stader-labs/stader-node/shared/services"
30 | "github.com/stader-labs/stader-node/shared/types/api"
31 | hexutils "github.com/stader-labs/stader-node/shared/utils/hex"
32 | )
33 |
34 | func signMessage(c *cli.Context, message string) (*api.NodeSignResponse, error) {
35 | // Get services
36 | w, err := services.GetWallet(c)
37 | if err != nil {
38 | return nil, err
39 | }
40 |
41 | // Response
42 | response := api.NodeSignResponse{}
43 | signedBytes, err := w.SignMessage(message)
44 | if err != nil {
45 | return nil, fmt.Errorf("Error signing message [%s]: %w", message, err)
46 | }
47 | response.SignedData = hexutils.AddPrefix(hex.EncodeToString(signedBytes))
48 |
49 | // Return response
50 | return &response, nil
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/stader/api/node/sign.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package node
21 |
22 | import (
23 | "encoding/hex"
24 | "fmt"
25 | _ "time/tzdata"
26 |
27 | "github.com/urfave/cli"
28 |
29 | "github.com/stader-labs/stader-node/shared/services"
30 | "github.com/stader-labs/stader-node/shared/types/api"
31 | hexutils "github.com/stader-labs/stader-node/shared/utils/hex"
32 | )
33 |
34 | func sign(c *cli.Context, serializedTx string) (*api.NodeSignResponse, error) {
35 |
36 | // Get services
37 | if err := services.RequireNodeRegistered(c); err != nil {
38 | return nil, err
39 | }
40 | w, err := services.GetWallet(c)
41 | if err != nil {
42 | return nil, err
43 | }
44 | // Response
45 | response := api.NodeSignResponse{}
46 |
47 | serializedTx = hexutils.RemovePrefix(serializedTx)
48 | bytes, err := hex.DecodeString(serializedTx)
49 | if err != nil {
50 | return nil, fmt.Errorf("Error parsing TX bytes [%s]: %w", serializedTx, err)
51 | }
52 |
53 | signedBytes, err := w.Sign(bytes)
54 | if err != nil {
55 | return nil, fmt.Errorf("Error signing TX [%s]: %w", serializedTx, err)
56 | }
57 | response.SignedData = hexutils.AddPrefix(hex.EncodeToString(signedBytes))
58 |
59 | // Return response
60 | return &response, nil
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/stader/api/node/sync.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package node
21 |
22 | import (
23 | "github.com/urfave/cli"
24 |
25 | "github.com/stader-labs/stader-node/shared/services"
26 | "github.com/stader-labs/stader-node/shared/types/api"
27 | )
28 |
29 | func getSyncProgress(c *cli.Context) (*api.NodeSyncProgressResponse, error) {
30 |
31 | // Response
32 | response := api.NodeSyncProgressResponse{}
33 |
34 | cfg, err := services.GetConfig(c)
35 | if err != nil {
36 | return nil, err
37 | }
38 |
39 | // Get the EC manager
40 | ecMgr, err := services.GetEthClient(c)
41 | if err != nil {
42 | return nil, err
43 | }
44 |
45 | // Get the status of the EC and fallback EC
46 | ecStatus := ecMgr.CheckStatus(cfg)
47 | response.EcStatus = *ecStatus
48 |
49 | // Get the BC manager
50 | bcMgr, err := services.GetBeaconClient(c)
51 | if err != nil {
52 | return nil, err
53 | }
54 |
55 | // Get the status of the BC and fallback BC
56 | bcStatus := bcMgr.CheckStatus()
57 | response.BcStatus = *bcStatus
58 |
59 | // Return response
60 | return &response, nil
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/stader/api/node/utility-sd.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "math/big"
5 |
6 | "github.com/stader-labs/stader-node/stader-lib/node"
7 | "github.com/urfave/cli"
8 |
9 | "github.com/stader-labs/stader-node/shared/services"
10 | "github.com/stader-labs/stader-node/shared/types/api"
11 | "github.com/stader-labs/stader-node/stader-lib/sdutility"
12 | )
13 |
14 | func canUtilitySd(c *cli.Context, amountWei *big.Int) (*api.CanUtilitySDResponse, error) {
15 | if err := services.RequireNodeWallet(c); err != nil {
16 | return nil, err
17 | }
18 |
19 | w, err := services.GetWallet(c)
20 | if err != nil {
21 | return nil, err
22 | }
23 |
24 | nodeAccount, err := w.GetNodeAccount()
25 | if err != nil {
26 | return nil, err
27 | }
28 |
29 | prn, err := services.GetPermissionlessNodeRegistry(c)
30 | if err != nil {
31 | return nil, err
32 | }
33 |
34 | // Response
35 | response := api.CanUtilitySDResponse{}
36 |
37 | sdu, err := services.GetSdUtilityContract(c)
38 | if err != nil {
39 | return nil, err
40 | }
41 |
42 | operatorID, err := node.GetOperatorId(prn, nodeAccount.Address, nil)
43 | if err != nil {
44 | return nil, err
45 | }
46 |
47 | totalValidatorKeys, err := node.GetTotalValidatorKeys(prn, operatorID, nil)
48 | if err != nil {
49 | return nil, err
50 | }
51 |
52 | totalValidatorNonTerminalKeys, err := node.GetTotalNonTerminalValidatorKeys(prn, nodeAccount.Address, totalValidatorKeys, nil)
53 | if err != nil {
54 | return nil, err
55 | }
56 |
57 | response.NonTerminalValidators = totalValidatorNonTerminalKeys
58 |
59 | // Get gas estimates
60 | opts, err := w.GetNodeAccountTransactor()
61 | if err != nil {
62 | return nil, err
63 | }
64 |
65 | gasInfo, err := sdutility.EstimateUtilize(sdu, amountWei, opts)
66 | if err != nil {
67 | return nil, err
68 | }
69 |
70 | response.GasInfo = gasInfo
71 |
72 | return &response, nil
73 | }
74 |
75 | func utilitySd(c *cli.Context, amountWei *big.Int) (*api.NodeUtilitySDResponse, error) {
76 | // Get services
77 | if err := services.RequireNodeWallet(c); err != nil {
78 | return nil, err
79 | }
80 |
81 | w, err := services.GetWallet(c)
82 | if err != nil {
83 | return nil, err
84 | }
85 |
86 | sdu, err := services.GetSdUtilityContract(c)
87 | if err != nil {
88 | return nil, err
89 | }
90 |
91 | // Get gas estimates
92 | opts, err := w.GetNodeAccountTransactor()
93 | if err != nil {
94 | return nil, err
95 | }
96 |
97 | // Response
98 | response := api.NodeUtilitySDResponse{}
99 |
100 | tx, err := sdutility.Utilize(sdu, amountWei, opts)
101 | if err != nil {
102 | return nil, err
103 | }
104 |
105 | response.TxHash = tx.Hash()
106 |
107 | return &response, nil
108 | }
109 |
--------------------------------------------------------------------------------
/stader/api/service/commands.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package service
21 |
22 | import (
23 | "github.com/urfave/cli"
24 |
25 | "github.com/stader-labs/stader-node/shared/utils/api"
26 | cliutils "github.com/stader-labs/stader-node/shared/utils/cli"
27 | )
28 |
29 | // Register subcommands
30 | func RegisterSubcommands(command *cli.Command, name string, aliases []string) {
31 | command.Subcommands = append(command.Subcommands, cli.Command{
32 | Name: name,
33 | Aliases: aliases,
34 | Usage: "Manage the deposit queue",
35 | Subcommands: []cli.Command{
36 | {
37 | Name: "terminate-data-folder",
38 | Aliases: []string{"t"},
39 | Usage: "Deletes the data folder including the wallet file, password file, and all validator keys - don't use this unless you have a very good reason to do it (such as switching from Prater to Mainnet)",
40 | UsageText: "stader-cli api service terminate-data-folder",
41 | Action: func(c *cli.Context) error {
42 |
43 | // Validate args
44 | if err := cliutils.ValidateArgCount(c, 0); err != nil {
45 | return err
46 | }
47 |
48 | // Run
49 | api.PrintResponse(terminateDataFolder(c))
50 | return nil
51 |
52 | },
53 | },
54 |
55 | {
56 | Name: "get-client-status",
57 | Aliases: []string{"g"},
58 | Usage: "Gets the status of the configured Execution and Beacon clients",
59 | UsageText: "stader-cli api service get-client-status",
60 | Action: func(c *cli.Context) error {
61 |
62 | // Validate args
63 | if err := cliutils.ValidateArgCount(c, 0); err != nil {
64 | return err
65 | }
66 |
67 | // Run
68 | api.PrintResponse(getClientStatus(c))
69 | return nil
70 |
71 | },
72 | },
73 | },
74 | })
75 | }
76 |
--------------------------------------------------------------------------------
/stader/api/service/status.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package service
21 |
22 | import (
23 | "github.com/urfave/cli"
24 |
25 | "github.com/stader-labs/stader-node/shared/services"
26 | "github.com/stader-labs/stader-node/shared/types/api"
27 | )
28 |
29 | // Gets the status of the configured Execution clients
30 | func getClientStatus(c *cli.Context) (*api.ClientStatusResponse, error) {
31 |
32 | // Get services
33 | ec, err := services.GetEthClient(c)
34 | if err != nil {
35 | return nil, err
36 | }
37 | bc, err := services.GetBeaconClient(c)
38 | if err != nil {
39 | return nil, err
40 | }
41 |
42 | cfg, err := services.GetConfig(c)
43 | if err != nil {
44 | return nil, err
45 | }
46 |
47 | // Response
48 | response := api.ClientStatusResponse{}
49 |
50 | // Get the EC manager status
51 | ecMgrStatus := ec.CheckStatus(cfg)
52 | response.EcManagerStatus = *ecMgrStatus
53 |
54 | // Get the BC manager status
55 | bcMgrStatus := bc.CheckStatus()
56 | response.BcManagerStatus = *bcMgrStatus
57 |
58 | // Return response
59 | return &response, nil
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/stader/api/wallet/export.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "encoding/hex"
24 |
25 | "github.com/urfave/cli"
26 |
27 | "github.com/stader-labs/stader-node/shared/services"
28 | "github.com/stader-labs/stader-node/shared/types/api"
29 | )
30 |
31 | func exportWallet(c *cli.Context) (*api.ExportWalletResponse, error) {
32 |
33 | // Get services
34 | if err := services.RequireNodeWallet(c); err != nil {
35 | return nil, err
36 | }
37 | pm, err := services.GetPasswordManager(c)
38 | if err != nil {
39 | return nil, err
40 | }
41 | w, err := services.GetWallet(c)
42 | if err != nil {
43 | return nil, err
44 | }
45 |
46 | // Response
47 | response := api.ExportWalletResponse{}
48 |
49 | // Get password
50 | password, err := pm.GetPassword()
51 | if err != nil {
52 | return nil, err
53 | }
54 | response.Password = password
55 |
56 | // Serialize wallet
57 | wallet, err := w.String()
58 | if err != nil {
59 | return nil, err
60 | }
61 | response.Wallet = wallet
62 |
63 | // Get account private key
64 | privateKey, err := w.GetNodePrivateKeyBytes()
65 | if err != nil {
66 | return nil, err
67 | }
68 | response.AccountPrivateKey = hex.EncodeToString(privateKey)
69 |
70 | // Return response
71 | return &response, nil
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/stader/api/wallet/init.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "errors"
24 |
25 | "github.com/urfave/cli"
26 |
27 | "github.com/stader-labs/stader-node/shared/services"
28 | "github.com/stader-labs/stader-node/shared/services/wallet"
29 | "github.com/stader-labs/stader-node/shared/types/api"
30 | )
31 |
32 | func initWallet(c *cli.Context) (*api.InitWalletResponse, error) {
33 |
34 | // Get services
35 | if err := services.RequireNodePassword(c); err != nil {
36 | return nil, err
37 | }
38 | w, err := services.GetWallet(c)
39 | if err != nil {
40 | return nil, err
41 | }
42 |
43 | // Response
44 | response := api.InitWalletResponse{}
45 |
46 | // Check if wallet is already initialized
47 | if w.IsInitialized() {
48 | return nil, errors.New("The wallet is already initialized")
49 | }
50 |
51 | // Get the derivation path
52 | path := c.String("derivation-path")
53 | switch path {
54 | case "":
55 | path = wallet.DefaultNodeKeyPath
56 | case "ledgerLive":
57 | path = wallet.LedgerLiveNodeKeyPath
58 | case "mew":
59 | path = wallet.MyEtherWalletNodeKeyPath
60 | }
61 |
62 | // Initialize wallet but don't save it
63 | mnemonic, err := w.Initialize(path, 0)
64 | if err != nil {
65 | return nil, err
66 | }
67 | response.Mnemonic = mnemonic
68 |
69 | // Get node account
70 | nodeAccount, err := w.GetNodeAccount()
71 | if err != nil {
72 | return nil, err
73 | }
74 | response.AccountAddress = nodeAccount.Address
75 |
76 | // Return response
77 | return &response, nil
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/stader/api/wallet/purge.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "fmt"
24 |
25 | "github.com/stader-labs/stader-node/shared/services"
26 | "github.com/stader-labs/stader-node/shared/types/api"
27 | "github.com/stader-labs/stader-node/shared/utils/validator"
28 | "github.com/urfave/cli"
29 | )
30 |
31 | func purge(c *cli.Context) (*api.PurgeResponse, error) {
32 |
33 | cfg, err := services.GetConfig(c)
34 | if err != nil {
35 | return nil, err
36 | }
37 |
38 | w, err := services.GetWallet(c)
39 | if err != nil {
40 | return nil, err
41 | }
42 |
43 | pm, err := services.GetPasswordManager(c)
44 | if err != nil {
45 | return nil, err
46 | }
47 |
48 | bc, err := services.GetBeaconClient(c)
49 | if err != nil {
50 | return nil, err
51 | }
52 |
53 | d, err := services.GetDocker(c)
54 | if err != nil {
55 | return nil, err
56 | }
57 |
58 | response := api.PurgeResponse{}
59 |
60 | // Stop the VC to unlock keystores and slashing DBs
61 | err = validator.StopValidator(cfg, bc, nil, d)
62 | if err != nil {
63 | return nil, fmt.Errorf("error stopping validator client: %w", err)
64 | }
65 |
66 | // Delete the VC directories
67 | err = w.DeleteValidatorStores()
68 | if err != nil {
69 | return nil, fmt.Errorf("error deleting validator storage: %w", err)
70 | }
71 |
72 | // Delete the wallet and password
73 | err = w.Delete()
74 | if err != nil {
75 | return nil, fmt.Errorf("error deleting wallet: %w", err)
76 | }
77 | err = pm.DeletePassword()
78 | if err != nil {
79 | return nil, fmt.Errorf("error deleting password: %w", err)
80 | }
81 |
82 | // Restart the VC once cleanup is done
83 | err = validator.RestartValidator(cfg, bc, nil, d)
84 | if err != nil {
85 | return nil, fmt.Errorf("error restarting validator client: %w", err)
86 | }
87 |
88 | return &response, nil
89 | }
90 |
--------------------------------------------------------------------------------
/stader/api/wallet/set-password.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "errors"
24 |
25 | "github.com/urfave/cli"
26 |
27 | "github.com/stader-labs/stader-node/shared/services"
28 | "github.com/stader-labs/stader-node/shared/types/api"
29 | )
30 |
31 | func setPassword(c *cli.Context, password string) (*api.SetPasswordResponse, error) {
32 |
33 | // Get services
34 | pm, err := services.GetPasswordManager(c)
35 | if err != nil {
36 | return nil, err
37 | }
38 |
39 | // Response
40 | response := api.SetPasswordResponse{}
41 |
42 | // Check if password is already set
43 | if pm.IsPasswordSet() {
44 | return nil, errors.New("The node password is already set")
45 | }
46 |
47 | // Set password
48 | if err := pm.SetPassword(password); err != nil {
49 | return nil, err
50 | }
51 |
52 | // Return response
53 | return &response, nil
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/stader/api/wallet/status.go:
--------------------------------------------------------------------------------
1 | /*
2 | This work is licensed and released under GNU GPL v3 or any other later versions.
3 | The full text of the license is below/ found at
4 |
5 | (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
6 |
7 | This program is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program. If not, see .
19 | */
20 | package wallet
21 |
22 | import (
23 | "context"
24 | "math/big"
25 |
26 | "github.com/urfave/cli"
27 |
28 | "github.com/stader-labs/stader-node/shared/services"
29 | "github.com/stader-labs/stader-node/shared/types/api"
30 | )
31 |
32 | func getStatus(c *cli.Context) (*api.WalletStatusResponse, error) {
33 |
34 | // Get services
35 | pm, err := services.GetPasswordManager(c)
36 | if err != nil {
37 | return nil, err
38 | }
39 | w, err := services.GetWallet(c)
40 | if err != nil {
41 | return nil, err
42 | }
43 | ec, err := services.GetEthClient(c)
44 | if err != nil {
45 | return nil, err
46 | }
47 |
48 | // Response
49 | response := api.WalletStatusResponse{}
50 |
51 | // Get wallet status
52 | response.PasswordSet = pm.IsPasswordSet()
53 | response.WalletInitialized = w.IsInitialized()
54 |
55 | // Get accounts if initialized
56 | if response.WalletInitialized {
57 |
58 | // Get node account
59 | nodeAccount, err := w.GetNodeAccount()
60 | if err != nil {
61 | return nil, err
62 | }
63 | response.AccountAddress = nodeAccount.Address
64 |
65 | currentBlockNumber, err := ec.BlockNumber(context.Background())
66 | if err != nil {
67 | return nil, err
68 | }
69 |
70 | currentNonce, err := ec.NonceAt(context.Background(), nodeAccount.Address, big.NewInt(int64(currentBlockNumber)))
71 | if err != nil {
72 | return nil, err
73 | }
74 | pendingNonce, err := ec.PendingNonceAt(context.Background(), nodeAccount.Address)
75 | if err != nil {
76 | return nil, err
77 | }
78 |
79 | response.PendingNonce = big.NewInt(int64(pendingNonce))
80 | response.CurrentNonce = big.NewInt(int64(currentNonce))
81 | }
82 |
83 | // Return response
84 | return &response, nil
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/stader/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | export CGO_ENABLED=1
22 | cd /stader-node/stader
23 |
24 | #
25 | ## Build x64 version
26 | CGO_CFLAGS="-O -D__BLST_PORTABLE__" GOARCH=amd64 GOOS=linux go build -o stader-daemon-linux-amd64 stader.go
27 | #
28 | ## Build the arm64 version
29 | CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-cpp CGO_CFLAGS="-O -D__BLST_PORTABLE__" GOARCH=arm64 GOOS=linux go build -o stader-daemon-linux-arm64 stader.go
--------------------------------------------------------------------------------
/stader/ec_migrate multi.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 |
22 | EC_CHAINDATA_DIR=/ethclient
23 | EXTERNAL_DIR=/mnt/external
24 |
25 | # Get the core count
26 | CORE_COUNT=$(grep -c ^processor /proc/cpuinfo)
27 | if [ -z "$CORE_COUNT" ]; then
28 | CORE_COUNT=1
29 | elif [ "$CORE_COUNT" -lt 1 ]; then
30 | CORE_COUNT=1
31 | fi
32 |
33 | RSYNC_CMD="xargs -n1 -P${CORE_COUNT} -I% rsync -a --progress %"
34 |
35 | if [ "$EC_MIGRATE_MODE" = "export" ]; then
36 | ls $EC_CHAINDATA_DIR/* | $RSYNC_CMD $EXTERNAL_DIR
37 | elif [ "$EC_MIGRATE_MODE" = "import" ]; then
38 | rm -rf $EC_CHAINDATA_DIR/*
39 | ls $EXTERNAL_DIR/* | $RSYNC_CMD $EC_CHAINDATA_DIR
40 | else
41 | echo "Unknown migrate mode \"$EC_MIGRATE_MODE\""
42 | fi
--------------------------------------------------------------------------------
/stader/ec_migrate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | EC_CHAINDATA_DIR=/ethclient
22 | EXTERNAL_DIR=/mnt/external
23 |
24 | if [ "$OPERATION" = "size" ]; then
25 |
26 | if [ ! -d $EXTERNAL_DIR ]; then
27 | echo "Source path is not a directory." 1>&2
28 | exit 1
29 | else
30 | # Get the space used by the external directory
31 | DIR_SIZE=$(du -s -k $EXTERNAL_DIR | awk -F '\\s*' '{print $1}')
32 | if [ ! -z "$DIR_SIZE" ]; then
33 | # The size will be in KB because of Busybox, so turn it into bytes
34 | expr $DIR_SIZE \* 1024
35 | else
36 | echo "Failed to get source directory size." 1>&2
37 | exit 2
38 | fi
39 | fi
40 |
41 | else
42 |
43 | RSYNC_CMD="rsync -a --progress"
44 |
45 | if [ "$EC_MIGRATE_MODE" = "export" ]; then
46 | $RSYNC_CMD $EC_CHAINDATA_DIR/* $EXTERNAL_DIR
47 | elif [ "$EC_MIGRATE_MODE" = "import" ]; then
48 | rm -rf $EC_CHAINDATA_DIR/*
49 | $RSYNC_CMD $EXTERNAL_DIR/* $EC_CHAINDATA_DIR
50 | else
51 | echo "Unknown migrate mode \"$EC_MIGRATE_MODE\""
52 | fi
53 |
54 | fi
--------------------------------------------------------------------------------
/stader/guardian/collector/constants.go:
--------------------------------------------------------------------------------
1 | package collector
2 |
3 | const namespace = "stader"
4 |
5 | // Validator rewards & performance => stader_validator_rewards_performance + key
6 | const OperatorSub = "operator"
7 |
8 | const ActiveValidators = "active_validators" //GetAllActiveValidators _PermissionlessNodeRegistry
9 | const BeaconChainQueuedValidators = "beacon_chain_queued_validators" //BeaconChainQueuedValidators _PermissionlessNodeRegistry
10 | const StaderQueuedValidators = "stader_queued_validators"
11 | const SlashedValidators = "slashed_validators" //GetValidatorStatus
12 | const ExitingValidators = "exiting_validators" //GetValidatorStatus
13 | const WithdrawnValidators = "withdrawn_validators" //GetValidatorStatus
14 | const InitializedValidators = "initialized_validators" //GetValidatorStatus
15 | const InvalidSignatureValidators = "invalid_signature_validators" //GetValidatorStatus
16 | const FrontRunValidators = "front_run_validators" //GetValidatorStatus
17 | const FundsSettledValidators = "funds_settled_validators" //GetValidatorStatus
18 |
19 | const TotalETHBonded = "total_eth_bonded"
20 | const TotalSDBonded = "total_sd_bonded"
21 | const SdCollateral = "sd_collateral"
22 | const SdCollateralInEth = "sd_collateral_in_eth"
23 | const EthCollateral = "eth_collateral"
24 | const CumulativePenalty = "cumulative_penalty"
25 | const ClaimedSocializingPoolELRewards = "claimed_socializing_pool_el_rewards"
26 | const ClaimedSocializingPoolSDrewards = "claimed_socializing_pool_sd_rewards"
27 | const UnclaimedNonSocializingPoolELRewards = "unclaimed_non_socializing_pool_el_rewards"
28 | const UnclaimedSocializingPoolELRewards = "unclaimed_socializing_pool_el_rewards"
29 | const UnclaimedSocializingPoolSdRewards = "unclaimed_socializing_pool_sd_rewards"
30 | const UnclaimedCLRewards = "unclaimed_cl_rewards"
31 | const NextRewardCycleTime = "next_reward_cycle_time"
32 | const SDUtilized = "sd_utilized"
33 | const SDUtilizedInterest = "sd_utilized_interest"
34 | const SdCollateralPct = "sd_collateral_pct"
35 | const LockedEth = "eth_locked"
36 | const HeathFactor = "heath_factor"
37 | const TotalSDUtilizationPosition = "sd_utility_position"
38 | const TotalSDSelfBonded = "total_sd_self_bonded"
39 | const LiquidationStatus = "liquidation_status"
40 | const ClaimVaultBalance = "claim_vault_balance"
41 |
42 | // Node Health => stader_node_health+ key
43 | const NodeSub = "node_health"
44 | const CPUUsage = "cpu_usage"
45 | const CPUUsageTimeSeries = "cpu_usage_time_series"
46 | const RAMUsage = "ram_usage"
47 | const RAMUsageTimeSeries = "ram_usage_time_series"
48 | const DiskSpaceUsed = "disk_space_used"
49 | const SSDLatency = "ssd_latency"
50 | const TotalIO = "total_io"
51 | const IOWaiTTime = "io_wait_time"
52 | const NetworkUsage = "network_usage"
53 | const NetworkLatency = "network_latency"
54 | const ECPeers = "ec_peers"
55 | const NBCPeers = "nbc_peers"
56 |
--------------------------------------------------------------------------------
/stader/node/merkle-proofs-download.go:
--------------------------------------------------------------------------------
1 | package node
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "github.com/mitchellh/go-homedir"
7 | "github.com/stader-labs/stader-node/shared/services"
8 | "github.com/stader-labs/stader-node/shared/services/config"
9 | "github.com/stader-labs/stader-node/shared/services/wallet"
10 | "github.com/stader-labs/stader-node/shared/utils/log"
11 | "github.com/stader-labs/stader-node/shared/utils/stader"
12 | "github.com/urfave/cli"
13 | "os"
14 | )
15 |
16 | type MerkleProofsDownloader struct {
17 | c *cli.Context
18 | log log.ColorLogger
19 | cfg *config.StaderConfig
20 | w *wallet.Wallet
21 | }
22 |
23 | func NewMerkleProofsDownloader(c *cli.Context, logger log.ColorLogger) (*MerkleProofsDownloader, error) {
24 | cfg, err := services.GetConfig(c)
25 | if err != nil {
26 | return nil, err
27 | }
28 | w, err := services.GetWallet(c)
29 | if err != nil {
30 | return nil, err
31 | }
32 |
33 | return &MerkleProofsDownloader{
34 | c: c,
35 | log: logger,
36 | cfg: cfg,
37 | w: w,
38 | }, nil
39 | }
40 |
41 | func (m *MerkleProofsDownloader) run() error {
42 | // Wait for eth client to sync
43 | if err := services.WaitEthClientSynced(m.c, true); err != nil {
44 | return err
45 | }
46 |
47 | nodeAccount, err := m.w.GetNodeAccount()
48 | if err != nil {
49 | return err
50 | }
51 |
52 | allMerkleProofs, err := stader.GetAllMerkleProofsForOperator(m.c, nodeAccount.Address)
53 | if err != nil {
54 | return err
55 | }
56 |
57 | downloadedCycles := []int64{}
58 |
59 | for _, cycleMerkleProof := range allMerkleProofs {
60 | cycleMerkleProofFile := m.cfg.StaderNode.GetSpRewardCyclePath(cycleMerkleProof.Cycle, true)
61 | absolutePathOfProofFile, err := homedir.Expand(cycleMerkleProofFile)
62 | if err != nil {
63 | return err
64 | }
65 |
66 | _, err = os.Stat(cycleMerkleProofFile)
67 | if !os.IsNotExist(err) && err != nil {
68 | return err
69 | }
70 | if !os.IsNotExist(err) {
71 | m.log.Printlnf("Merkle proof for cycle %d already exists, skipping", cycleMerkleProof.Cycle)
72 | continue
73 | }
74 |
75 | m.log.Printlnf("Downloading merkle proof for cycle %d", cycleMerkleProof.Cycle)
76 | file, err := os.Create(absolutePathOfProofFile)
77 | if err != nil {
78 | return err
79 | }
80 |
81 | encoder := json.NewEncoder(file)
82 | err = encoder.Encode(cycleMerkleProof)
83 | if err != nil {
84 | return fmt.Errorf("error encoding JSON: %v", err)
85 | }
86 |
87 | downloadedCycles = append(downloadedCycles, cycleMerkleProof.Cycle)
88 | }
89 |
90 | if len(downloadedCycles) == 0 {
91 | m.log.Printlnf("No merkle proofs to download")
92 | return nil
93 | } else {
94 | m.log.Printlnf("Downloaded merkle proofs for cycles: %v", downloadedCycles)
95 | }
96 |
97 | return nil
98 | }
99 |
--------------------------------------------------------------------------------
/stader/prune_provision.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This work is licensed and released under GNU GPL v3 or any other later versions.
4 | # The full text of the license is below/ found at
5 |
6 | # (c) 2023 Rocket Pool Pty Ltd. Modified under GNU GPL v3. [1.5.0]
7 |
8 | # This program is free software: you can redistribute it and/or modify
9 | # it under the terms of the GNU General Public License as published by
10 | # the Free Software Foundation, either version 3 of the License, or
11 | # (at your option) any later version.
12 |
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with this program. If not, see .
20 |
21 | touch /ethclient/prune.lock
--------------------------------------------------------------------------------
/update-abis.sh:
--------------------------------------------------------------------------------
1 | # enter in stader-lib/contracts and throw and error if it fails
2 | echo "Updating ABIs..."
3 |
4 | cd ./stader-lib/contracts;
5 |
6 | abigen --abi ./../../abis/VaultFactory.abi.json --pkg contracts --type VaultFactory --out vault-factory.go;
7 | abigen --abi ./../../abis/ValidatorWithdrawVault.abi.json --pkg contracts --type ValidatorWithdrawVault --out validator-withdraw-vault.go;
8 | abigen --abi ./../../abis/StakePoolManager.abi.json --pkg contracts --type StakePoolManager --out stake-pool-manager.go;
9 | abigen --abi ./../../abis/StaderConfig.abi.json --pkg contracts --type StaderConfig --out stader-config.go;
10 | abigen --abi ./../../abis/SocializingPool.abi.json --pkg contracts --type SocializingPool --out socializing-pool.go;
11 | abigen --abi ./../../abis/PoolUtils.abi.json --pkg contracts --type PoolUtils --out pool-utils.go;
12 | abigen --abi ./../../abis/PermissionlessPool.abi.json --pkg contracts --type PermissionlessPool --out permissionless-pool.go;
13 | abigen --abi ./../../abis/PermissionlessNodeRegistry.abi.json --pkg contracts --type PermissionlessNodeRegistry --out permissionless-node-registry.go;
14 | abigen --abi ./../../abis/Penalty.abi.json --pkg contracts --type PenaltyTracker --out penalty.go;
15 | abigen --abi ./../../abis/NodeElRewardVault.abi.json --pkg contracts --type NodeElRewardVault --out node-el-reward-vault.go;
16 | abigen --abi ./../../abis/OperatorRewardsCollector.abi.json --pkg contracts --type OperatorRewardsCollector --out operator-rewards-collector.go;
17 | abigen --abi ./../../abis/SdCollateral.abi.json --pkg contracts --type SdCollateral --out sd-collateral.go;
18 | abigen --abi ./../../abis/SDUtilityPool.abi.json --pkg contracts --type SDUtilityPool --out sd-utility.go;
19 |
20 | cd ../..;
21 |
22 | echo "Done updating ABIs."
--------------------------------------------------------------------------------