From d707e6e584c4feffd7c1af6732778ad839be34b0 Mon Sep 17 00:00:00 2001 From: dappnodedev Date: Thu, 4 Jul 2024 15:59:00 +0200 Subject: [PATCH] Create generic nimbus package --- .github/CODEOWNERS | 1 + .github/workflows/auto_check.yml | 20 + .github/workflows/main.yml | 40 + .gitignore | 3 + DISCLAIMER.md | 92 + GETTING_STARTED.md | 5 + LICENSE | 201 + README.md | 9 + avatar.png | Bin 0 -> 2567 bytes beacon-chain/Dockerfile | 26 + beacon-chain/entrypoint.sh | 46 + beacon-chain/jwtsecret.hex | 1 + dappnode_package.json | 40 + docker-compose.yml | 36 + nimbus-grafana-dashboard.json | 3924 +++++++++++++++++ package_variants/gnosis/dappnode_package.json | 20 + package_variants/gnosis/docker-compose.yml | 14 + .../gnosis/prometheus-targets.json | 11 + .../holesky/dappnode_package.json | 20 + package_variants/holesky/docker-compose.yml | 14 + .../holesky/prometheus-targets.json | 11 + .../mainnet/dappnode_package.json | 20 + package_variants/mainnet/docker-compose.yml | 14 + .../mainnet/prometheus-targets.json | 11 + setup-wizard.yml | 33 + validator/Dockerfile | 18 + validator/auth-token | 1 + validator/entrypoint.sh | 36 + 28 files changed, 4667 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/auto_check.yml create mode 100644 .github/workflows/main.yml create mode 100644 .gitignore create mode 100644 DISCLAIMER.md create mode 100644 GETTING_STARTED.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 avatar.png create mode 100644 beacon-chain/Dockerfile create mode 100755 beacon-chain/entrypoint.sh create mode 100644 beacon-chain/jwtsecret.hex create mode 100644 dappnode_package.json create mode 100644 docker-compose.yml create mode 100644 nimbus-grafana-dashboard.json create mode 100644 package_variants/gnosis/dappnode_package.json create mode 100644 package_variants/gnosis/docker-compose.yml create mode 100644 package_variants/gnosis/prometheus-targets.json create mode 100644 package_variants/holesky/dappnode_package.json create mode 100644 package_variants/holesky/docker-compose.yml create mode 100644 package_variants/holesky/prometheus-targets.json create mode 100644 package_variants/mainnet/dappnode_package.json create mode 100644 package_variants/mainnet/docker-compose.yml create mode 100644 package_variants/mainnet/prometheus-targets.json create mode 100644 setup-wizard.yml create mode 100644 validator/Dockerfile create mode 100644 validator/auth-token create mode 100644 validator/entrypoint.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..1899643 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ + * @dappnode/package-mantainers diff --git a/.github/workflows/auto_check.yml b/.github/workflows/auto_check.yml new file mode 100644 index 0000000..23f2613 --- /dev/null +++ b/.github/workflows/auto_check.yml @@ -0,0 +1,20 @@ +name: Bump upstream version + +on: + schedule: + - cron: "00 */4 * * *" + push: + branches: + - "master" + - "main" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: npx @dappnode/dappnodesdk github-action bump-upstream + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PINATA_API_KEY: ${{ secrets.PINATA_API_KEY }} + PINATA_SECRET_API_KEY: ${{ secrets.PINATA_SECRET_API_KEY }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..30b8043 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,40 @@ +name: "Main" +on: + pull_request: + push: + branches: + - "master" + - "main" + - "v[0-9]+.[0-9]+.[0-9]+" + paths-ignore: + - "README.md" + +jobs: + build-test: + runs-on: ubuntu-latest + name: Build test + if: github.event_name != 'push' + steps: + - uses: actions/checkout@v4 + - run: npx @dappnode/dappnodesdk build --variant mainnet --skip_save + + # e2e-test: + # runs-on: mainnet + # needs: build-test + # if: github.event_name != 'push' + # name: End to end tests + # steps: + # - uses: actions/checkout@v3 + # - run: npx @dappnode/dappnodesdk@latest github-action test-end-to-end --errorLogsTimeout 120 --healthCheckUrl http://beacon-validator.nimbus.dappnode:4500/eth/v1/beacon/genesis --network mainnet --environmentByService="{\"beacon-validator\":{\"CHECKPOINT_SYNC_URL\":\"https://checkpoint-sync.dappnode.io\"}}" + + release: + name: Release + runs-on: ubuntu-latest + if: github.event_name == 'push' + steps: + - uses: actions/checkout@v4 + - name: Publish + run: npx @dappnode/dappnodesdk publish patch --dappnode_team_preset --all-variants + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEVELOPER_ADDRESS: "0xf35960302a07022aba880dffaec2fdd64d5bf1c1" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..12d2f54 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# DAppNodeSDK release directories +build_* +docker-compose-tmp.yml diff --git a/DISCLAIMER.md b/DISCLAIMER.md new file mode 100644 index 0000000..05509b5 --- /dev/null +++ b/DISCLAIMER.md @@ -0,0 +1,92 @@ +## Terms of Use - DAppNode + +Effective as of Oct 14, 2020 + +By downloading, accessing or using this DAppNode Package ("DNP"), you (referenced herein as “you” or the “user”) certify that you have read and agreed to the terms and conditions below (the “Terms”) which form a binding contract between you and DAppNode Association (referenced herein as “we” or “us”). If you do not agree to the Terms, do not download or use DAppNode. + +### About DAppNode + +DAppNode is Free Open Source Software ("FOSS") aimed at facilitating the use of decentralized technologies. DAppNode is developed by the DAppNode Association, a voluntary association with the purpose of empowering users to participate in decentralized networks and to help such networks become more resilient by promoting the deployment of more nodes. +The modular structure of the DAppNode FOSS allows for the wrapping of 3rd party software with the intention of facilitating its deployment. In no way we are responsible for the misuse of such software and in no way we warrant its functionalities. We accept no responsibiity for its errors, or for the errors that the wrapping process might have introduced. Any usage of DAppNode and a DNP is strictly at your own risk. + +### About this DNP + +This software is experimental, presented 'as is' and inherently carries risks. By installing it, you acknowledge that DAppNode Association has done its best to mitigate these risks and accept to waive any liability or responsibility for DAppNode Association in case of any shortage, discrepancy, damage, loss or destruction of any digital asset managed within this DAppNode package. + +This package stores private keys. Neither DAppNode Association nor the developers of this software can have access to your private keys, nor help you recover it if you lose them. + +You are solely responsible for keeping your private keys and password safe and to perform secure backups, as well as to restrict access to your computer and other equipment. To the extent permitted by applicable law, you agree to be responsible for all activities that have been conducted from your account. You must take all necessary steps to ensure that your private key, password, and recovery phrase remain confidential and secured. + +This is experimental open source software released under an GPLv3 license and may contain errors and/or bugs. No guarantee or representations whatsoever is made regarding its suitability (or its use) for any purpose or regarding its compliance with any applicable laws and regulations. Use of the software is at your own risk and discretion and by using the software you acknowledge that you have read this disclaimer, understand its contents, assume all risk related thereto and hereby release, waive, discharge and covenant not to sue DAppNode Association or any officers, employees or affiliates from and for any direct or indirect liability resulting from the use of the software as permissible by applicable laws and regulations. + +### Licensing Terms + +DAppNode FOSS is a fully open-source software program licensed pursuant to the GNU General Public License v3.0. + +The DAppNode name, the term “DAppNode” and all related names, logos, product and service names, designs and slogans are trademarks of DAppNode Association or its affiliates and/or licensors. You must not use such marks without our prior written permission. + +### Risks of Operating DAppNode + +The use of DAppNode and the 3rd party software included within its different DNPs can lead to loss of money. Blockchain technologies and in particular Ethereum are still experimental systems and ETH and other cryptocurrencies remain a risky investment. You alone are responsible for your actions on DAppNode including the security of your ETH and meeting any applicable minimum system requirements. + +Furthermore the Wider Crypto Industry including Ethereum is still nascesnt in most respects: Technologically it remains experimental and as such laws and regulations surrounding the industry are still developing, many of which contrast dramatically with the ideological values of much of the Ethereum community mainly related to censorhip. + +Use the 3rd party software included within its different DNPs might be subject to Terms and Conditions of the 3rd party. DAppNode association has done its best to include such Terms and Conditions, however we do not warrant the accuracy, completeness or usefulness of the 3rd party Terms and Conditions. Any reliance you place on such information is strictly at your own risk. We recommend consulting with the 3rd party responsible for the software for its most updated Terms and Conditions. + +We make no claims that DAppNode is appropriate or permitted for use in any specific jurisdiction. Access to DAppNode may not be legal by certain persons or in certain jurisdictions or countries. If you access DAppNode, you do so on your own initiative and are responsible for compliance with local laws. + +Some Internet plans will charge an additional amount for any excess upload bandwidth used that isn’t included in the plan and may terminate your connection without warning because of overuse. We advise that you check whether your Internet connection is subjected to such limitations and monitor your bandwidth use so that you can stop DAppNode before you reach your bandwidth limit. + +### OFAC + MEV-Boost + +One of the most contentious issues in Ethereum at the moment is related to a new technology known as Proposer-Builder Separation (PBS). So far, the primary implementation of this protocol is highly centralized to a single program called MEV-Boost, which is developed by Flashbots. This technology is designed to try to increase rewards for block proposers by finding the (MEV) Maximal Extractable Value. It is the profit a block proposer (miner or validator) can make through their ability to arbitrarily include, exclude, or re-order transactions from the blocks they propose. MEV-Boost accomplishes this by outsourcing the block building/transaction bundling duties of the validator to an external specialized builder running a builder relay(s). There are many builder relays availible from several different sources. The main differences between builder relays are primarily how they bundle these transactions, however the more important difference is whether or not the relay censors any transactions, by not includidng them in the block, regardless of the fee or tip the transaction is paying to be included in the block. This censorship is a legal and regulatory quandary that goes against the very ideological nature of Ethereum as a censorship resistent, free, open, and permissionless financial ecosystem. + +The censorship at the crux of this quandary is related to the Office of Foreign Asset Control (OFAC) which is one of the enforcement arms of the United States Treasury Department. OFAC has wide authority over financial transactions and is charged with monitoring and enforcing US financial sanctions against certain countries, organizations, and individuals. Penalties are strong for OFAC violations and the reach of OFAC extends far beyond US borders; according to OFAC's October 2021 "Sanctions Compliance Guidance for the Virtual Currency Industry", when asked "Who Must Comply with OFAC Sanctions?" the response is as follows: "All U.S. persons are required to comply with OFAC regulations. This includes all U.S. citizens and lawful permanent residents, +wherever located; all individuals and entities within the United States; and all entities organized under the laws of the United States or +any jurisdiction within the United States, including any foreign branches of those entities. Accordingly, anyone engaging in virtual currency +activities in the United States, or that involve U.S. individuals or entities, should be aware of OFAC sanctions requirements and the +circumstances in which they must comply with those requirements. +Depending on the authorities governing each sanctions program, others may also be required to adhere to OFAC sanctions requirements. +For example, OFAC’s Cuba, Iran, and North Korea sanctions programs extend sanctions prohibitions to certain foreign entities owned or +controlled by U.S. persons or U.S. financial institutions. Certain activities by non-U.S. persons that involve the United States, U.S. persons, +or goods or services exported from the United States may also be subject to OFAC sanctions regulations. +Additionally, in most sanctions programs, any transaction that causes a violation — including a transaction by a non-U.S. person that causes +a U.S. person to violate sanctions — is also prohibited. For certain sanctions programs, U.S. persons, wherever located, also are prohibited +from facilitating actions on behalf of non-U.S. persons if the activity would be prohibited by sanctions regulations if directly performed by a +U.S. person or within the United States. +**Strict Liability Regulations** +OFAC may impose civil penalties for sanctions violations generally based on a strict liability legal standard. This means that, in many cases, +a U.S. person may be held civilly liable for sanctions violations even without having knowledge or reason to know it was engaging in such +a violation. As a general matter, however, OFAC takes into consideration the totality of facts and circumstances surrounding an apparent +violation to determine the appropriate enforcement response. " + +As such, relay providers offer: + - Non-Compliant: relays that attempt to maximize the fees paid to the block proposer by using every possible strategy, including not filtering or censoring any transactions, even those that may be destined to or coming from an address that has been blacklisted by OFAC. + - Compliant: relays that attempt to maximize fees paid to the block proposor, but filter out and censor any transactions destined to or coming from an OFAC blacklisted address. + +Your use of DAppNode is subject to all applicable laws of any governmental authority You are subject to, including, without limitation, federal, state and foreign securities laws, tax laws, tariff and trade laws, ordinances, judgments, decrees, injunctions, writs and orders or like actions of any governmental authority and rules, regulations, orders, interpretations, licenses, and permits of any federal, regional, state, county, municipal or other governmental authority and you agree to comply with all such laws in Your use of DAppNode. You are solely responsible for determining what rules and regulations apply to Your personal actions that may arise as the result of using MEV-Boost and/or any relays that do not comply with OFAC. The owners of, or contributors to, DAppNode are not responsible for any unnanounced changes to the availability or reliability of any relays, nor determining the rules and regulations that apply to cryptocurrency transactions users may propose using the DAppNode Platform. DAppNode does not explicitly endorse the use of MEV-Boost or any paricular relay in any way; it is Your responsibility to determine what laws apply to You and abide by them. DAppNode will not be held liable for any of your choices or actions as a result of using DAppNode. Continued use of DAppNode constitutes Your understanding and agreement with these updated terms. + +### Warranty Disclaimer + +DAPPNODE IS PROVIDED ON AN “AS-IS” BASIS AND MAY INCLUDE ERRORS, OMISSIONS, OR OTHER INACCURACIES. DAPPNODE ASSOCIATION AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT DAPNODDE FOR ANY PURPOSE, AND HEREBY EXPRESSLY DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT OR ANY OTHER IMPLIED WARRANTY UNDER THE UNIFORM COMPUTER INFORMATION TRANSACTIONS ACT AS ENACTED BY ANY STATE. WE ALSO MAKE NO REPRESENTATIONS OR WARRANTIES THAT DAPPNODE WILL OPERATE ERROR-FREE, UNINTERRUPTED, OR IN A MANNER THAT WILL MEET YOUR REQUIREMENTS AND/OR NEEDS. THEREFORE, YOU ASSUME THE ENTIRE RISK REGARDING THE QUALITY AND/OR PERFORMANCE OF DAPPNODE AND ANY TRANSACTIONS ENTERED INTO THEREON. + +### Limitation of Liability + +In no event will DAppNode Association or any of its contributors be liable, whether in contract, warranty, tort (including negligence, whether active, passive or imputed), product liability, strict liability or other theory, breach of statutory duty or otherwise arising out of, or in connection with, your use of DAppNode, for any direct, indirect, incidental, special or consequential damages (including any loss of profits or data, business interruption or other pecuniary loss, or damage, loss or other compromise of data, in each case whether direct, indirect, incidental, special or consequential) arising out of the use of DAppNode, even if we or other users have been advised of the possibility of such damages. The foregoing limitations and disclaimers shall apply to the maximum extent permitted by applicable law, even if any remedy fails of its essential purpose. You acknowledge and agree that the limitations of liability afforded us hereunder constitute a material and actual inducement and condition to entering into these Terms, and are reasonable, fair and equitable in scope to protect our legitimate interests in light of the fact that we are not receiving consideration from you for providing DAppNode. + +### Indemnification + +To the maximum extent permitted by law, you will defend, indemnify and hold DAppNode and its contributors harmless from and against any and all claims, actions, suits, investigations, or proceedings by any third party (including any party or purported party to or beneficiary or purported beneficiary of any transaction on DAppNode), as well as any and all losses, liabilities, +damages, costs, and expenses (including reasonable attorneys’ fees) arising out of, accruing from, or in any way related to (i) your breach of the terms of this Agreement, (ii) any transaction, or the failure to occur of any transaction on DAppNode, and (iii) your negligence, fraud, or willful misconduct. + +### Compliance with Laws and Tax Obligations + +Your use of DAppNode is subject to all applicable laws of any governmental authority, including, without limitation, federal, state and foreign securities laws, tax laws, tariff and trade laws, ordinances, judgments, decrees, injunctions, writs and orders or like actions of any governmental authority and rules, regulations, orders, interpretations, licenses, and permits of any federal, regional, state, county, municipal or other governmental authority and you agree to comply with all such laws in your use of DAppNode. The users of DAppNode are solely responsible to determinate what, if any, taxes apply to their cryptocurrency transactions. The owners of, or contributors to, DAppNode are not responsible for determining the taxes that apply to cryptocurrency transactions. + +### Miscellaneous + +We reserve the right to revise these Terms, and your rights and obligations are at all times subject to the then-current Terms provided on DAppNode. Your continued use of DAppNode constitutes acceptance of such revised Terms. + +These Terms constitute the entire agreement between you and DAppNode Association regarding use of DAppNode FOSS and will supersede all prior agreements whether, written or oral. No usage of trade or other regular practice or method of dealing between the parties will be used to modify, interpret, supplement, or alter the terms of these Terms. + +If any portion of these Terms is held invalid or unenforceable, such invalidity or enforceability will not affect the other provisions of these Terms, which will remain in full force and effect, and the invalid or unenforceable portion will be given effect to the greatest extent possible. The failure of a party to require performance of any provision will not affect that party’s right to require performance at any time thereafter, nor will a waiver of any breach or default of these Terms or any provision of these Terms constitute a waiver of any subsequent breach or default or a waiver of the provision itself. diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md new file mode 100644 index 0000000..30ca750 --- /dev/null +++ b/GETTING_STARTED.md @@ -0,0 +1,5 @@ +## Welcome to the Merged Ethereum Mainnet Consensus Client: Nimbus + +- Your keystores should now managed in the [Staking Brain](http://brain.web3signer.dappnode) +- Don't have the Web3signer installed yet? It can be manually installed [here](http://my.dappnode/installer/my/web3signer.dnp.dappnode.eth) +- All Staking management now has a new home in the comprehensive [StakersUI](http://my.dappnode/stakers/ethereum) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6a88f9 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Nimbus Dappnode package + +**Nimbus ETH2.0 Beacon chain + validator** + +Nimbus is a client implementation for both the consensus layer (eth2) and execution layer (eth1) that strives to be as lightweight as possible in terms of resources used. This allows it to perform well on embedded systems, resource-restricted devices (including Raspberry Pis and mobile devices). + +However, resource-restricted hardware is not the only thing Nimbus is good for. Its low resource consumption makes it easy to run Nimbus together with other workloads on your server (this is especially valuable for stakers looking to lower the cost of their server instances). + +![avatar](avatar.png) diff --git a/avatar.png b/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..e66a1d83581269baee445628289b1f2aed37c746 GIT binary patch literal 2567 zcmdT_`8U+vAOBc7in2baL|W8SMl_mac~UY-ib6F)#xSTMJ6VhDYf2*-`y<8Bj2fP@ z6*H2NGIm19GFh@@U*6y8$M5%??;r5o^SbAK->>t2z3x5to^#*Pmy8Xz3GWm}5M-O- zIek+E;Y0nNn+14`ac-~yF90734BA;=1kx;KU( z-f9T)1CJnDPY^`bjq>)g4$o-f(gkxYuK-+Ke^^+6qa!#uRh>K6V`j#~Iv&4aYYRN! z@nB;EE-nxr4v~=%76$k4!`-_O6a;>L;O!0W?r{4ykVwBB?Cjv?O|Z9zxH$On17>Go zW(I!#gsCZ*n1Hb{7#@a!0qE|AmKI>Mp{54P%HYKdNJ|4RFSvIPzJG_gIcRN#2M=Ir z33y{;1J>4Ha1g4iAwM4y65!S?AP}IxpLcRtT!i&?7#{})10FwyJ9mIcgpm>W_z|+Q zATSUd9N^(Y=<0&JJn->>p&_7B!PggZa$t28I2=e!gn#~l&Q4fafzVKhjRh_j$Yh9! z0DpgIY61@rsH}wN&mk!ZzI_8XH<+J?_;~p81!`--*_n55P*4EBenECNOix2b2BfD$ zW+s%B0E-2alkoX7#Kb^(IRpnoX(`m#!_%j5;|44*!{{h3PBR0Mzj4GRlUTnumDLVG*Be-CwaP*nvq z8c-+@6$PH2P*DN7xeyWp&CSr*sH@6};k~!8m#MKCFCvK48SLEhrEd&D-kOhKWT21f zEA1lj5+N_ci&&wNt=oi^6!xDGqw^SkL;cg{ce*Eg<892YAa(9t_;;GMe8P6B?*z9p zui49PO}$rNpRCU`J+@W4U(xK)g-tfJV*=bO>P4tkgL2RFQEE+|z8@T?bgFgnqZz7> zi+%CwE^UYFwg-G@@Hp|xB9xLq)kGO2D5ogZKOTBg>+yDW)*^J)s!5YN@ip+hWO8QO zMO0hVCViA5flopt3U`XhzgI?_e(zsQeTlI(^wrs+>MihQ#yru1MH9Xnpp#LPGl(G> zov$RGtd3)Moixt+B5-Zj1yz)*9j9IS%Uq3~#v~8n?TxZdBx<{%ix<;g3Z< zjqbFar2%cCwk+Dt+PX9hCbH0{wX(m&(}l#Wk{&ryaO|58BTw$?>Yz}!M4xrXn|$S4 zEh`?f;ppw-#L3>>6YFl7@;7$kQ!yQ_KV78^J-H!7nW^QmQzcg2_*8b`BHqTsYNu`L z=&E((ABhy4!+NA{!u3(kR<_z<-9vP0o;7)A8)dD%U#KwuS|%s;k=z;b+jg?N@3;~N}XlN=@el3P$$hRa7Ei7CH)Wj z4cQHy^Qhq?!2>+glq0HhcY_F@I=U&iSlpbYFUtfq&%ltKTqMRn>8Wg)QjB6`EvSl+ zDZA)0?Qo^T^wqw0OH7-B}+(;#*ifzjdLq+EJ)G~>(gV!6%`ID}t(OgAwofJ*Vd6etG zt=Bd54C~sSTLot((h{W%>%s6Bn#2YbEAbc$Buu$GvBc;sq4HF&6=C^_-;{JtN#=!l0R^?#isPFu`(ay)T3= z()(f>owiW5aa>Rlqa2HqY0@1Pm{WMCk}Gszx7GPg?arp!(;RVSQJLwrOIVZ=b^Ene z&w;)4WEvsyyLPYLT-#AkdZTvfLt_!&B!5Dxn9RES6I={#q_$}JV_iNW!fuO&|EH=B zz0?FH`|;1E*3#+0w_NKk#-WVK*qJjpwf0v5v&Z$wlQ+r8k{yp=y&g2W^C0 zrHm|;P1gdgxUE=fXVylDT(7XnSpq9^o6maCovuZ}=y`vYv#&br!v&) z=xj^IjHOZfJB}E;W~5QJ6wj($+b1Sxl3t+|R55UMPVY6>t5!>+r(D3f$1^kDKz{YF zVSLsv{pO~R<)0OFQ&$#QjY+GoT1HM(nr-5SD+T7cohev-z(>Dk!>_pSvJJ^1q-^qn z^RAbZL;ItZrmgE=tnn>sBpwW}rFMRPc0douJ$(_{QkdS%7i7x6Cj3IWBp=1eCU4wk*Vj6 literal 0 HcmV?d00001 diff --git a/beacon-chain/Dockerfile b/beacon-chain/Dockerfile new file mode 100644 index 0000000..b4a2b7b --- /dev/null +++ b/beacon-chain/Dockerfile @@ -0,0 +1,26 @@ +ARG UPSTREAM_VERSION + +FROM statusim/nimbus-eth2:multiarch-${UPSTREAM_VERSION} + +ARG NETWORK +ARG STAKER_SCRIPTS_VERSION + +RUN apt-get update && apt-get install -y curl && apt-get clean + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +COPY jwtsecret.hex /jwtsecret + +ENV JWT_SECRET_FILE=/jwtsecret \ + NETWORK=${NETWORK} \ + VALIDATOR_PORT=3500 \ + NIMBUS_BIN="/home/user/nimbus_beacon_node" \ + DATA_DIR="/home/user/nimbus-eth2/build/data" \ + TOKEN_FILE="${DATA_DIR}/auth-token" \ + AUTH_TOKEN_PATH=${AUTH_TOKEN_PATH} \ + STAKER_SCRIPTS_URL=https://github.com/dappnode/staker-package-scripts/releases/download/${STAKER_SCRIPTS_VERSION} + +ADD ${STAKER_SCRIPTS_URL}/consensus_tools.sh /etc/profile.d/ + +RUN mkdir -p ${VALIDATORS_DIR} + +ENTRYPOINT [ "/usr/local/bin/entrypoint.sh" ] \ No newline at end of file diff --git a/beacon-chain/entrypoint.sh b/beacon-chain/entrypoint.sh new file mode 100755 index 0000000..c576eed --- /dev/null +++ b/beacon-chain/entrypoint.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +SUPPORTED_NETWORKS="gnosis holesky mainnet" +MEVBOOST_FLAGS="--payload-builder=true --payload-builder-url" + +handle_checkpoint() { + # Run checkpoint sync script if provided + if [ -n "${CHECKPOINT_SYNC_URL}" ]; then + echo "[INFO - entrypoint] Running checkpoint sync script" + + ${NIMBUS_BIN} trustedNodeSync \ + --network="${NETWORK}" \ + --trusted-node-url="${CHECKPOINT_SYNC_URL}" \ + --backfill=false \ + --data-dir="${DATA_DIR}" + else + echo "[WARN - entrypoint] No checkpoint sync script provided. Syncing from genesis." + fi +} + +run_beacon() { + echo "[INFO - entrypoint] Running beacon node service" + + # shellcheck disable=SC2086 + exec ${NIMBUS_BIN} \ + --network="${NETWORK}" \ + --data-dir="${DATA_DIR}" \ + --tcp-port="${P2P_PORT}" \ + --udp-port="${P2P_PORT}" \ + --log-level="${LOG_TYPE}" \ + --rest \ + --rest-port=3500 \ + --rest-address=0.0.0.0 \ + --metrics \ + --metrics-address=0.0.0.0 \ + --metrics-port=8008 \ + --jwt-secret=/jwtsecret \ + --web3-url="${ENGINE_API_URL}" \ + --suggested-fee-recipient="${FEE_RECIPIENT}" ${EXTRA_OPTS} +} + +format_graffiti +set_beacon_config_by_network "${SUPPORTED_NETWORKS}" +handle_checkpoint +set_mevboost_flag "${MEVBOOST_FLAGS}" # MEV-Boost: https://chainsafe.github.io/lodestar/usage/mev-integration/ +run_beacon diff --git a/beacon-chain/jwtsecret.hex b/beacon-chain/jwtsecret.hex new file mode 100644 index 0000000..53d2fa8 --- /dev/null +++ b/beacon-chain/jwtsecret.hex @@ -0,0 +1 @@ +7ad9cfdec75eceb662f5e48f5765701c17f51a5233a60fbcfa5f9e495fa99d17 \ No newline at end of file diff --git a/dappnode_package.json b/dappnode_package.json new file mode 100644 index 0000000..a488842 --- /dev/null +++ b/dappnode_package.json @@ -0,0 +1,40 @@ +{ + "upstream": [ + { + "repo": "status-im/nimbus-eth2", + "version": "v24.6.0", + "arg": "UPSTREAM_VERSION" + }, + { + "repo": "dappnode/staker-package-scripts", + "version": "v0.1.0", + "arg": "STAKER_SCRIPTS_VERSION" + } + ], + "architectures": ["linux/amd64"], + "shortDescription": "Nimbus ETH2.0 Beacon chain + validator", + "description": "Nimbus is a client implementation that strives to be as lightweight as possible in terms of resources used. This allows it to perform well on embedded systems, resource-restricted devices -- including Raspberry Pis and mobile devices -- and multi-purpose servers.", + "type": "service", + "author": "DAppNode Association (https://github.com/dappnode)", + "contributors": [ + "pablo (https://github.com/pablomendezroyo)", + "marce (https://github.com/mgarciate)" + ], + "license": "GPL-3.0", + "repository": { + "type": "git", + "url": "git+https://github.com/dappnode/DAppNodePackage-nimbus-generic.git" + }, + "bugs": { + "url": "https://github.com/dappnode/DAppNodePackage-nimbus-generic/issues" + }, + "categories": ["Blockchain", "ETH2.0"], + "chain": { + "driver": "ethereum-beacon-chain", + "serviceName": "beacon-chain", + "portNumber": 3500 + }, + "warnings": { + "onRemove": "Make sure your StakersUI does not have this client selected! Double check in the Stakers Tab in the left NavBar" + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7b72d86 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,36 @@ +version: "3.6" +services: + + beacon-chain: + build: + context: beacon-chain + args: + UPSTREAM_VERSION: v24.6.0 + STAKER_SCRIPTS_VERSION: v0.1.0 + environment: + LOG_TYPE: INFO + FEE_RECIPIENT: "" + CHECKPOINT_SYNC_URL: "" + EXTRA_OPTS: "" + volumes: + - nimbus-data:/home/user/nimbus-eth2/build/data + restart: unless-stopped + stop_grace_period: 1m + + validator: + build: + context: validator + args: + UPSTREAM_VERSION: v24.6.0 + STAKER_SCRIPTS_VERSION: v0.1.0 + environment: + LOG_TYPE: INFO + GRAFFITI: validating_from_DAppNode + FEE_RECIPIENT: "" + ENABLE_DOPPELGANGER: true + EXTRA_OPTS: "" + + restart: unless-stopped + stop_grace_period: 1m +volumes: + nimbus-data: {} diff --git a/nimbus-grafana-dashboard.json b/nimbus-grafana-dashboard.json new file mode 100644 index 0000000..7f67129 --- /dev/null +++ b/nimbus-grafana-dashboard.json @@ -0,0 +1,3924 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 16, + "links": [], + "panels": [ + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "#37872D", + "#37872D", + "#37872D" + ], + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 1, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 95, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "expr": "1", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "0,0", + "timeFrom": null, + "timeShift": null, + "title": "Validator Earnings", + "type": "singlestat", + "valueFontSize": "20%", + "valueMaps": [ + { + "op": "=", + "text": "", + "value": "null" + }, + { + "op": "=", + "text": "", + "value": "1" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "#F2495C", + "#F2495C", + "#F2495C" + ], + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 1, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 109, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "expr": "1", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Nimbus Client Status", + "type": "singlestat", + "valueFontSize": "20%", + "valueMaps": [ + { + "op": "=", + "text": "", + "value": "null" + }, + { + "op": "=", + "text": "", + "value": "1" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "#1F60C4", + "#1F60C4", + "#1F60C4" + ], + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 1, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 56, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "expr": "1", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Network Status", + "type": "singlestat", + "valueFontSize": "20%", + "valueMaps": [ + { + "op": "=", + "text": "", + "value": "null" + }, + { + "op": "=", + "text": "", + "value": "1" + } + ], + "valueName": "current" + }, + { + "datasource": null, + "description": "Sum of all validator balances.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 4, + "mappings": [], + "min": 0, + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ETH" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 94, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "attached_validator_balance_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}/1000000000", + "instant": true, + "interval": "", + "legendFormat": "vbal", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Validator Balance (ETH)", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": null, + "description": "Total ETH return on the initial effective stake of active local validators.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 4, + "mappings": [ + { + "id": 0, + "op": "=", + "text": "N/A", + "type": 1, + "value": "null" + } + ], + "nullValueMode": "connected", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#F2495C", + "value": null + }, + { + "color": "#F2CC0C", + "value": 0 + }, + { + "color": "#73BF69", + "value": 0.0001 + } + ] + }, + "unit": "ETH" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 52, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "fieldOptions": { + "calcs": [ + "lastNotNull" + ] + }, + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000-(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)*32)", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Earnings (ETH)", + "type": "stat" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Total percentage return on the initial effective stake of active local validators. Excess deposits will be reflected as earnings.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 6, + "y": 1 + }, + "id": 70, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "expr": "(sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000-(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)*32))/(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)*32) ", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Total Return", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "columns": [], + "datasource": null, + "description": "Validator balances by public key. ", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fontSize": "100%", + "gridPos": { + "h": 6, + "w": 3, + "x": 9, + "y": 1 + }, + "id": 54, + "interval": "", + "links": [], + "pageSize": null, + "pluginVersion": "6.5.1", + "showHeader": true, + "sort": { + "col": 4, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "job", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "public key", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "", + "linkUrl": "", + "pattern": "pubkey", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "instance", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "__name__", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "attested", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #A", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "aggregated", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #C", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "proposed", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #E", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "failed attestations", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #B", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "failed aggregations", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #D", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "balance", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 4, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "", + "linkUrl": "", + "mappingType": 1, + "pattern": "Value #F", + "thresholds": [ + "24", + "32" + ], + "type": "number", + "unit": "short" + }, + { + "alias": "pubkey", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": true, + "linkTooltip": "", + "linkUrl": "", + "mappingType": 1, + "pattern": "pubkey_short", + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "last inclusion distance", + "align": "auto", + "colorMode": null, + "colors": [ + "#F2495C", + "#FF9830", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #H", + "thresholds": [ + "" + ], + "type": "number", + "unit": "short" + }, + { + "alias": "status", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #J", + "thresholds": [], + "type": "string", + "unit": "none", + "valueMaps": [ + { + "text": "unknown", + "value": "0" + }, + { + "text": "deposited", + "value": "1" + }, + { + "text": "pending", + "value": "2" + }, + { + "text": "active", + "value": "3" + }, + { + "text": "exiting", + "value": "4" + }, + { + "text": "slashing", + "value": "5" + }, + { + "text": "exited", + "value": "6" + } + ] + } + ], + "targets": [ + { + "expr": "label_replace(max by(pubkey) (attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}/1000000000), \"pubkey_short\", \"$1\", \"pubkey\", \"(.{8}).*\") ", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "balance", + "refId": "F" + }, + { + "expr": "label_replace(max by(pubkey) (validator_balance{job=\"validator\"}), \"pubkey\", \"$1\", \"pubkey_short\", \"(.{8}).*\") ", + "interval": "", + "legendFormat": "", + "refId": "G" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Validator Balances", + "transform": "table", + "type": "table-old" + }, + { + "datasource": null, + "description": "Number of beacon nodes to which this node is connected.", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "min": 0, + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "orange", + "value": 10 + }, + { + "color": "yellow", + "value": 20 + }, + { + "color": "green", + "value": 30 + } + ] + }, + "unit": "peers" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 12, + "y": 1 + }, + "id": 98, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "libp2p_peers{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Peer Count", + "type": "stat" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorPrefix": false, + "colorValue": true, + "colors": [ + "#F2495C", + "rgba(237, 129, 40, 0.89)", + "#299c46" + ], + "datasource": null, + "decimals": 1, + "description": "The length of time the beacon chain process has been running", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "h", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 15, + "y": 1 + }, + "id": 45, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "(s)", + "postfixFontSize": "80%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "{instance=\"127.0.0.1:8008\", instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "targets": [ + { + "expr": "(time()-process_start_time_seconds{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/3600", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "48,96", + "timeFrom": null, + "timeShift": null, + "title": "Beacon Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "datasource": null, + "description": "Count of active validators.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "displayName": "", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 18, + "y": 1 + }, + "id": 71, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_active_validators{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} ", + "instant": true, + "interval": "", + "legendFormat": "active", + "refId": "C" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Validator Count", + "type": "stat" + }, + { + "datasource": null, + "description": "A metric expressing the distance between the current finalized epoch and the expected finalized epoch based on the genesis time. 100% means the expected and current finalized epochs are the same. The metric reaches 0% when the finalized epoch is 25 epochs behind the expected epoch.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "orange", + "value": 0.88 + }, + { + "color": "#EAB839", + "value": 0.92 + }, + { + "color": "green", + "value": 0.96 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 1 + }, + "id": 73, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "clamp_min((1-(4*((finalization_delay{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}-2)/100))),0)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Liveness", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "Sum of all validator balances multiplied by the price of ETH in USD.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 2, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "currencyUSD" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 4 + }, + "id": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "ethusd ", + "hide": false, + "instant": true, + "interval": "", + "legendFormat": "ethusd", + "refId": "A" + }, + { + "expr": "attached_validator_balance_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}/1000000000", + "hide": false, + "instant": true, + "interval": "", + "legendFormat": "balance", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Validator Balance (USD)", + "transformations": [ + { + "id": "calculateField", + "options": { + "alias": "total_validator_value", + "binary": { + "left": "ethusd", + "operator": "*", + "reducer": "sum", + "right": "balance" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true + } + } + ], + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": null, + "description": "Total earnings in USD.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 2, + "mappings": [ + { + "id": 0, + "op": "=", + "text": "N/A", + "type": 1, + "value": "null" + } + ], + "min": 0, + "nullValueMode": "connected", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "currencyUSD" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 3, + "y": 4 + }, + "id": 101, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "fieldOptions": { + "calcs": [ + "lastNotNull" + ] + }, + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000-(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)*32)", + "instant": true, + "interval": "", + "legendFormat": "total_balance", + "refId": "A" + }, + { + "expr": "ethusd", + "instant": true, + "interval": "", + "legendFormat": "ethusd", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Earnings (USD)", + "transformations": [ + { + "id": "calculateField", + "options": { + "alias": "Total Earnings (USD)", + "binary": { + "left": "total_balance", + "operator": "*", + "reducer": "sum", + "right": "ethusd" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true + } + } + ], + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": null, + "description": "Price of ETH in USD.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 2, + "mappings": [ + { + "id": 0, + "op": "=", + "text": "N/A", + "type": 1, + "value": "null" + } + ], + "min": 0, + "nullValueMode": "connected", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "currencyUSD" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 6, + "y": 4 + }, + "id": 102, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "fieldOptions": { + "calcs": [ + "lastNotNull" + ] + }, + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "ethusd", + "instant": true, + "interval": "", + "legendFormat": "ethusd", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "ETH Price (USD)", + "transformations": [ + { + "id": "calculateField", + "options": { + "alias": "Total Earnings (USD)", + "binary": { + "left": "total_balance", + "operator": "*", + "reducer": "sum", + "right": "ethusd" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true + } + } + ], + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "The number of peers to which the beacon chain is connected", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 4, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 4 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": true, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "libp2p_peers{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "interval": "", + "legendFormat": "peers", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Peers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Peers", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": null, + "description": "Justified, and finalized epochs. In this order, these two values should be sequentially decreasing.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(135, 135, 135)", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 18, + "y": 4 + }, + "id": 27, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_current_justified_epoch{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "justified", + "refId": "C" + }, + { + "expr": "beacon_finalized_epoch {instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} ", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "finalized", + "refId": "D" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Epochs", + "type": "stat" + }, + { + "datasource": null, + "description": "Current slot and head slot", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(135, 135, 135)", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 4 + }, + "id": 29, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_slot{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "current slot", + "refId": "A" + }, + { + "expr": "beacon_head_slot{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "head slot", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Slots", + "type": "stat" + }, + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "#8F3BB8", + "#8F3BB8", + "#8F3BB8" + ], + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 1, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 57, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "expr": "1", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "0,0", + "timeFrom": null, + "timeShift": null, + "title": "Earnings Rates", + "type": "singlestat", + "valueFontSize": "20%", + "valueMaps": [ + { + "op": "=", + "text": "", + "value": "null" + }, + { + "op": "=", + "text": "", + "value": "1" + } + ], + "valueName": "current" + }, + { + "aliasColors": { + "active validators": "rgba(239, 132, 60, 0.57)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "Number of pending and existing validators over time. Pending validators are shown as positive values, while exiting validators are shown as negative values.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 7 + }, + "hiddenSeries": false, + "id": 64, + "interval": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.7.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "exiting", + "transform": "negative-Y" + }, + { + "alias": "active validators", + "yaxis": 2 + }, + { + "alias": "slashing", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "beacon_pending_deposits{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "interval": "", + "legendFormat": "pending", + "refId": "B" + }, + { + "expr": "beacon_active_validators{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "interval": "", + "legendFormat": "active validators", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Validators", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": "validators", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Increase in all local validator balances over the last hour", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ETH", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 8 + }, + "id": 77, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "#5794F2", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000 - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1h != 0)/1000000000 - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1h > 16))", + "instant": false, + "interval": "", + "intervalFactor": 3, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Hourly Earnings", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#d44a3a", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Increase in all local validator balances over the last day", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ETH", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 3, + "y": 8 + }, + "id": 48, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000 - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1d != 0)/1000000000 - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1d > 16))", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Daily Earnings", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Increase in all local validator balances over the last week", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ETH", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 6, + "y": 8 + }, + "id": 49, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.3", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000 - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 7d != 0)/1000000000 - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 7d > 16))", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Weekly Earnings", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#299c46" + ], + "datasource": null, + "decimals": 4, + "description": "Increase in all local validator balances over the last month", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ETH", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 9, + "y": 8 + }, + "id": 50, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"})/1000000000 - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 30d != 0)/1000000000 - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 30d > 16))", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Monthly Earnings", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "datasource": null, + "description": "Total number of block proposals and attestations made by local validators since the last restart of the beacon chain.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 12, + "y": 10 + }, + "id": 103, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_blocks_proposed_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "proposals", + "refId": "B" + }, + { + "expr": "beacon_attestations_sent_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "interval": "", + "legendFormat": "attestations", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Validator Activity", + "type": "stat" + }, + { + "datasource": null, + "description": "Number of proposer and attester slashings received by the local beacon chain since the last restart of the beacon chain.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 15, + "y": 10 + }, + "id": 107, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_proposer_slashings_received_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "interval": "", + "legendFormat": "proposer", + "refId": "A" + }, + { + "expr": "beacon_attester_slashings_received_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "attester", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Slashings Received", + "type": "stat" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Percentage increase in all local validator balances over the last hour", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 11 + }, + "id": 82, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "annualized hourly return", + "targets": [ + { + "expr": "((sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}) - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1h != 0) - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1h > 16)))/(32 * avg_over_time(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)[1h:])))/1000000000 * 365 * 24", + "hide": false, + "interval": "", + "legendFormat": "annualized hourly return", + "refId": "B" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Hourly Return, Annualized", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Percentage increase in all local validator balances over the last day", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 3, + "y": 11 + }, + "id": 69, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "annualized daily return", + "targets": [ + { + "expr": "((sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}) - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1d != 0) - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 1d > 16)))/(32 * avg_over_time(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)[1d:])))/1000000000 * 365", + "hide": false, + "interval": "", + "legendFormat": "annualized daily return", + "refId": "B" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Daily Return, Annualized", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Percentage increase in all local validator balances over the last week", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 6, + "y": 11 + }, + "id": 83, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "annualized weekly return", + "targets": [ + { + "expr": "((sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}) - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 7d != 0) - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 7d > 16)))/(32 * avg_over_time(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)[7d:])))/1000000000 * (365/7)", + "hide": false, + "interval": "", + "legendFormat": "annualized weekly return", + "refId": "B" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Weekly Return, Annualized", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorPostfix": true, + "colorValue": true, + "colors": [ + "#F2495C", + "#FADE2A", + "#73BF69" + ], + "datasource": null, + "decimals": 4, + "description": "Percentage increase in all local validator balances over the last month", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 9, + "y": 11 + }, + "id": 84, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "pluginVersion": "6.7.2", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true, + "ymax": null, + "ymin": 0 + }, + "tableColumn": "", + "targets": [ + { + "expr": "((sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}) - sum(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 30d != 0) - (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)) + (32 * count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} offset 30d > 16)))/(32 * avg_over_time(count(attached_validator_balance{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"} > 16)[30d:])))/1000000000 * (365/30)", + "hide": false, + "interval": "", + "legendFormat": "annualized monthly return", + "refId": "B" + } + ], + "thresholds": "-0, 0.0001", + "timeFrom": null, + "timeShift": null, + "title": "Monthly Return, Annualized", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "datasource": null, + "description": "Number of voluntary exits received by the local beacon chain since the last restart of the beacon chain.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 12, + "y": 13 + }, + "id": 106, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_voluntary_exits_received_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "voluntary exits received", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Voluntary Exits Received", + "type": "stat" + }, + { + "datasource": null, + "description": "Number of failed web3 requests since the last restart of the beacon chain.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 0.0001 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 15, + "y": 13 + }, + "id": 108, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "failed_web3_requests_total{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "failed requests", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Failed web3 Requests", + "type": "stat" + }, + { + "datasource": null, + "description": "Current number of pending validators", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 18, + "y": 13 + }, + "id": 88, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "beacon_pending_deposits{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "instant": true, + "interval": "", + "legendFormat": "pending", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Pending Validator Queue", + "type": "stat" + }, + { + "datasource": null, + "description": "Estimated length of time until all pending validators have cleared the queue.", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "m" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 13 + }, + "id": 87, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.0", + "targets": [ + { + "expr": "((beacon_pending_deposits{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}/4)*6.4)", + "instant": true, + "interval": "", + "legendFormat": "pending", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Pending Queue Length", + "type": "stat" + }, + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "rgb(105, 70, 0)", + "rgb(105, 70, 0)", + "rgb(105, 70, 0)" + ], + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 58, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false, + "ymax": null, + "ymin": null + }, + "tableColumn": "", + "targets": [ + { + "expr": "1", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "0,0", + "timeFrom": null, + "timeShift": null, + "title": "Server", + "type": "singlestat", + "valueFontSize": "20%", + "valueMaps": [ + { + "op": "=", + "text": "", + "value": "null" + }, + { + "op": "=", + "text": "", + "value": "1" + } + ], + "valueName": "current" + }, + { + "aliasColors": { + "Free": "rgb(51, 51, 51)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "decimals": 2, + "description": "Beacon chain and validator memory usage on the server.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 17 + }, + "hiddenSeries": false, + "id": 99, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "beacon memory", + "fill": 0, + "fillGradient": 0, + "stack": false + }, + { + "alias": "validator memory", + "fill": 0, + "fillGradient": 0, + "stack": false + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "nim_gc_mem_occupied_bytes{instance=\"beacon-validator.nimbus.dappnode:8008\", job=\"manager_sd\", package=\"nimbus.dnp.dappnode.eth\", service=\"beacon-validator.nimbus.dappnode\"}", + "interval": "", + "intervalFactor": 1, + "legendFormat": "beacon memory", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Client Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "GB", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "idle": "rgb(51, 51, 51)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "decimals": 2, + "description": "Processor usage on the server", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 8, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 17 + }, + "hiddenSeries": false, + "id": 20, + "interval": "", + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": true, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"system\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"system\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "system", + "refId": "A" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"user\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"user\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "user", + "refId": "B" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"nice\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"nice\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "nice", + "refId": "C" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"iowait\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"iowait\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "iowait", + "refId": "D" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"steal\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"steal\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "steal", + "refId": "E" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"idle\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"idle\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "idle", + "refId": "F" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"irq\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"irq\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "irq", + "refId": "G" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"softirq\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"softirq\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "softirq", + "refId": "H" + }, + { + "expr": "sum(irate(node_cpu_seconds_total{mode=\"guest\",job=\"node_exporter\"}[5m])) or sum(irate(node_cpu{mode=\"guest\",job=\"node_exporter\"}[5m]))", + "interval": "", + "intervalFactor": 10, + "legendFormat": "guest", + "refId": "I" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": "%", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "Network transmission (tx) and reception (rx) rates", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 4, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 17 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_transmit_bytes_total{job=\"node_exporter\",device='enp1s0'}[5m])*8 or irate(node_network_transmit_bytes{job=\"node_exporter\",device='enp1s0'}[5m])*8 or irate(node_network_transmit_bytes_total{job=\"node_exporter\",device='eno1'}[5m])*8 or irate(node_network_transmit_bytes{job=\"node_exporter\",device='eno1'}[5m])*8", + "interval": "", + "intervalFactor": 5, + "legendFormat": "tx", + "refId": "A" + }, + { + "expr": "irate(node_network_receive_bytes_total{job=\"node_exporter\",device='enp1s0'}[5m])*8 or irate(node_network_receive_bytes{job=\"node_exporter\",device='enp1s0'}[5m])*8 or irate(node_network_receive_bytes_total{job=\"node_exporter\",device='eno1'}[5m])*8 or irate(node_network_receive_bytes{job=\"node_exporter\",device='eno1'}[5m])*8", + "interval": "", + "intervalFactor": 5, + "legendFormat": "rx", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "bps", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 17 + }, + "hiddenSeries": false, + "id": 92, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(node_filesystem_size_bytes{job=\"node_exporter\"})-sum(node_filesystem_avail_bytes{job=\"node_exporter\"}))/sum(node_filesystem_size_bytes{job=\"node_exporter\"})", + "interval": "", + "legendFormat": "disk usage", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": "0", + "show": true + }, + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Free": "rgb(51, 51, 51)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "decimals": 2, + "description": "Memory usage on the server", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 4, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 23 + }, + "hiddenSeries": false, + "id": 17, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "beacon memory", + "fill": 0, + "fillGradient": 0, + "stack": false + }, + { + "alias": "validator memory", + "fill": 0, + "fillGradient": 0, + "stack": false + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "( node_memory_MemTotal_bytes{job=\"node_exporter\"} - node_memory_MemFree_bytes{job=\"node_exporter\"} - node_memory_Buffers_bytes{job=\"node_exporter\"} - node_memory_Cached_bytes{job=\"node_exporter\"} - node_memory_SwapCached_bytes{job=\"node_exporter\"} - node_memory_Slab_bytes{job=\"node_exporter\"} - node_memory_PageTables_bytes{job=\"node_exporter\"} - node_memory_VmallocUsed_bytes{job=\"node_exporter\"} ) or ( node_memory_MemTotal{job=\"node_exporter\"} - node_memory_MemFree{job=\"node_exporter\"} - node_memory_Buffers{job=\"node_exporter\"} - node_memory_Cached{job=\"node_exporter\"} - node_memory_SwapCached{job=\"node_exporter\"} - node_memory_Slab{job=\"node_exporter\"} - node_memory_PageTables{job=\"node_exporter\"} - node_memory_VmallocUsed{job=\"node_exporter\"} )", + "interval": "", + "intervalFactor": 2, + "legendFormat": "apps", + "refId": "A" + }, + { + "expr": "node_memory_Buffers_bytes{job=\"node_exporter\"} or node_memory_Buffers{job=\"node_exporter\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "buffers", + "refId": "B" + }, + { + "expr": "node_memory_Cached_bytes{job=\"node_exporter\"} or node_memory_Cached{job=\"node_exporter\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "cached", + "refId": "C" + }, + { + "expr": "node_memory_MemFree_bytes{job=\"node_exporter\"} or node_memory_MemFree{job=\"node_exporter\"}", + "interval": "", + "legendFormat": "free", + "refId": "D" + }, + { + "expr": "node_memory_Slab_bytes{job=\"node_exporter\"} or node_memory_Slab{job=\"node_exporter\"}", + "interval": "", + "legendFormat": "slab", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Server Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "GB", + "logBase": 1, + "max": "16000000000", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 23 + }, + "hiddenSeries": false, + "id": 90, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_hwmon_temp_celsius{chip=\"platform_coretemp_0\",job=\"node_exporter\",sensor=\"temp1\"}", + "interval": "", + "intervalFactor": 1, + "legendFormat": "cpu temp", + "refId": "A" + } + ], + "thresholds": [ + { + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "yaxis": "left" + } + ], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Temp", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 4, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 23 + }, + "hiddenSeries": false, + "id": 81, + "legend": { + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "probe_duration_seconds{job=\"ping_google\"}", + "interval": "", + "intervalFactor": 10, + "legendFormat": "google", + "refId": "A" + }, + { + "expr": "probe_duration_seconds{job=\"ping_cloudflare\"}", + "interval": "", + "intervalFactor": 10, + "legendFormat": "cloudflare", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Ping", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "1m", + "schemaVersion": 25, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-2d", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Ethereum 2", + "version": 1 +} \ No newline at end of file diff --git a/package_variants/gnosis/dappnode_package.json b/package_variants/gnosis/dappnode_package.json new file mode 100644 index 0000000..7bd60dc --- /dev/null +++ b/package_variants/gnosis/dappnode_package.json @@ -0,0 +1,20 @@ +{ + "name": "nimbus-gnosis.dnp.dappnode.eth", + "version": "0.1.1", + "links": { + "ui": "http://brain.web3signer-gnosis.dappnode", + "homepage": "https://nimbus.team/", + "readme": "https://github.com/dappnode/DAppNodePackage-nimbus-generic", + "docs": "https://nimbus.guide" + }, + "globalEnvs": [ + { + "envs": ["EXECUTION_CLIENT_GNOSIS", "MEVBOOST_GNOSIS"], + "services": ["beacon-chain"] + }, + { + "envs": ["MEVBOOST_GNOSIS"], + "services": ["validator"] + } + ] +} diff --git a/package_variants/gnosis/docker-compose.yml b/package_variants/gnosis/docker-compose.yml new file mode 100644 index 0000000..ca6b6df --- /dev/null +++ b/package_variants/gnosis/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" +services: + beacon-chain: + build: + args: + NETWORK: gnosis + P2P_PORT: 9706 + ports: + - 9706:9706/tcp + - 9706:9706/udp + validator: + build: + args: + NETWORK: gnosis diff --git a/package_variants/gnosis/prometheus-targets.json b/package_variants/gnosis/prometheus-targets.json new file mode 100644 index 0000000..1921305 --- /dev/null +++ b/package_variants/gnosis/prometheus-targets.json @@ -0,0 +1,11 @@ +[ + { + "labels": { + "package": "nimbus-gnosis.dnp.dappnode.eth", + "service": "beacon-validator.nimbus-gnosis.dappnode" + }, + "targets": [ + "beacon-validator.nimbus-gnosis.dappnode:8008" + ] + } +] \ No newline at end of file diff --git a/package_variants/holesky/dappnode_package.json b/package_variants/holesky/dappnode_package.json new file mode 100644 index 0000000..9fe1c8e --- /dev/null +++ b/package_variants/holesky/dappnode_package.json @@ -0,0 +1,20 @@ +{ + "name": "nimbus-holesky.dnp.dappnode.eth", + "version": "0.1.2", + "links": { + "ui": "http://brain.web3signer-holesky.dappnode", + "homepage": "https://nimbus.team/", + "readme": "https://github.com/dappnode/DAppNodePackage-nimbus-generic", + "docs": "https://nimbus.guide" + }, + "globalEnvs": [ + { + "envs": ["EXECUTION_CLIENT_HOLESKY", "MEVBOOST_HOLESKY"], + "services": ["beacon-chain"] + }, + { + "envs": ["MEVBOOST_HOLESKY"], + "services": ["validator"] + } + ] +} diff --git a/package_variants/holesky/docker-compose.yml b/package_variants/holesky/docker-compose.yml new file mode 100644 index 0000000..adebb45 --- /dev/null +++ b/package_variants/holesky/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" +services: + beacon-chain: + build: + args: + NETWORK: holesky + P2P_PORT: 9606 + ports: + - 9606:9606/tcp + - 9606:9606/udp + validator: + build: + args: + NETWORK: holesky diff --git a/package_variants/holesky/prometheus-targets.json b/package_variants/holesky/prometheus-targets.json new file mode 100644 index 0000000..9278b03 --- /dev/null +++ b/package_variants/holesky/prometheus-targets.json @@ -0,0 +1,11 @@ +[ + { + "labels": { + "package": "nimbus-holesky.dnp.dappnode.eth", + "service": "beacon-validator.nimbus-holesky.dappnode" + }, + "targets": [ + "beacon-validator.nimbus-holesky.dappnode:8008" + ] + } +] \ No newline at end of file diff --git a/package_variants/mainnet/dappnode_package.json b/package_variants/mainnet/dappnode_package.json new file mode 100644 index 0000000..76aa2dd --- /dev/null +++ b/package_variants/mainnet/dappnode_package.json @@ -0,0 +1,20 @@ +{ + "name": "nimbus.dnp.dappnode.eth", + "version": "1.0.13", + "links": { + "ui": "http://brain.web3signer.dappnode", + "homepage": "https://nimbus.team/", + "readme": "https://github.com/dappnode/DAppNodePackage-nimbus-generic", + "docs": "https://nimbus.guide" + }, + "globalEnvs": [ + { + "envs": ["EXECUTION_CLIENT_MAINNET", "MEVBOOST_MAINNET"], + "services": ["beacon-chain"] + }, + { + "envs": ["MEVBOOST_MAINNET"], + "services": ["validator"] + } + ] +} diff --git a/package_variants/mainnet/docker-compose.yml b/package_variants/mainnet/docker-compose.yml new file mode 100644 index 0000000..e850f47 --- /dev/null +++ b/package_variants/mainnet/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" +services: + beacon-chain: + build: + args: + NETWORK: mainnet + P2P_PORT: 9106 + ports: + - 9106:9106/tcp + - 9106:9106/udp + validator: + build: + args: + NETWORK: mainnet diff --git a/package_variants/mainnet/prometheus-targets.json b/package_variants/mainnet/prometheus-targets.json new file mode 100644 index 0000000..ed9302b --- /dev/null +++ b/package_variants/mainnet/prometheus-targets.json @@ -0,0 +1,11 @@ +[ + { + "labels": { + "package": "nimbus.dnp.dappnode.eth", + "service": "beacon-validator.nimbus.dappnode" + }, + "targets": [ + "beacon-validator.nimbus.dappnode:8008" + ] + } +] \ No newline at end of file diff --git a/setup-wizard.yml b/setup-wizard.yml new file mode 100644 index 0000000..2eaea74 --- /dev/null +++ b/setup-wizard.yml @@ -0,0 +1,33 @@ +version: "2" +fields: + - id: GRAFFITI + target: + type: environment + name: GRAFFITI + service: validator + title: Graffiti + maxLength: 32 + description: >- + Add a string to your proposed blocks, which will be seen on the block explorer + - id: checkpointSyncUrl + target: + type: environment + name: CHECKPOINT_SYNC_URL + service: beacon-chain + title: Checkpoint for fast sync + description: >- + To get Nimbus up and running in only a few minutes, you can start Nimbus from a recent finalized checkpoint state rather than syncing from genesis. This is substantially **faster** and consumes **less resources** than syncing from genesis, while still providing all the same features. Be sure you are using a trusted node for the fast sync. Check the [Nimbus docs](https://nimbus.guide/trusted-node-sync.html) for more information. + Use the Dappnode Official endpoint `https://checkpoint-sync.dappnode.io` or get your checkpoint sync from [Infura](https://infura.io/) (i.e https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@eth2-beacon.infura.io) + *Note - If you are going to provide your own checkpoint sync endpoint, make sure you do not use a slash `/` at the end of the URL.* + required: false + - id: feeRecipientAddress + target: + type: environment + name: FEE_RECIPIENT + service: [beacon-chain, validator] + title: Fee Recipient Address + description: >- + Fee Recipient is a feature that lets you specify a priority fee recipient address on your validator client instance and beacon node. Make sure this is an address you control. After The Merge, Execution Clients will begin depositing priority fees into this address whenever your validator proposes a new block. + required: true + pattern: "^0x[a-fA-F0-9]{40}$" + patternErrorMessage: Must be a valid address (0x1fd16a...) diff --git a/validator/Dockerfile b/validator/Dockerfile new file mode 100644 index 0000000..2438985 --- /dev/null +++ b/validator/Dockerfile @@ -0,0 +1,18 @@ +ARG UPSTREAM_VERSION + +FROM statusim/nimbus-validator-client:multiarch-${UPSTREAM_VERSION} + +ARG NETWORK +ARG STAKER_SCRIPTS_VERSION +ARG AUTH_TOKEN_PATH=/security/auth-token + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +COPY auth-token ${AUTH_TOKEN_PATH} + +ENV NETWORK=${NETWORK} \ + AUTH_TOKEN_PATH=${AUTH_TOKEN_PATH} \ + STAKER_SCRIPTS_URL=https://github.com/dappnode/staker-package-scripts/releases/download/${STAKER_SCRIPTS_VERSION} + +ADD ${STAKER_SCRIPTS_URL}/consensus_tools.sh /etc/profile.d/ + +ENTRYPOINT [ "/usr/local/bin/entrypoint.sh" ] \ No newline at end of file diff --git a/validator/auth-token b/validator/auth-token new file mode 100644 index 0000000..5cffb27 --- /dev/null +++ b/validator/auth-token @@ -0,0 +1 @@ +eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.MxwOozSH-TLbW_XKepjyYDHm2IT8Ki0tD3AHuajfNMg \ No newline at end of file diff --git a/validator/entrypoint.sh b/validator/entrypoint.sh new file mode 100644 index 0000000..057a440 --- /dev/null +++ b/validator/entrypoint.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +SUPPORTED_NETWORKS="gnosis holesky mainnet" +MEVBOOST_FLAG="--payload-builder=true" +SKIP_MEVBOOST_URL="true" +CLIENT="nimbus" + +# shellcheck disable=SC1091 +. /etc/profile + +run_validator() { + echo "[INFO - entrypoint] Running validator service" + + # shellcheck disable=SC2086 + exec nimbus_validator_client \ + --log-level="${LOG_TYPE}" \ + --doppelganger-detection="${ENABLE_DOPPELGANGER}" \ + --non-interactive=true \ + --web3-signer-url="${WEB3SIGNER_API_URL}" \ + --suggested-fee-recipient="${FEE_RECIPIENT}" \ + --keymanager=true \ + --keymanager-port=3500 \ + --keymanager-address=0.0.0.0 \ + --keymanager-allow-origin=* \ + --keymanager-token-file="${AUTH_TOKEN_PATH}" \ + --metrics=true \ + --metrics-address=0.0.0.0 \ + --metrics-port=8008 \ + --graffiti="${GRAFFITI}" \ + --beacon-node="${BEACON_NODE_API_URL}" ${EXTRA_OPTS} +} + +format_graffiti +set_validator_config_by_network "${NETWORK}" "${SUPPORTED_NETWORKS}" "${CLIENT}" +set_mevboost_flag "${MEVBOOST_FLAG}" "${SKIP_MEVBOOST_URL}" # MEV-Boost: https://chainsafe.github.io/lodestar/usage/mev-integration/ +run_validator