From 49eb23dc88d80b25081fe71352888b2b73b536c8 Mon Sep 17 00:00:00 2001 From: NoahMaizels Date: Wed, 4 Dec 2024 17:07:57 +0000 Subject: [PATCH] deploy: c245e6d2f7d08e5b6c41b2440779cfbddf0e8070 --- 404.html | 2 +- api/index.html | 2 +- assets/js/5ee72a4b.260f5f47.js | 1 - assets/js/5ee72a4b.faa65b99.js | 1 + ...n.7e1ed731.js => runtime~main.2b756c69.js} | 2 +- awesome-list/index.html | 2 +- docs/bee/bee-faq/index.html | 2 +- .../installation/build-from-source/index.html | 2 +- docs/bee/installation/connectivity/index.html | 2 +- docs/bee/installation/docker/index.html | 2 +- .../installation/fund-your-node/index.html | 2 +- docs/bee/installation/hive/index.html | 2 +- docs/bee/installation/install/index.html | 2 +- docs/bee/installation/quick-start/index.html | 2 +- docs/bee/installation/verify/index.html | 2 +- docs/bee/working-with-bee/backups/index.html | 2 +- docs/bee/working-with-bee/bcrypt/index.html | 2 +- docs/bee/working-with-bee/bee-api/index.html | 2 +- .../working-with-bee/bee-dashboard/index.html | 2 +- .../working-with-bee/cashing-out/index.html | 2 +- .../working-with-bee/configuration/index.html | 2 +- .../working-with-bee/introduction/index.html | 2 +- .../working-with-bee/light-nodes/index.html | 2 +- .../logs-and-files/index.html | 2 +- .../working-with-bee/monitoring/index.html | 2 +- docs/bee/working-with-bee/staking/index.html | 46 ++++++++++++++++++- .../bee/working-with-bee/swarm-cli/index.html | 2 +- .../ultra-light-nodes/index.html | 2 +- .../uninstalling-bee/index.html | 2 +- .../working-with-bee/upgrading-bee/index.html | 2 +- docs/concepts/DISC/erasure-coding/index.html | 2 +- docs/concepts/DISC/index.html | 2 +- docs/concepts/DISC/kademlia/index.html | 2 +- docs/concepts/DISC/neighborhoods/index.html | 2 +- docs/concepts/access-control/index.html | 2 +- .../bandwidth-incentives/index.html | 2 +- docs/concepts/incentives/overview/index.html | 2 +- .../incentives/postage-stamps/index.html | 2 +- .../incentives/price-oracle/index.html | 2 +- .../incentives/redistribution-game/index.html | 2 +- docs/concepts/introduction/index.html | 2 +- docs/concepts/pss/index.html | 2 +- docs/concepts/what-is-swarm/index.html | 2 +- docs/desktop/access-content/index.html | 2 +- docs/desktop/backup-restore/index.html | 2 +- docs/desktop/configuration/index.html | 2 +- docs/desktop/install/index.html | 2 +- docs/desktop/introduction/index.html | 2 +- docs/desktop/postage-stamps/index.html | 2 +- docs/desktop/publish-a-website/index.html | 2 +- docs/desktop/start-a-blog/index.html | 2 +- docs/desktop/upload-content/index.html | 2 +- .../buy-a-stamp-batch/index.html | 2 +- .../erasure-coding/index.html | 2 +- .../host-your-website/index.html | 2 +- .../access-the-swarm/introduction/index.html | 2 +- .../access-the-swarm/pinning/index.html | 2 +- .../store-with-encryption/index.html | 2 +- .../access-the-swarm/syncing/index.html | 2 +- .../ultra-light-nodes/index.html | 2 +- .../upload-and-download/index.html | 2 +- .../contribute/introduction/index.html | 2 +- docs/develop/contribute/protocols/index.html | 2 +- docs/develop/introduction/index.html | 2 +- .../develop/tools-and-features/act/index.html | 2 +- .../bee-dev-mode/index.html | 2 +- .../tools-and-features/bee-js/index.html | 2 +- .../tools-and-features/chunk-types/index.html | 2 +- .../tools-and-features/feeds/index.html | 2 +- .../gateway-proxy/index.html | 2 +- .../introduction/index.html | 2 +- .../develop/tools-and-features/pss/index.html | 2 +- .../starting-a-test-network/index.html | 2 +- docs/references/awesome-list/index.html | 2 +- docs/references/community/index.html | 2 +- docs/references/fair-data-society/index.html | 2 +- docs/references/faq/index.html | 2 +- docs/references/glossary/index.html | 2 +- docs/references/smart-contracts/index.html | 2 +- docs/references/tokens/index.html | 2 +- index.html | 2 +- search/index.html | 2 +- 82 files changed, 124 insertions(+), 82 deletions(-) delete mode 100644 assets/js/5ee72a4b.260f5f47.js create mode 100644 assets/js/5ee72a4b.faa65b99.js rename assets/js/{runtime~main.7e1ed731.js => runtime~main.2b756c69.js} (76%) diff --git a/404.html b/404.html index 4ead658c..6b8cb845 100644 --- a/404.html +++ b/404.html @@ -10,7 +10,7 @@ - + diff --git a/api/index.html b/api/index.html index 1d153928..68f4aceb 100644 --- a/api/index.html +++ b/api/index.html @@ -10,7 +10,7 @@ - + diff --git a/assets/js/5ee72a4b.260f5f47.js b/assets/js/5ee72a4b.260f5f47.js deleted file mode 100644 index 796935d0..00000000 --- a/assets/js/5ee72a4b.260f5f47.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkbee_docs=self.webpackChunkbee_docs||[]).push([[1628],{17489:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var o=s(74848),t=s(28453);const i={title:"Staking",id:"staking"},r=void 0,a={id:"bee/working-with-bee/staking",title:"Staking",description:"In order to participate in the redistribution of xBZZ from uploaders to storers, storers must first deposit a non-refundable xBZZ stake with a smart contract. Then, they are going to be chosen for payout with a probability proportional to their stake in their neighborhood, as long as they can log storing the part of the content that they are supposed to be storing according to protocol rules.",source:"@site/docs/bee/working-with-bee/staking.md",sourceDirName:"bee/working-with-bee",slug:"/bee/working-with-bee/staking",permalink:"/docs/bee/working-with-bee/staking",draft:!1,unlisted:!1,editUrl:"https://github.com/ethersphere/docs.github.io/blob/master/docs/bee/working-with-bee/staking.md",tags:[],version:"current",frontMatter:{title:"Staking",id:"staking"},sidebar:"bee",previous:{title:"Swarm CLI",permalink:"/docs/bee/working-with-bee/swarm-cli"},next:{title:"Cashing Out",permalink:"/docs/bee/working-with-bee/cashing-out"}},d={},c=[{value:"Add stake",id:"add-stake",level:2},{value:"Check redistribution status",id:"check-redistribution-status",level:2},{value:"Partial Stake Withdrawals",id:"partial-stake-withdrawals",level:2},{value:"Check for withdrawable stake",id:"check-for-withdrawable-stake",level:3},{value:"Withdraw available stake",id:"withdraw-available-stake",level:3},{value:"Maximize rewards",id:"maximize-rewards",level:2},{value:"Neighborhood selection",id:"neighborhood-selection",level:3},{value:"Stake density",id:"stake-density",level:3},{value:"Neighborhood Hopping",id:"neighborhood-hopping",level:2},{value:"Checking neighborhood population",id:"checking-neighborhood-population",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Frozen node",id:"frozen-node",level:3},{value:"Check frozen status",id:"check-frozen-status",level:4},{value:"Diagnosing freezing issues",id:"diagnosing-freezing-issues",level:4},{value:"Repairing corrupt reserve",id:"repairing-corrupt-reserve",level:3},{value:"Node occupies unusually large space on disk",id:"node-occupies-unusually-large-space-on-disk",level:3},{value:"Node not participating in redistribution",id:"node-not-participating-in-redistribution",level:3},{value:"Run sampler process to benchmark performance",id:"run-sampler-process-to-benchmark-performance",level:4}];function h(e){const n={a:"a",admonition:"admonition",annotation:"annotation",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",math:"math",mdxAdmonitionTitle:"mdxAdmonitionTitle",mn:"mn",mo:"mo",mrow:"mrow",msup:"msup",mtext:"mtext",ol:"ol",p:"p",pre:"pre",semantics:"semantics",span:"span",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.p,{children:"In order to participate in the redistribution of xBZZ from uploaders to storers, storers must first deposit a non-refundable xBZZ stake with a smart contract. Then, they are going to be chosen for payout with a probability proportional to their stake in their neighborhood, as long as they can log storing the part of the content that they are supposed to be storing according to protocol rules."}),"\n",(0,o.jsx)(n.p,{children:"In order to participate in redistribution, storers need to do the following:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Join the network and download all the data that the protocol assigns to them. They can only participate if they are fully synchronised with the network."}),"\n",(0,o.jsx)(n.li,{children:"Deposit a stake with the staking contract. There is a minimum staking requirement, presently 10 xBZZ. It can change in the future."}),"\n",(0,o.jsx)(n.li,{children:"Stay online and fully synced, so that when a redistribution round comes, their node can check whether their neighborhood (nodes that are assigned the same content to store) has been selected and if so, they can perform a certain calculation (a random sampling) on their content and submit the result to the redistribution contract. This happens in two phases (commit and reveal), so that the nodes cannot know the results of others\u2019 calculations when committing to their own."}),"\n",(0,o.jsx)(n.li,{children:"Round length is estimated around 15 minutes (152 blocks to be precise), though it can be extended."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Amongst the nodes that agree with the correct result, one is chosen \u2014 with a probability in proportion to their stake \u2014 as the winner. The winner must execute an on-chain transaction claiming their reward, which is the entire pot of storage rent paid since the previous round, or even more, if the previous pot has not been claimed at that time."}),"\n",(0,o.jsx)(n.h2,{id:"add-stake",children:"Add stake"}),"\n",(0,o.jsx)(n.p,{children:"Bee has builtin endpoints for depositing the stake. Currently the minimum staking requirement is 10 xBZZ, so make sure that there is enough tokens in the node's wallet and you must have some native token as well for paying the gas."}),"\n",(0,o.jsxs)(n.p,{children:["Then you can run the following command to stake 10 xBZZ. The amount is given in PLUR which is the smallest denomination of xBZZ and ",(0,o.jsx)(n.code,{children:"1 xBZZ == 1e16 PLUR"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -X POST localhost:1633/stake/100000000000000000\n"})}),"\n",(0,o.jsx)(n.p,{children:"If the command executed successfully it returns a transaction hash that you can use to verify on a block explorer."}),"\n",(0,o.jsx)(n.p,{children:"It is possible to deposit more by repeatedly using the command above."}),"\n",(0,o.jsx)(n.p,{children:"You can also check the amount staked with the following command:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl localhost:1633/stake\n"})}),"\n",(0,o.jsx)(n.h2,{id:"check-redistribution-status",children:"Check redistribution status"}),"\n",(0,o.jsxs)(n.p,{children:["Use the ",(0,o.jsx)("a",{href:"/api/#tag/RedistributionState",target:"_blank",rel:"noopener noreferrer",children:"RedistributionState"})," endpoint of the API to get more information about the redistribution status of the node."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"minimumFunds": '})," - The minimum xDAI needed to play a single round of the redistribution game (the unit is 1e-18 xDAI)."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"hasSufficientFunds": '})," - Shows whether the node has enough xDAI balance to submit at least five storage incentives redistribution related transactions. If ",(0,o.jsx)(n.code,{children:"false"})," the node will not be permitted to participate in next round."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"isFrozen": '})," - Shows node frozen status."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"isFullySynced": '})," - Shows whether node's localstore has completed full historical syncing with all connected peers."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"phase": '})," - Current phase of ",(0,o.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"redistribution game"})," (",(0,o.jsx)(n.code,{children:"commit"}),", ",(0,o.jsx)(n.code,{children:"reveal"}),", or ",(0,o.jsx)(n.code,{children:"claim"}),")."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"round": '}),' - Current round of redistribution game. The round number is determined by dividing the current Gnosis Chain block height by the number of blocks in one round. One round takes 152 blocks, so using the "block" output from the example above we can confirm that the round number is 176319 (block 26800488 / 152 blocks = round 176319).']}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"lastWonRound": '})," - Number of round last won by this node."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"lastPlayedRound": '})," - Number of the last round where node's neighborhood was selected to participate in redistribution game."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"lastFrozenRound": '})," The number the round when node was last frozen."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"block": '})," - Gnosis block of the current redistribution game."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"reward": '})," - Record of total reward received in ",(0,o.jsx)(n.a,{href:"/docs/references/glossary#plur",children:"PLUR"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'"fees": '})," - Record of total spent in 1E-18 xDAI on all redistribution related transactions."]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["Nodes should not be shut down or updated in the middle of a round they are playing in as it may cause them to lose out on winnings or become frozen. To see if your node is playing the current round, check if ",(0,o.jsx)(n.code,{children:"lastPlayedRound"})," equals ",(0,o.jsx)(n.code,{children:"round"})," in the output from the ",(0,o.jsxs)(n.a,{href:"/api/#tag/RedistributionState/paths/~1redistributionstate/get",children:[(0,o.jsx)(n.code,{children:"/redistributionstate"})," endpoint"]}),"."]})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["If your node is not operating properly such as getting frozen or not participating in any rounds, see the ",(0,o.jsx)(n.a,{href:"#troubleshooting",children:"troubleshooting section"}),"."]})}),"\n",(0,o.jsx)(n.h2,{id:"partial-stake-withdrawals",children:"Partial Stake Withdrawals"}),"\n",(0,o.jsx)(n.p,{children:"In cases that the price of xBZZ rises so much that it is more than enough to act as collateral, a partial withdrawal will be allowed down to the minimum required stake:"}),"\n",(0,o.jsx)(n.h3,{id:"check-for-withdrawable-stake",children:"Check for withdrawable stake"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl http://localhost:1633/stake/withdrawable | jq\n"})}),"\n",(0,o.jsx)(n.p,{children:"If there is any stake available for withdrawal, the amount will be displayed in PLUR:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'{\n "withdrawableStake": "18411"\n}\n'})}),"\n",(0,o.jsx)(n.h3,{id:"withdraw-available-stake",children:"Withdraw available stake"}),"\n",(0,o.jsxs)(n.p,{children:["If there is any stake available for withdrawal, you can withdraw it using the ",(0,o.jsx)(n.code,{children:"DELETE"})," method on ",(0,o.jsx)(n.code,{children:"/stake/withdrawable"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -X DELETE http://localhost:1633/stake/withdrawable\n"})}),"\n",(0,o.jsx)(n.h2,{id:"maximize-rewards",children:"Maximize rewards"}),"\n",(0,o.jsxs)(n.p,{children:["There are two main factors which determine the chances for a staking node to win a reward \u2014 neighborhood selection and stake density. Both of these should be considered together before starting up a Bee node for the first time. See the ",(0,o.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"incentives page"})," for more context."]}),"\n",(0,o.jsx)(n.h3,{id:"neighborhood-selection",children:"Neighborhood selection"}),"\n",(0,o.jsxs)(n.p,{children:["By default when running a Bee node for the first time an overlay address will be generated and used to assign the node to a random ",(0,o.jsx)(n.a,{href:"/docs/concepts/DISC/neighborhoods",children:"neighborhood"}),". However, by using the ",(0,o.jsx)(n.code,{children:"target-neighborhood"})," config option, a specific neighborhood can be selected in which to generate the node's overlay address. This is an excellent tool for maximizing reward chances as generally speaking running in a less populated neighborhood will increase the chances of winning a reward. See the ",(0,o.jsx)(n.a,{href:"/docs/bee/installation/install#set-target-neighborhood-optional",children:"config section"})," on the installation page for more information on how to set a target neighborhood."]}),"\n",(0,o.jsx)(n.h3,{id:"stake-density",children:"Stake density"}),"\n",(0,o.jsx)(n.p,{children:"Stake density is defined as:"}),"\n",(0,o.jsx)(n.span,{className:"katex-display",children:(0,o.jsxs)(n.span,{className:"katex",children:[(0,o.jsx)(n.span,{className:"katex-mathml",children:(0,o.jsx)(n.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,o.jsxs)(n.semantics,{children:[(0,o.jsxs)(n.mrow,{children:[(0,o.jsx)(n.mtext,{children:"stake\xa0density"}),(0,o.jsx)(n.mo,{children:"="}),(0,o.jsx)(n.mtext,{children:"staked\xa0xBZZ"}),(0,o.jsx)(n.mo,{children:"\xd7"}),(0,o.jsxs)(n.msup,{children:[(0,o.jsx)(n.mn,{children:"2"}),(0,o.jsx)(n.mtext,{children:"storageDepth"})]})]}),(0,o.jsx)(n.annotation,{encoding:"application/x-tex",children:"\\text{stake density} = \\text{staked xBZZ} \\times {2}^\\text{storageDepth}"})]})})}),(0,o.jsxs)(n.span,{className:"katex-html","aria-hidden":"true",children:[(0,o.jsxs)(n.span,{className:"base",children:[(0,o.jsx)(n.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,o.jsx)(n.span,{className:"mord text",children:(0,o.jsx)(n.span,{className:"mord",children:"stake\xa0density"})}),(0,o.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,o.jsx)(n.span,{className:"mrel",children:"="}),(0,o.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,o.jsxs)(n.span,{className:"base",children:[(0,o.jsx)(n.span,{className:"strut",style:{height:"0.7778em",verticalAlign:"-0.0833em"}}),(0,o.jsx)(n.span,{className:"mord text",children:(0,o.jsx)(n.span,{className:"mord",children:"staked\xa0xBZZ"})}),(0,o.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,o.jsx)(n.span,{className:"mbin",children:"\xd7"}),(0,o.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,o.jsxs)(n.span,{className:"base",children:[(0,o.jsx)(n.span,{className:"strut",style:{height:"0.8991em"}}),(0,o.jsxs)(n.span,{className:"mord",children:[(0,o.jsx)(n.span,{className:"mord",children:(0,o.jsx)(n.span,{className:"mord",children:"2"})}),(0,o.jsx)(n.span,{className:"msupsub",children:(0,o.jsx)(n.span,{className:"vlist-t",children:(0,o.jsx)(n.span,{className:"vlist-r",children:(0,o.jsx)(n.span,{className:"vlist",style:{height:"0.8991em"},children:(0,o.jsxs)(n.span,{style:{top:"-3.113em",marginRight:"0.05em"},children:[(0,o.jsx)(n.span,{className:"pstrut",style:{height:"2.7em"}}),(0,o.jsx)(n.span,{className:"sizing reset-size6 size3 mtight",children:(0,o.jsx)(n.span,{className:"mord text mtight",children:(0,o.jsx)(n.span,{className:"mord mtight",children:"storageDepth"})})})]})})})})})]})]})]})]})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["To learn more about stake density and the mechanics of the incentives system, see the ",(0,o.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"incentives page"}),"."]})}),"\n",(0,o.jsx)(n.p,{children:"Stake density determines the weighted chances of nodes within a neighborhood of winning rewards. The chance of winning within a neighborhood corresponds to stake density. Stake density can be increased by depositing more xBZZ as stake (note that stake withdrawals are not currently possible, so any staked xBZZ is not currently recoverable)."}),"\n",(0,o.jsxs)(n.p,{children:["Generally speaking, the minimum required stake of 10 xBZZ is sufficient, and rewards can be better maximized by operating more nodes over a greater range of neighborhoods rather than increasing stake. However this may not be true for all node operators depending on how many different neighborhoods they operate nodes in, and it also may change as network dynamics continue to evolve (join the ",(0,o.jsx)(n.code,{children:"#node-operators"})," ",(0,o.jsx)(n.a,{href:"https://discord.com/channels/799027393297514537/811553590170353685",children:"Discord channel"})," to stay up to date with the latest discussions about staking and network dynamics)."]}),"\n",(0,o.jsx)(n.h2,{id:"neighborhood-hopping",children:"Neighborhood Hopping"}),"\n",(0,o.jsxs)(n.admonition,{type:"warning",children:[(0,o.jsx)(n.mdxAdmonitionTitle,{}),(0,o.jsx)(n.p,{children:"While you may update your neighborhood freely as you wish, it takes significant time for to fully sync chunks and become eligible for playing in the redistribution game, so it is not advised to hop too frequently."})]}),"\n",(0,o.jsxs)(n.p,{children:["You can use the option ",(0,o.jsx)(n.code,{children:"target-neighborhood"})," to switch your node over to a new neighborhood. You may wish to use this option if your node's neighborhood becomes overpopulated."]}),"\n",(0,o.jsx)(n.h3,{id:"checking-neighborhood-population",children:"Checking neighborhood population"}),"\n",(0,o.jsxs)(n.p,{children:["For a quick check of your node's neighborhood population, we can use the ",(0,o.jsx)(n.code,{children:"/status"})," endpoint:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'curl -s http://localhost:1633/status | jq\n{\n "peer": "e7b5c1aac67693268fdec98d097a8ccee1aabcf58e26c4512ea888256d0e6dff",\n "proximity": 0,\n "beeMode": "full",\n "reserveSize": 1055543,\n "reserveSizeWithinRadius": 1039749,\n "pullsyncRate": 42.67013868148148,\n "storageRadius": 11,\n "connectedPeers": 140,\n "neighborhoodSize": 6,\n "batchCommitment": 74463051776,\n "isReachable": false\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Here we can see that at the current ",(0,o.jsx)(n.code,{children:"storageRadius"})," of 11, our node is in a neighborhood with size 6 from the ",(0,o.jsx)(n.code,{children:"neighborhoodSize"})," value."]}),"\n",(0,o.jsxs)(n.p,{children:["Using the ",(0,o.jsx)(n.a,{href:"https://swarmscan.io/neighborhoods",children:"Swarmscan neighborhoods tool"})," we can see there are many neighborhoods with fewer nodes, so it would benefit us to move to less populated neighborhood:"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{src:s(81920).A+"",width:"2102",height:"1224"})}),"\n",(0,o.jsx)(n.p,{children:"While you might be tempted to simply pick one of these less populated neighborhoods, it is best practice to use the neighborhood suggester API instead, since it will help to prevent too many node operators rapidly moving to the same underpopulated neighborhoods, and also since the suggester takes a look at the next depth down to make sure that even in case of a neighborhood split, your node will end up in the smaller neighborhood."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -s https://api.swarmscan.io/v1/network/neighborhoods/suggestion\n"})}),"\n",(0,o.jsx)(n.p,{children:"Copy the binary number returned from the API:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'{"neighborhood":"01100011110"}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Use the binary number you just copied and set it as a string value for the ",(0,o.jsx)(n.code,{children:"target-neighborhood"})," option in your config."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'## bee.yaml\ntarget-neighborhood: "01100011110"\n'})}),"\n",(0,o.jsxs)(n.admonition,{type:"info",children:[(0,o.jsx)(n.mdxAdmonitionTitle,{}),(0,o.jsxs)(n.p,{children:["Depending on your setup, you may need change the ",(0,o.jsx)(n.code,{children:"target-neighborhood"})," option by updating your ",(0,o.jsx)(n.code,{children:"bee.yaml"})," file, adding the ",(0,o.jsx)(n.code,{children:"--target-neighborhood"})," command line flag, or edit a ",(0,o.jsx)(n.code,{children:".env"})," file, among several possible common options."]})]}),"\n",(0,o.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsxs)(n.p,{children:["In this section we cover several commonly seen issues encountered for staking nodes participating in the redistribution game. If you don't see your issue covered here or require additional guidance, check out the ",(0,o.jsx)(n.code,{children:"#node-operators"})," ",(0,o.jsx)(n.a,{href:"https://discord.com/channels/799027393297514537/811553590170353685",children:"Discord channel"})," where you will find support from other node operators and community members."]}),"\n",(0,o.jsx)(n.h3,{id:"frozen-node",children:"Frozen node"}),"\n",(0,o.jsxs)(n.p,{children:["A node will be frozen when the reserve commitment hash it submits in its ",(0,o.jsxs)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:[(0,o.jsx)(n.code,{children:"commit"})," transaction"]})," does not match the correct hash. The reserve commitment hash is used as proof that a node is storing the chunks it is responsible for. It will not be able to play in the redistribution game during the freezing period. See the ",(0,o.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"penalties"})," section for more information."]}),"\n",(0,o.jsx)(n.h4,{id:"check-frozen-status",children:"Check frozen status"}),"\n",(0,o.jsxs)(n.p,{children:["You can check your node's frozen status using the ",(0,o.jsx)(n.code,{children:"/redistributionstate"})," endpoint:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The relevant fields here are ",(0,o.jsx)(n.code,{children:"isFrozen"})," and ",(0,o.jsx)(n.code,{children:"lastFrozenRound"}),", which respectively indicate whether the node is currently frozen and the last round in which the node was frozen."]}),"\n",(0,o.jsx)(n.h4,{id:"diagnosing-freezing-issues",children:"Diagnosing freezing issues"}),"\n",(0,o.jsxs)(n.p,{children:["In order to diagnose the cause of freezing issues we must compare our own node's status to that of other nodes within the same neighborhood by comparing the results from our own node returned from the ",(0,o.jsx)(n.code,{children:"/status"})," endpoint to the other nodes in the same neighborhood which can be found from the ",(0,o.jsx)(n.code,{children:"/status/peers"})," endpoint."]}),"\n",(0,o.jsx)(n.p,{children:"First we check our own node's status:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:" curl -s localhost:1633/status | jq\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:' {\n "peer": "da7e5cc3ed9a46b6e7491d3bf738535d98112641380cbed2e9ddfe4cf4fc01c4",\n "proximity": 0,\n "beeMode": "full",\n "reserveSize": 3747532,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 183,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true \n }\n'})}),"\n",(0,o.jsx)(n.p,{children:"And next we will find the status for all the other nodes in the same neighborhood as our own."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:" curl -s localhost:1633/status/peers | jq\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"/status/peers"})," endpoint returns all the peers of our node, but we are only concerned with peers in the same neighborhood as our own node. Nodes whose ",(0,o.jsx)(n.code,{children:"proximity"})," value is equal to or greater than our own node's ",(0,o.jsx)(n.code,{children:"storageRadius"})," value all fall into the same neighborhood as our node, so the rest have been omitted in the example output below:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'{ \n ...\n {\n "peer": "da33f7a504a74094242d3e542475b49847d1d0f375e0c86bac1c9d7f0937acc0",\n "proximity": 9,\n "beeMode": "full",\n "reserveSize": 3782924,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 188,\n "neighborhoodSize": 11,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4b529cc1aedc62e31849cf7f8ab8c1866d9d86038b857d6cf2f590604387fe",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3719593,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 176,\n "neighborhoodSize": 11,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da5d39a5508fadf66c8665d5e51617f0e9e5fd501e429c38471b861f104c1504",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3777241,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 198,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4cb0d125bba638def55c0061b00d7c01ed4033fa193d6e53a67183c5488d73",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3849125,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 181,\n "neighborhoodSize": 13,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4b1cd5d15e061fdd474003b5602ab1cff939b4b9e30d60f8ff693141ede810",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3778452,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 183,\n "neighborhoodSize": 12,\n "batchCommitment": 133827002368,\n "isReachable": true\n },\n {\n "peer": "da49e6c6174e3410edad2e0f05d704bbc33e9996bc0ead310d55372677316593",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3779560,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 185,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4cdab480f323d5791d3ab8d22d99147f110841e44a8991a169f0ab1f47d8e5",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3778518,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 189,\n "neighborhoodSize": 11,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4ccec79bc34b502c802415b0008c4cee161faf3cee0f572bb019b117c89b2f",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3779003,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 179,\n "neighborhoodSize": 10,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da69d412b79358f84b7928d2f6b7ccdaf165a21313608e16edd317a5355ba250",\n "proximity": 11,\n "beeMode": "full",\n "reserveSize": 3712586,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 189,\n "neighborhoodSize": 12,\n "batchCommitment": 133827002368,\n "isReachable": true\n },\n {\n "peer": "da61967b1bd614a69e5e83f73cc98a63a70ebe20454ca9aafea6b57493e00a34",\n "proximity": 11,\n "beeMode": "full",\n "reserveSize": 3780190,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 182,\n "neighborhoodSize": 13,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da7b6a268637cfd6799a9923129347fc3d564496ea79aea119e89c09c5d9efed",\n "proximity": 13,\n "beeMode": "full",\n "reserveSize": 3721494,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 188,\n "neighborhoodSize": 14,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da7a974149543df1b459831286b42b302f22393a20e9b3dd9a7bb5a7aa5af263",\n "proximity": 13,\n "beeMode": "full",\n "reserveSize": 3852986,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 186,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true\n }\n]\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"Now that we have the status for our own node and all its neighborhood peers we can begin to diagnose the issue through a series of checks outlined below:"}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"If you are able to identify and fix a problem with your node from the checklist below, it's possible that your node's reserve has become corrupted. Therefore, after fixing the problem, stop your node, and repair your node according to the instructions in the section following the checklist."})}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Compare ",(0,o.jsx)(n.code,{children:"reserveSize"})," with peers"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"reserveSize"})," value is the number of chunks stored by a node in its reserve. The value for ",(0,o.jsx)(n.code,{children:"reserveSize"})," for a healthy node should be around +/- 1% the size of most other nodes in the neighborhood. In our example, for our node's ",(0,o.jsx)(n.code,{children:"reserveSize"})," of 3747532, it falls within that normal range. This does not guarantee our node has no missing or corrupted chunks, but it does indicate that it is generally storing the same chunks as its neighbors. If it falls outside this range, see the next section for instructions on repairing reserves."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Compare ",(0,o.jsx)(n.code,{children:"batchCommitment"})," with peers"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"batchCommitment"})," value shows how many chunks would be stored if all postage batches were fully utilised. It also represents whether the node has fully synced postage batch data from on-chain. If your node's ",(0,o.jsx)(n.code,{children:"batchCommitment"})," value falls below that of its peers in the same neighborhood, it could indicate an issue with your blockchain RPC endpoint that is preventing it from properly syncing on-chain data. If you are running your own node, check your setup to make sure it is functioning properly, or check with your provider if you are using a 3rd party service for your RPC endpoint."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Check ",(0,o.jsx)(n.code,{children:"pullsyncRate"})]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"pullsyncRate"})," value measures the speed at which a node is syncing chunks from its peers. Once a node is fully synced, ",(0,o.jsx)(n.code,{children:"pullsyncRate"})," should go to zero. If ",(0,o.jsx)(n.code,{children:"pullsyncRate"})," is above zero it indicates that your node is still syncing chunks, so you should wait until it goes to zero before doing any other checks. If ",(0,o.jsx)(n.code,{children:"pullsyncRate"})," is at zero but your node's ",(0,o.jsx)(n.code,{children:"reserveSize"})," does not match its peers, you should check whether your network connection and RPC endpoint are stable and functioning properly. A node should be fully synced after several hours at most."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Check most recent ",(0,o.jsx)(n.code,{children:"block"})," number"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"block"})," value returned from the ",(0,o.jsx)(n.code,{children:"/redistributionstate"})," endpoint shows the most recent block a node has synced. If this number is far behind the actual more recent block then it indicates an issue with your RPC endpoint or network. If you are running your own node, check your setup to make sure it is functioning properly, or check with your provider if you are using a 3rd party service for your RPC endpoint."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Check peer connectivity"}),"\n",(0,o.jsxs)(n.p,{children:["Compare the value of your node's ",(0,o.jsx)(n.code,{children:"neighborhoodSize"})," from the ",(0,o.jsx)(n.code,{children:"/status"})," endpoint and the ",(0,o.jsx)(n.code,{children:"neighborhoodSize"})," of its peers in the same neighborhood from the ",(0,o.jsx)(n.code,{children:"/status/peers"})," endpoint. The figure should be generally the same (although it may fluctuate slightly up or down at any one point in time). If your node's ",(0,o.jsx)(n.code,{children:"neighborhoodSize"})," value is significantly different and remains so over time then your node likely has a connectivity problem. Make sure to ",(0,o.jsx)(n.a,{href:"/docs/bee/installation/connectivity",children:"check your network environment"})," to ensure your node is able to communicate with the network."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"If no problems are identified during these checks it likely indicates that your node was frozen in error and there are no additional steps you need to take."}),"\n",(0,o.jsx)(n.h3,{id:"repairing-corrupt-reserve",children:"Repairing corrupt reserve"}),"\n",(0,o.jsxs)(n.p,{children:["If you have identified and fixed a problem causing your node to become frozen or have other reason to believe that your node's reserves are corrupted then you should repair your node's reserve using the ",(0,o.jsx)(n.code,{children:"db repair-reserve"})," command."]}),"\n",(0,o.jsx)(n.p,{children:"First stop your node, and then run the following command:"}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["Make sure to replace ",(0,o.jsx)(n.code,{children:"/home/bee/.bee"})," with your node\u2019s data directory if it differs from the one shown in the example. Make sure that the directory you specify is the root directory for your node\u2019s data files, not the localstore directory itself. This is the same directory specified using the ",(0,o.jsx)(n.code,{children:"data-dir"})," option in your node\u2019s ",(0,o.jsx)(n.a,{href:"/docs/bee/working-with-bee/configuration/",children:"configuration"}),"."]})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"bee db repair-reserve --data-dir=/home/bee/.bee\n"})}),"\n",(0,o.jsx)(n.p,{children:"After the command has finished running, you may restart your node."}),"\n",(0,o.jsx)(n.h3,{id:"node-occupies-unusually-large-space-on-disk",children:"Node occupies unusually large space on disk"}),"\n",(0,o.jsxs)(n.p,{children:["During normal operation of a Bee node, it should not take up more than ~30 GB of disk space. In the rare cases when the node's occupied disk space grows larger, you may need to use the compaction ",(0,o.jsx)(n.code,{children:"db compact"})," command."]}),"\n",(0,o.jsx)(n.admonition,{type:"danger",children:(0,o.jsx)(n.p,{children:"To prevent any data loss, operators should run the compaction on a copy of the localstore directory and, if successful, replace the original localstore with the compacted copy."})}),"\n",(0,o.jsxs)(n.p,{children:["The command is available as a sub-command under db as such (make sure to replace the value for ",(0,o.jsx)(n.code,{children:"--data-dir"})," with the correct path to your bee node's data folder if it differs from the path shown in the example):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"bee db compact --data-dir=/home/bee/.bee\n"})}),"\n",(0,o.jsx)(n.h3,{id:"node-not-participating-in-redistribution",children:"Node not participating in redistribution"}),"\n",(0,o.jsxs)(n.p,{children:["First check that the node is fully synced, is not frozen, and has sufficient funds to participate in staking. To check node sync status, call the ",(0,o.jsx)(n.code,{children:"redistributionstate"})," endpoint:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,o.jsx)(n.p,{children:"Response:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Confirm that ",(0,o.jsx)(n.code,{children:"hasSufficientFunds"})," is ",(0,o.jsx)(n.code,{children:"true"}),", and ",(0,o.jsx)(n.code,{children:"isFullySynced"})," is ",(0,o.jsx)(n.code,{children:"true"})," before moving to the next step. If ",(0,o.jsx)(n.code,{children:"hasSufficientFunds"})," if ",(0,o.jsx)(n.code,{children:"false"}),", make sure to add at least the amount of xDAI shown in ",(0,o.jsx)(n.code,{children:"minimumFunds"})," (unit of 1e-18 xDAI). If the node was recently installed and ",(0,o.jsx)(n.code,{children:"isFullySynced"})," is ",(0,o.jsx)(n.code,{children:"false"}),", wait for the node to fully sync before continuing. After confirming the node's status, continue to the next step."]}),"\n",(0,o.jsx)(n.h4,{id:"run-sampler-process-to-benchmark-performance",children:"Run sampler process to benchmark performance"}),"\n",(0,o.jsxs)(n.p,{children:["One of the most common issues affecting staking is the ",(0,o.jsx)(n.code,{children:"sampler"})," process failing. The sampler is a resource intensive process which is run by nodes which are selected to take part in redistribution. The process may fail or time out if the node's hardware specifications aren't high enough. To check a node's performance the ",(0,o.jsx)(n.code,{children:"/rchash/{depth}/{anchor_01}/{anchor_02}"})," endpoint of the API may be used. The ",(0,o.jsx)(n.code,{children:"anchor_01"})," and ",(0,o.jsx)(n.code,{children:"anchor_02"})," must be a hex string with an even number of digits. For simplicity, you can just use ",(0,o.jsx)(n.code,{children:"aaaa"})," for both anchors as we do in the example further down."]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"{anchor}"})," value can be set to any random hexadecimal string, while ",(0,o.jsx)(n.code,{children:"{depth}"})," should be set to the current depth."]}),"\n",(0,o.jsxs)(n.p,{children:["To get the current depth, call the ",(0,o.jsx)(n.code,{children:"/reservestate"})," endpoint"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo curl -sX GET http://localhost:1633/reservestate | jq\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Copy the ",(0,o.jsx)(n.code,{children:"storageRadius"})," value from the output (this represents the ACTUAL depth for your node, in other words, the depth to which your node is responsible for storing files. The ",(0,o.jsx)(n.code,{children:"radius"})," value is the hypothetical depth your node would be at if every postage batch was fully utilised.)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'{\n "radius": 15,\n "storageRadius": 10,\n "commitment": 128332464128\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"Call the endpoint like so:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo curl -sX GET http://localhost:1633/rchash/10/aaaa/aaaa | jq\n"})}),"\n",(0,o.jsx)(n.p,{children:"If the sampler runs successfully, you should see output like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'{\n "Sample": {\n "Items": [\n "000003dac2b2f75842e410474dfa4c1e6e0b9970d81b57b33564c5620667ba96",\n "00000baace30916f7445dbcc44d9b55cb699925acfbe157e4498c63bde834f40",\n "0000126f48fb1e99e471efc683565e4b245703c922b9956f89cbe09e1238e983",\n "000012db04a281b7cc0e6436a49bdc5b06ff85396fcb327330ca307e409d2a04",\n "000014f365b1a381dda85bbeabdd3040fb1395ca9e222e72a597f4cc76ecf6c2",\n "00001869a9216b3da6814a877fdbc31f156fc2e983b52bc68ffc6d3f3cc79af0",\n "0000198c0456230b555d5261091cf9206e75b4ad738495a60640b425ecdf408f",\n "00001a523bd1b688472c6ea5a3c87c697db64d54744829372ac808de8ec1d427"\n ],\n "Hash": "7f7d93c6235855fedc34e32c6b67253e27910ca4e3b8f2d942efcd758a6d8829"\n },\n "Time": "2m54.087909745s"\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["If the ",(0,o.jsx)(n.code,{children:"Time"})," value is higher than 6 minutes, then the hardware specifications for the node may need to be upgraded."]}),"\n",(0,o.jsxs)(n.p,{children:["If there is an evictions related error such as the one below, try running the call to the ",(0,o.jsx)(n.code,{children:"/rchash/"})," endpoint again."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'error: "level"="error" "logger"="node/storageincentives" "msg"="make sample" "error"="sampler: failed creating sample: sampler stopped due to ongoing evictions"\n'})}),"\n",(0,o.jsx)(n.p,{children:"While evictions are a normal part of Bee's standard operation, the event of an eviction will interrupt the sampler process."}),"\n",(0,o.jsxs)(n.p,{children:["If you are still experiencing problems, you can find more help in the ",(0,o.jsx)(n.a,{href:"https://discord.gg/kHRyMNpw7t",children:"node-operators"})," Discord channel (for your safety, do not accept advice from anyone sending a private message on Discord)."]})]})}function l(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},81920:(e,n,s)=>{s.d(n,{A:()=>o});const o=s.p+"assets/images/staking-swarmscan-7a08f2c5be1d57dbe9c9b64f8fb3c608.png"},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var o=s(96540);const t={},i=o.createContext(t);function r(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5ee72a4b.faa65b99.js b/assets/js/5ee72a4b.faa65b99.js new file mode 100644 index 00000000..c3414f1d --- /dev/null +++ b/assets/js/5ee72a4b.faa65b99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkbee_docs=self.webpackChunkbee_docs||[]).push([[1628],{17489:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>h});var t=s(74848),o=s(28453);const i={title:"Staking",id:"staking"},r=void 0,a={id:"bee/working-with-bee/staking",title:"Staking",description:"In order to participate in the redistribution of xBZZ from uploaders to storers, storers must first deposit a non-refundable xBZZ stake with a smart contract. Then, they are going to be chosen for payout with a probability proportional to their stake in their neighborhood, as long as they can log storing the part of the content that they are supposed to be storing according to protocol rules.",source:"@site/docs/bee/working-with-bee/staking.md",sourceDirName:"bee/working-with-bee",slug:"/bee/working-with-bee/staking",permalink:"/docs/bee/working-with-bee/staking",draft:!1,unlisted:!1,editUrl:"https://github.com/ethersphere/docs.github.io/blob/master/docs/bee/working-with-bee/staking.md",tags:[],version:"current",frontMatter:{title:"Staking",id:"staking"},sidebar:"bee",previous:{title:"Swarm CLI",permalink:"/docs/bee/working-with-bee/swarm-cli"},next:{title:"Cashing Out",permalink:"/docs/bee/working-with-bee/cashing-out"}},d={},h=[{value:"Add stake",id:"add-stake",level:2},{value:"Check redistribution status",id:"check-redistribution-status",level:2},{value:"Partial Stake Withdrawals",id:"partial-stake-withdrawals",level:2},{value:"Check for withdrawable stake",id:"check-for-withdrawable-stake",level:3},{value:"Withdraw available stake",id:"withdraw-available-stake",level:3},{value:"Reserve Doubling",id:"reserve-doubling",level:2},{value:"Step by Step Guide",id:"step-by-step-guide",level:3},{value:"Step 1: Stake at least 20 xBZZ",id:"step-1-stake-at-least-20-xbzz",level:4},{value:"Step 2: Set reserve-capacity-doubling to 1.",id:"step-2-set-reserve-capacity-doubling-to-1",level:4},{value:"Step 3: Restart node",id:"step-3-restart-node",level:4},{value:"Reserve Doubling Reversing & Withdrawable Stake",id:"reserve-doubling-reversing--withdrawable-stake",level:3},{value:"How to free up withdrawable stake from a node with >= 20 xBZZ stake that currently has zero withdrawable stake:",id:"how-to-free-up-withdrawable-stake-from-a-node-with--20-xbzz-stake-that-currently-has-zero-withdrawable-stake",level:4},{value:"Maximize rewards",id:"maximize-rewards",level:2},{value:"Neighborhood selection",id:"neighborhood-selection",level:3},{value:"Stake density",id:"stake-density",level:3},{value:"Neighborhood Hopping",id:"neighborhood-hopping",level:2},{value:"Checking neighborhood population",id:"checking-neighborhood-population",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Frozen node",id:"frozen-node",level:3},{value:"Check frozen status",id:"check-frozen-status",level:4},{value:"Diagnosing freezing issues",id:"diagnosing-freezing-issues",level:4},{value:"Repairing corrupt reserve",id:"repairing-corrupt-reserve",level:3},{value:"Node occupies unusually large space on disk",id:"node-occupies-unusually-large-space-on-disk",level:3},{value:"Node not participating in redistribution",id:"node-not-participating-in-redistribution",level:3},{value:"Run sampler process to benchmark performance",id:"run-sampler-process-to-benchmark-performance",level:4}];function c(e){const n={a:"a",admonition:"admonition",annotation:"annotation",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",math:"math",mdxAdmonitionTitle:"mdxAdmonitionTitle",mn:"mn",mo:"mo",mrow:"mrow",msup:"msup",mtext:"mtext",ol:"ol",p:"p",pre:"pre",semantics:"semantics",span:"span",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"In order to participate in the redistribution of xBZZ from uploaders to storers, storers must first deposit a non-refundable xBZZ stake with a smart contract. Then, they are going to be chosen for payout with a probability proportional to their stake in their neighborhood, as long as they can log storing the part of the content that they are supposed to be storing according to protocol rules."}),"\n",(0,t.jsx)(n.p,{children:"In order to participate in redistribution, storers need to do the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Join the network and download all the data that the protocol assigns to them. They can only participate if they are fully synchronised with the network."}),"\n",(0,t.jsx)(n.li,{children:"Deposit a stake with the staking contract. There is a minimum staking requirement, presently 10 xBZZ. It can change in the future."}),"\n",(0,t.jsx)(n.li,{children:"Stay online and fully synced, so that when a redistribution round comes, their node can check whether their neighborhood (nodes that are assigned the same content to store) has been selected and if so, they can perform a certain calculation (a random sampling) on their content and submit the result to the redistribution contract. This happens in two phases (commit and reveal), so that the nodes cannot know the results of others\u2019 calculations when committing to their own."}),"\n",(0,t.jsx)(n.li,{children:"Round length is estimated around 15 minutes (152 blocks to be precise), though it can be extended."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Amongst the nodes that agree with the correct result, one is chosen \u2014 with a probability in proportion to their stake \u2014 as the winner. The winner must execute an on-chain transaction claiming their reward, which is the entire pot of storage rent paid since the previous round, or even more, if the previous pot has not been claimed at that time."}),"\n",(0,t.jsx)(n.h2,{id:"add-stake",children:"Add stake"}),"\n",(0,t.jsx)(n.p,{children:"Bee has builtin endpoints for depositing the stake. Currently the minimum staking requirement is 10 xBZZ, so make sure that there is enough tokens in the node's wallet and you must have some native token as well for paying the gas."}),"\n",(0,t.jsxs)(n.p,{children:["Then you can run the following command to stake 10 xBZZ. The amount is given in PLUR which is the smallest denomination of xBZZ and ",(0,t.jsx)(n.code,{children:"1 xBZZ == 1e16 PLUR"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X POST localhost:1633/stake/100000000000000000\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the command executed successfully it returns a transaction hash that you can use to verify on a block explorer."}),"\n",(0,t.jsx)(n.p,{children:"It is possible to deposit more by repeatedly using the command above."}),"\n",(0,t.jsx)(n.p,{children:"You can also check the amount staked with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl localhost:1633/stake\n"})}),"\n",(0,t.jsx)(n.h2,{id:"check-redistribution-status",children:"Check redistribution status"}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)("a",{href:"/api/#tag/RedistributionState",target:"_blank",rel:"noopener noreferrer",children:"RedistributionState"})," endpoint of the API to get more information about the redistribution status of the node."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"minimumFunds": '})," - The minimum xDAI needed to play a single round of the redistribution game (the unit is 1e-18 xDAI)."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"hasSufficientFunds": '})," - Shows whether the node has enough xDAI balance to submit at least five storage incentives redistribution related transactions. If ",(0,t.jsx)(n.code,{children:"false"})," the node will not be permitted to participate in next round."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"isFrozen": '})," - Shows node frozen status."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"isFullySynced": '})," - Shows whether node's localstore has completed full historical syncing with all connected peers."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"phase": '})," - Current phase of ",(0,t.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"redistribution game"})," (",(0,t.jsx)(n.code,{children:"commit"}),", ",(0,t.jsx)(n.code,{children:"reveal"}),", or ",(0,t.jsx)(n.code,{children:"claim"}),")."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"round": '}),' - Current round of redistribution game. The round number is determined by dividing the current Gnosis Chain block height by the number of blocks in one round. One round takes 152 blocks, so using the "block" output from the example above we can confirm that the round number is 176319 (block 26800488 / 152 blocks = round 176319).']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"lastWonRound": '})," - Number of round last won by this node."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"lastPlayedRound": '})," - Number of the last round where node's neighborhood was selected to participate in redistribution game."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"lastFrozenRound": '})," The number the round when node was last frozen."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"block": '})," - Gnosis block of the current redistribution game."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"reward": '})," - Record of total reward received in ",(0,t.jsx)(n.a,{href:"/docs/references/glossary#plur",children:"PLUR"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"fees": '})," - Record of total spent in 1E-18 xDAI on all redistribution related transactions."]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:["Nodes should not be shut down or updated in the middle of a round they are playing in as it may cause them to lose out on winnings or become frozen. To see if your node is playing the current round, check if ",(0,t.jsx)(n.code,{children:"lastPlayedRound"})," equals ",(0,t.jsx)(n.code,{children:"round"})," in the output from the ",(0,t.jsxs)(n.a,{href:"/api/#tag/RedistributionState/paths/~1redistributionstate/get",children:[(0,t.jsx)(n.code,{children:"/redistributionstate"})," endpoint"]}),"."]})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["If your node is not operating properly such as getting frozen or not participating in any rounds, see the ",(0,t.jsx)(n.a,{href:"#troubleshooting",children:"troubleshooting section"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"partial-stake-withdrawals",children:"Partial Stake Withdrawals"}),"\n",(0,t.jsx)(n.p,{children:"In cases that the price of xBZZ rises so much that it is more than enough to act as collateral, a partial withdrawal will be allowed down to the minimum required stake:"}),"\n",(0,t.jsx)(n.h3,{id:"check-for-withdrawable-stake",children:"Check for withdrawable stake"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl http://localhost:1633/stake/withdrawable | jq\n"})}),"\n",(0,t.jsx)(n.p,{children:"If there is any stake available for withdrawal, the amount will be displayed in PLUR:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "withdrawableStake": "18411"\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"withdraw-available-stake",children:"Withdraw available stake"}),"\n",(0,t.jsxs)(n.p,{children:["If there is any stake available for withdrawal, you can withdraw it using the ",(0,t.jsx)(n.code,{children:"DELETE"})," method on ",(0,t.jsx)(n.code,{children:"/stake/withdrawable"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X DELETE http://localhost:1633/stake/withdrawable\n"})}),"\n",(0,t.jsx)(n.h2,{id:"reserve-doubling",children:"Reserve Doubling"}),"\n",(0,t.jsx)(n.p,{children:'The reserve doubling feature enables nodes to store chunks from a neighboring "sister" area, effectively increasing their reserve capacity twofold. By maintaining chunks from this sister neighborhood, a node becomes eligible to join the redistribution game whenever the sister neighborhood is chosen, effectively doubling its chances of participating.'}),"\n",(0,t.jsx)(n.p,{children:"Although reserve doubling demands twice the disk storage and increases bandwidth usage for chunk syncing (with no additional bandwidth needed for chunk forwarding), its effect on CPU and RAM consumption remains minimal. This feature provides node operators with greater flexibility to optimize their nodes, aiming to achieve a higher reward-to-resource usage ratio."}),"\n",(0,t.jsx)(n.h3,{id:"step-by-step-guide",children:"Step by Step Guide"}),"\n",(0,t.jsxs)(n.p,{children:["In order to double a node's reserve which has previously been operating without doubling, the ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," option must be updated from the default of ",(0,t.jsx)(n.code,{children:"0"})," to ",(0,t.jsx)(n.code,{children:"1"})," and restarted. There is also an increase in the xBZZ stake requirement from the minimum of 10 xBZZ to 20 xBZZ."]}),"\n",(0,t.jsxs)(n.h4,{id:"step-1-stake-at-least-20-xbzz",children:[(0,t.jsx)(n.strong,{children:"Step 1"}),": Stake at least 20 xBZZ"]}),"\n",(0,t.jsx)(n.p,{children:"For doubling the reserve of a node which was previously operating which already has 10 xBZZ staked, simply stake an additional 10 xBZZ for a total of 20 xBZZ stake:"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"As always, make sure that to properly convert the stake parameter to PLUR where 1 PLUR is equal to 1e-16 xBZZ. As in our example below, we have converted from 10 xBZZ to 100000000000000000 PLUR."})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X POST localhost:1633/stake/100000000000000000\n"})}),"\n",(0,t.jsx)(n.p,{children:"Or for a new node with zero staked xBZZ, the entire 20 xBZZ can be staked at once:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X POST localhost:1633/stake/200000000000000000\n"})}),"\n",(0,t.jsxs)(n.p,{children:["We can use the ",(0,t.jsx)(n.code,{children:"GET /stake"})," endpoint to confirm the total stake for our node:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://localhost:1633/stake | jq\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "stakedAmount": "200000000000000000"\n}\n'})}),"\n",(0,t.jsxs)(n.h4,{id:"step-2-set-reserve-capacity-doubling-to-1",children:[(0,t.jsx)(n.strong,{children:"Step 2"}),": Set ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," to ",(0,t.jsx)(n.code,{children:"1"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The reserve doubling feature can be enabled by setting the new ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," config option to ",(0,t.jsx)(n.code,{children:"1"})," using the ",(0,t.jsx)(n.a,{href:"/docs/bee/working-with-bee/configuration#configuration-methods-and-priority",children:"configuration method"})," of your choice."]}),"\n",(0,t.jsxs)(n.h4,{id:"step-3-restart-node",children:[(0,t.jsx)(n.strong,{children:"Step 3"}),": Restart node"]}),"\n",(0,t.jsxs)(n.p,{children:["After ensuring the node has at least 20 xBZZ staked and the ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," option has been set to ",(0,t.jsx)(n.code,{children:"1"}),", restart the node."]}),"\n",(0,t.jsx)(n.p,{children:"After restarting your node, it should then begin syncing chunks from its sister neighborhood."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"/status/neighborhoods"})," endpoint can be used to confirm that the node has doubled its reserve and is now syncing with its sister neighborhood:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "neighborhoods": [\n {\n "neighborhood": "01111101011",\n "reserveSizeWithinRadius": 1148351,\n "proximity": 10\n },\n {\n "neighborhood": "01111101010",\n "reserveSizeWithinRadius": 1147423,\n "proximity": 11\n }\n ]\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"The expected output should contain two neighborhoods, the node's original neighborhood along with its sister neighborhood."}),"\n",(0,t.jsxs)(n.p,{children:["We can also check the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint to confirm our node is syncing new chunks:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://localhost:1633/status | jq\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "overlay": "be177e61b13b1caa20690311a909bd674a3c1ef5f00d60414f261856a8ad5c30",\n "proximity": 256,\n "beeMode": "full",\n "reserveSize": 4192792,\n "reserveSizeWithinRadius": 2295023,\n "pullsyncRate": 1.3033333333333332,\n "storageRadius": 10,\n "connectedPeers": 18,\n "neighborhoodSize": 1,\n "batchCommitment": 388104192,\n "isReachable": true,\n "lastSyncedBlock": 6982430\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["We can see that the ",(0,t.jsx)(n.code,{children:"pullsyncRate"})," value is above zero, meaning that our node is currently syncing chunks, as expected."]}),"\n",(0,t.jsx)(n.h3,{id:"reserve-doubling-reversing--withdrawable-stake",children:"Reserve Doubling Reversing & Withdrawable Stake"}),"\n",(0,t.jsxs)(n.p,{children:["Due to certain ",(0,t.jsx)(n.a,{href:"https://github.com/ethersphere/storage-incentives/blob/20bf3c0e3fcf1e98dedcbf16cd82fb4d337fdaf7/src/Staking.sol#L136",children:"implementation details"}),", the order in which a node's reserve is doubled and then reversed can have an impact on the amount of withdrawable stake."]}),"\n",(0,t.jsxs)(n.p,{children:["When doubling a node's reserve, stake should be added AFTER\nsetting ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," to 1. If instead, xBZZ is first staked with ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," set to 0, and the reserve is then doubled by increasing from 0 to 1 without the addition of more stake, this will prevent stake from being withdrawable when the doubling is reversed."]}),"\n",(0,t.jsx)(n.p,{children:"In order to maximize the amount of withdrawable stake after reversing a reserve doubling, follow the step from the previous section in the exact order described when doubling."}),"\n",(0,t.jsx)(n.h4,{id:"how-to-free-up-withdrawable-stake-from-a-node-with--20-xbzz-stake-that-currently-has-zero-withdrawable-stake",children:"How to free up withdrawable stake from a node with >= 20 xBZZ stake that currently has zero withdrawable stake:"}),"\n",(0,t.jsxs)(n.p,{children:["In the case that a node with 20 xBZZ stake was doubled directly by increasing ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," from 0 to 1, the surplus xBZZ over the minimum required 10 xBZZ cannot be made withdrawable by simply reversing the ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," from 1 back to 0."]}),"\n",(0,t.jsxs)(n.p,{children:["In this case, you will need to first send a very small staking transaction of a single PLUR while ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," is set to 1, and after that, change ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," from 1 to 0. This works because every time any amount of stake is added, it forces to staking contract to redo its calculations."]}),"\n",(0,t.jsx)(n.p,{children:"The detailed steps are:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Issue a staking transaction for 1 PLUR while ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," is set to 1.","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X POST localhost:1633/stake/1\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Stop node and set ",(0,t.jsx)(n.code,{children:"reserve-capacity-doubling"})," to 0."]}),"\n",(0,t.jsx)(n.li,{children:"Restart node. The 10 xBZZ should now be withdrawable."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"maximize-rewards",children:"Maximize rewards"}),"\n",(0,t.jsxs)(n.p,{children:["There are two main factors which determine the chances for a staking node to win a reward \u2014 neighborhood selection and stake density. Both of these should be considered together before starting up a Bee node for the first time. See the ",(0,t.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"incentives page"})," for more context."]}),"\n",(0,t.jsx)(n.h3,{id:"neighborhood-selection",children:"Neighborhood selection"}),"\n",(0,t.jsxs)(n.p,{children:["By default when running a Bee node for the first time an overlay address will be generated and used to assign the node to a random ",(0,t.jsx)(n.a,{href:"/docs/concepts/DISC/neighborhoods",children:"neighborhood"}),". However, by using the ",(0,t.jsx)(n.code,{children:"target-neighborhood"})," config option, a specific neighborhood can be selected in which to generate the node's overlay address. This is an excellent tool for maximizing reward chances as generally speaking running in a less populated neighborhood will increase the chances of winning a reward. See the ",(0,t.jsx)(n.a,{href:"/docs/bee/installation/install#set-target-neighborhood-optional",children:"config section"})," on the installation page for more information on how to set a target neighborhood."]}),"\n",(0,t.jsx)(n.h3,{id:"stake-density",children:"Stake density"}),"\n",(0,t.jsx)(n.p,{children:"Stake density is defined as:"}),"\n",(0,t.jsx)(n.span,{className:"katex-display",children:(0,t.jsxs)(n.span,{className:"katex",children:[(0,t.jsx)(n.span,{className:"katex-mathml",children:(0,t.jsx)(n.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,t.jsxs)(n.semantics,{children:[(0,t.jsxs)(n.mrow,{children:[(0,t.jsx)(n.mtext,{children:"stake\xa0density"}),(0,t.jsx)(n.mo,{children:"="}),(0,t.jsx)(n.mtext,{children:"staked\xa0xBZZ"}),(0,t.jsx)(n.mo,{children:"\xd7"}),(0,t.jsxs)(n.msup,{children:[(0,t.jsx)(n.mn,{children:"2"}),(0,t.jsx)(n.mtext,{children:"storageDepth"})]})]}),(0,t.jsx)(n.annotation,{encoding:"application/x-tex",children:"\\text{stake density} = \\text{staked xBZZ} \\times {2}^\\text{storageDepth}"})]})})}),(0,t.jsxs)(n.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(n.span,{className:"base",children:[(0,t.jsx)(n.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,t.jsx)(n.span,{className:"mord text",children:(0,t.jsx)(n.span,{className:"mord",children:"stake\xa0density"})}),(0,t.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,t.jsx)(n.span,{className:"mrel",children:"="}),(0,t.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,t.jsxs)(n.span,{className:"base",children:[(0,t.jsx)(n.span,{className:"strut",style:{height:"0.7778em",verticalAlign:"-0.0833em"}}),(0,t.jsx)(n.span,{className:"mord text",children:(0,t.jsx)(n.span,{className:"mord",children:"staked\xa0xBZZ"})}),(0,t.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(n.span,{className:"mbin",children:"\xd7"}),(0,t.jsx)(n.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(n.span,{className:"base",children:[(0,t.jsx)(n.span,{className:"strut",style:{height:"0.8991em"}}),(0,t.jsxs)(n.span,{className:"mord",children:[(0,t.jsx)(n.span,{className:"mord",children:(0,t.jsx)(n.span,{className:"mord",children:"2"})}),(0,t.jsx)(n.span,{className:"msupsub",children:(0,t.jsx)(n.span,{className:"vlist-t",children:(0,t.jsx)(n.span,{className:"vlist-r",children:(0,t.jsx)(n.span,{className:"vlist",style:{height:"0.8991em"},children:(0,t.jsxs)(n.span,{style:{top:"-3.113em",marginRight:"0.05em"},children:[(0,t.jsx)(n.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(n.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(n.span,{className:"mord text mtight",children:(0,t.jsx)(n.span,{className:"mord mtight",children:"storageDepth"})})})]})})})})})]})]})]})]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.em,{children:["To learn more about stake density and the mechanics of the incentives system, see the ",(0,t.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"incentives page"}),"."]})}),"\n",(0,t.jsx)(n.p,{children:"Stake density determines the weighted chances of nodes within a neighborhood of winning rewards. The chance of winning within a neighborhood corresponds to stake density. Stake density can be increased by depositing more xBZZ as stake (note that stake withdrawals are not currently possible, so any staked xBZZ is not currently recoverable)."}),"\n",(0,t.jsxs)(n.p,{children:["Generally speaking, the minimum required stake of 10 xBZZ is sufficient, and rewards can be better maximized by operating more nodes over a greater range of neighborhoods rather than increasing stake. However this may not be true for all node operators depending on how many different neighborhoods they operate nodes in, and it also may change as network dynamics continue to evolve (join the ",(0,t.jsx)(n.code,{children:"#node-operators"})," ",(0,t.jsx)(n.a,{href:"https://discord.com/channels/799027393297514537/811553590170353685",children:"Discord channel"})," to stay up to date with the latest discussions about staking and network dynamics)."]}),"\n",(0,t.jsx)(n.h2,{id:"neighborhood-hopping",children:"Neighborhood Hopping"}),"\n",(0,t.jsxs)(n.admonition,{type:"warning",children:[(0,t.jsx)(n.mdxAdmonitionTitle,{}),(0,t.jsx)(n.p,{children:"While you may update your neighborhood freely as you wish, it takes significant time for to fully sync chunks and become eligible for playing in the redistribution game, so it is not advised to hop too frequently."})]}),"\n",(0,t.jsxs)(n.p,{children:["You can use the option ",(0,t.jsx)(n.code,{children:"target-neighborhood"})," to switch your node over to a new neighborhood. You may wish to use this option if your node's neighborhood becomes overpopulated."]}),"\n",(0,t.jsx)(n.h3,{id:"checking-neighborhood-population",children:"Checking neighborhood population"}),"\n",(0,t.jsxs)(n.p,{children:["For a quick check of your node's neighborhood population, we can use the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'curl -s http://localhost:1633/status | jq\n{\n "peer": "e7b5c1aac67693268fdec98d097a8ccee1aabcf58e26c4512ea888256d0e6dff",\n "proximity": 0,\n "beeMode": "full",\n "reserveSize": 1055543,\n "reserveSizeWithinRadius": 1039749,\n "pullsyncRate": 42.67013868148148,\n "storageRadius": 11,\n "connectedPeers": 140,\n "neighborhoodSize": 6,\n "batchCommitment": 74463051776,\n "isReachable": false\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Here we can see that at the current ",(0,t.jsx)(n.code,{children:"storageRadius"})," of 11, our node is in a neighborhood with size 6 from the ",(0,t.jsx)(n.code,{children:"neighborhoodSize"})," value."]}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.a,{href:"https://swarmscan.io/neighborhoods",children:"Swarmscan neighborhoods tool"})," we can see there are many neighborhoods with fewer nodes, so it would benefit us to move to less populated neighborhood:"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(81920).A+"",width:"2102",height:"1224"})}),"\n",(0,t.jsx)(n.p,{children:"While you might be tempted to simply pick one of these less populated neighborhoods, it is best practice to use the neighborhood suggester API instead, since it will help to prevent too many node operators rapidly moving to the same underpopulated neighborhoods, and also since the suggester takes a look at the next depth down to make sure that even in case of a neighborhood split, your node will end up in the smaller neighborhood."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s https://api.swarmscan.io/v1/network/neighborhoods/suggestion\n"})}),"\n",(0,t.jsx)(n.p,{children:"Copy the binary number returned from the API:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{"neighborhood":"01100011110"}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Use the binary number you just copied and set it as a string value for the ",(0,t.jsx)(n.code,{children:"target-neighborhood"})," option in your config."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'## bee.yaml\ntarget-neighborhood: "01100011110"\n'})}),"\n",(0,t.jsxs)(n.admonition,{type:"info",children:[(0,t.jsx)(n.mdxAdmonitionTitle,{}),(0,t.jsxs)(n.p,{children:["Depending on your setup, you may need change the ",(0,t.jsx)(n.code,{children:"target-neighborhood"})," option by updating your ",(0,t.jsx)(n.code,{children:"bee.yaml"})," file, adding the ",(0,t.jsx)(n.code,{children:"--target-neighborhood"})," command line flag, or edit a ",(0,t.jsx)(n.code,{children:".env"})," file, among several possible common options."]})]}),"\n",(0,t.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,t.jsxs)(n.p,{children:["In this section we cover several commonly seen issues encountered for staking nodes participating in the redistribution game. If you don't see your issue covered here or require additional guidance, check out the ",(0,t.jsx)(n.code,{children:"#node-operators"})," ",(0,t.jsx)(n.a,{href:"https://discord.com/channels/799027393297514537/811553590170353685",children:"Discord channel"})," where you will find support from other node operators and community members."]}),"\n",(0,t.jsx)(n.h3,{id:"frozen-node",children:"Frozen node"}),"\n",(0,t.jsxs)(n.p,{children:["A node will be frozen when the reserve commitment hash it submits in its ",(0,t.jsxs)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:[(0,t.jsx)(n.code,{children:"commit"})," transaction"]})," does not match the correct hash. The reserve commitment hash is used as proof that a node is storing the chunks it is responsible for. It will not be able to play in the redistribution game during the freezing period. See the ",(0,t.jsx)(n.a,{href:"/docs/concepts/incentives/redistribution-game",children:"penalties"})," section for more information."]}),"\n",(0,t.jsx)(n.h4,{id:"check-frozen-status",children:"Check frozen status"}),"\n",(0,t.jsxs)(n.p,{children:["You can check your node's frozen status using the ",(0,t.jsx)(n.code,{children:"/redistributionstate"})," endpoint:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The relevant fields here are ",(0,t.jsx)(n.code,{children:"isFrozen"})," and ",(0,t.jsx)(n.code,{children:"lastFrozenRound"}),", which respectively indicate whether the node is currently frozen and the last round in which the node was frozen."]}),"\n",(0,t.jsx)(n.h4,{id:"diagnosing-freezing-issues",children:"Diagnosing freezing issues"}),"\n",(0,t.jsxs)(n.p,{children:["In order to diagnose the cause of freezing issues we must compare our own node's status to that of other nodes within the same neighborhood by comparing the results from our own node returned from the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint to the other nodes in the same neighborhood which can be found from the ",(0,t.jsx)(n.code,{children:"/status/peers"})," endpoint."]}),"\n",(0,t.jsx)(n.p,{children:"First we check our own node's status:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" curl -s localhost:1633/status | jq\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:' {\n "peer": "da7e5cc3ed9a46b6e7491d3bf738535d98112641380cbed2e9ddfe4cf4fc01c4",\n "proximity": 0,\n "beeMode": "full",\n "reserveSize": 3747532,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 183,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true \n }\n'})}),"\n",(0,t.jsx)(n.p,{children:"And next we will find the status for all the other nodes in the same neighborhood as our own."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" curl -s localhost:1633/status/peers | jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"/status/peers"})," endpoint returns all the peers of our node, but we are only concerned with peers in the same neighborhood as our own node. Nodes whose ",(0,t.jsx)(n.code,{children:"proximity"})," value is equal to or greater than our own node's ",(0,t.jsx)(n.code,{children:"storageRadius"})," value all fall into the same neighborhood as our node, so the rest have been omitted in the example output below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{ \n ...\n {\n "peer": "da33f7a504a74094242d3e542475b49847d1d0f375e0c86bac1c9d7f0937acc0",\n "proximity": 9,\n "beeMode": "full",\n "reserveSize": 3782924,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 188,\n "neighborhoodSize": 11,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4b529cc1aedc62e31849cf7f8ab8c1866d9d86038b857d6cf2f590604387fe",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3719593,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 176,\n "neighborhoodSize": 11,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da5d39a5508fadf66c8665d5e51617f0e9e5fd501e429c38471b861f104c1504",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3777241,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 198,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4cb0d125bba638def55c0061b00d7c01ed4033fa193d6e53a67183c5488d73",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3849125,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 181,\n "neighborhoodSize": 13,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4b1cd5d15e061fdd474003b5602ab1cff939b4b9e30d60f8ff693141ede810",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3778452,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 183,\n "neighborhoodSize": 12,\n "batchCommitment": 133827002368,\n "isReachable": true\n },\n {\n "peer": "da49e6c6174e3410edad2e0f05d704bbc33e9996bc0ead310d55372677316593",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3779560,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 185,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4cdab480f323d5791d3ab8d22d99147f110841e44a8991a169f0ab1f47d8e5",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3778518,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 189,\n "neighborhoodSize": 11,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da4ccec79bc34b502c802415b0008c4cee161faf3cee0f572bb019b117c89b2f",\n "proximity": 10,\n "beeMode": "full",\n "reserveSize": 3779003,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 179,\n "neighborhoodSize": 10,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da69d412b79358f84b7928d2f6b7ccdaf165a21313608e16edd317a5355ba250",\n "proximity": 11,\n "beeMode": "full",\n "reserveSize": 3712586,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 189,\n "neighborhoodSize": 12,\n "batchCommitment": 133827002368,\n "isReachable": true\n },\n {\n "peer": "da61967b1bd614a69e5e83f73cc98a63a70ebe20454ca9aafea6b57493e00a34",\n "proximity": 11,\n "beeMode": "full",\n "reserveSize": 3780190,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 182,\n "neighborhoodSize": 13,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da7b6a268637cfd6799a9923129347fc3d564496ea79aea119e89c09c5d9efed",\n "proximity": 13,\n "beeMode": "full",\n "reserveSize": 3721494,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 188,\n "neighborhoodSize": 14,\n "batchCommitment": 133828050944,\n "isReachable": true\n },\n {\n "peer": "da7a974149543df1b459831286b42b302f22393a20e9b3dd9a7bb5a7aa5af263",\n "proximity": 13,\n "beeMode": "full",\n "reserveSize": 3852986,\n "pullsyncRate": 0,\n "storageRadius": 10,\n "connectedPeers": 186,\n "neighborhoodSize": 12,\n "batchCommitment": 133828050944,\n "isReachable": true\n }\n]\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Now that we have the status for our own node and all its neighborhood peers we can begin to diagnose the issue through a series of checks outlined below:"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"If you are able to identify and fix a problem with your node from the checklist below, it's possible that your node's reserve has become corrupted. Therefore, after fixing the problem, stop your node, and repair your node according to the instructions in the section following the checklist."})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Compare ",(0,t.jsx)(n.code,{children:"reserveSize"})," with peers"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"reserveSize"})," value is the number of chunks stored by a node in its reserve. The value for ",(0,t.jsx)(n.code,{children:"reserveSize"})," for a healthy node should be around +/- 1% the size of most other nodes in the neighborhood. In our example, for our node's ",(0,t.jsx)(n.code,{children:"reserveSize"})," of 3747532, it falls within that normal range. This does not guarantee our node has no missing or corrupted chunks, but it does indicate that it is generally storing the same chunks as its neighbors. If it falls outside this range, see the next section for instructions on repairing reserves."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Compare ",(0,t.jsx)(n.code,{children:"batchCommitment"})," with peers"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"batchCommitment"})," value shows how many chunks would be stored if all postage batches were fully utilised. It also represents whether the node has fully synced postage batch data from on-chain. If your node's ",(0,t.jsx)(n.code,{children:"batchCommitment"})," value falls below that of its peers in the same neighborhood, it could indicate an issue with your blockchain RPC endpoint that is preventing it from properly syncing on-chain data. If you are running your own node, check your setup to make sure it is functioning properly, or check with your provider if you are using a 3rd party service for your RPC endpoint."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Check ",(0,t.jsx)(n.code,{children:"pullsyncRate"})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"pullsyncRate"})," value measures the speed at which a node is syncing chunks from its peers. Once a node is fully synced, ",(0,t.jsx)(n.code,{children:"pullsyncRate"})," should go to zero. If ",(0,t.jsx)(n.code,{children:"pullsyncRate"})," is above zero it indicates that your node is still syncing chunks, so you should wait until it goes to zero before doing any other checks. If ",(0,t.jsx)(n.code,{children:"pullsyncRate"})," is at zero but your node's ",(0,t.jsx)(n.code,{children:"reserveSize"})," does not match its peers, you should check whether your network connection and RPC endpoint are stable and functioning properly. A node should be fully synced after several hours at most."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Check most recent ",(0,t.jsx)(n.code,{children:"block"})," number"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"block"})," value returned from the ",(0,t.jsx)(n.code,{children:"/redistributionstate"})," endpoint shows the most recent block a node has synced. If this number is far behind the actual more recent block then it indicates an issue with your RPC endpoint or network. If you are running your own node, check your setup to make sure it is functioning properly, or check with your provider if you are using a 3rd party service for your RPC endpoint."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Check peer connectivity"}),"\n",(0,t.jsxs)(n.p,{children:["Compare the value of your node's ",(0,t.jsx)(n.code,{children:"neighborhoodSize"})," from the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint and the ",(0,t.jsx)(n.code,{children:"neighborhoodSize"})," of its peers in the same neighborhood from the ",(0,t.jsx)(n.code,{children:"/status/peers"})," endpoint. The figure should be generally the same (although it may fluctuate slightly up or down at any one point in time). If your node's ",(0,t.jsx)(n.code,{children:"neighborhoodSize"})," value is significantly different and remains so over time then your node likely has a connectivity problem. Make sure to ",(0,t.jsx)(n.a,{href:"/docs/bee/installation/connectivity",children:"check your network environment"})," to ensure your node is able to communicate with the network."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"If no problems are identified during these checks it likely indicates that your node was frozen in error and there are no additional steps you need to take."}),"\n",(0,t.jsx)(n.h3,{id:"repairing-corrupt-reserve",children:"Repairing corrupt reserve"}),"\n",(0,t.jsxs)(n.p,{children:["If you have identified and fixed a problem causing your node to become frozen or have other reason to believe that your node's reserves are corrupted then you should repair your node's reserve using the ",(0,t.jsx)(n.code,{children:"db repair-reserve"})," command."]}),"\n",(0,t.jsx)(n.p,{children:"First stop your node, and then run the following command:"}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["Make sure to replace ",(0,t.jsx)(n.code,{children:"/home/bee/.bee"})," with your node\u2019s data directory if it differs from the one shown in the example. Make sure that the directory you specify is the root directory for your node\u2019s data files, not the localstore directory itself. This is the same directory specified using the ",(0,t.jsx)(n.code,{children:"data-dir"})," option in your node\u2019s ",(0,t.jsx)(n.a,{href:"/docs/bee/working-with-bee/configuration/",children:"configuration"}),"."]})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bee db repair-reserve --data-dir=/home/bee/.bee\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the command has finished running, you may restart your node."}),"\n",(0,t.jsx)(n.h3,{id:"node-occupies-unusually-large-space-on-disk",children:"Node occupies unusually large space on disk"}),"\n",(0,t.jsxs)(n.p,{children:["During normal operation of a Bee node, it should not take up more than ~30 GB of disk space. In the rare cases when the node's occupied disk space grows larger, you may need to use the compaction ",(0,t.jsx)(n.code,{children:"db compact"})," command."]}),"\n",(0,t.jsx)(n.admonition,{type:"danger",children:(0,t.jsx)(n.p,{children:"To prevent any data loss, operators should run the compaction on a copy of the localstore directory and, if successful, replace the original localstore with the compacted copy."})}),"\n",(0,t.jsxs)(n.p,{children:["The command is available as a sub-command under db as such (make sure to replace the value for ",(0,t.jsx)(n.code,{children:"--data-dir"})," with the correct path to your bee node's data folder if it differs from the path shown in the example):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bee db compact --data-dir=/home/bee/.bee\n"})}),"\n",(0,t.jsx)(n.h3,{id:"node-not-participating-in-redistribution",children:"Node not participating in redistribution"}),"\n",(0,t.jsxs)(n.p,{children:["First check that the node is fully synced, is not frozen, and has sufficient funds to participate in staking. To check node sync status, call the ",(0,t.jsx)(n.code,{children:"redistributionstate"})," endpoint:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl -X GET http://localhost:1633/redistributionstate | jq\n"})}),"\n",(0,t.jsx)(n.p,{children:"Response:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{ \n "minimumFunds": "18750000000000000",\n "hasSufficientFunds": true,\n "isFrozen": false,\n "isFullySynced": true,\n "phase": "commit",\n "round": 176319,\n "lastWonRound": 176024,\n "lastPlayedRound": 176182,\n "lastFrozenRound": 0,\n "block": 26800488,\n "reward": "10479124611072000",\n "fees": "30166618102500000"\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Confirm that ",(0,t.jsx)(n.code,{children:"hasSufficientFunds"})," is ",(0,t.jsx)(n.code,{children:"true"}),", and ",(0,t.jsx)(n.code,{children:"isFullySynced"})," is ",(0,t.jsx)(n.code,{children:"true"})," before moving to the next step. If ",(0,t.jsx)(n.code,{children:"hasSufficientFunds"})," if ",(0,t.jsx)(n.code,{children:"false"}),", make sure to add at least the amount of xDAI shown in ",(0,t.jsx)(n.code,{children:"minimumFunds"})," (unit of 1e-18 xDAI). If the node was recently installed and ",(0,t.jsx)(n.code,{children:"isFullySynced"})," is ",(0,t.jsx)(n.code,{children:"false"}),", wait for the node to fully sync before continuing. After confirming the node's status, continue to the next step."]}),"\n",(0,t.jsx)(n.h4,{id:"run-sampler-process-to-benchmark-performance",children:"Run sampler process to benchmark performance"}),"\n",(0,t.jsxs)(n.p,{children:["One of the most common issues affecting staking is the ",(0,t.jsx)(n.code,{children:"sampler"})," process failing. The sampler is a resource intensive process which is run by nodes which are selected to take part in redistribution. The process may fail or time out if the node's hardware specifications aren't high enough. To check a node's performance the ",(0,t.jsx)(n.code,{children:"/rchash/{depth}/{anchor_01}/{anchor_02}"})," endpoint of the API may be used. The ",(0,t.jsx)(n.code,{children:"anchor_01"})," and ",(0,t.jsx)(n.code,{children:"anchor_02"})," must be a hex string with an even number of digits. For simplicity, you can just use ",(0,t.jsx)(n.code,{children:"aaaa"})," for both anchors as we do in the example further down."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"{anchor}"})," value can be set to any random hexadecimal string, while ",(0,t.jsx)(n.code,{children:"{depth}"})," should be set to the current depth."]}),"\n",(0,t.jsxs)(n.p,{children:["To get the current depth, call the ",(0,t.jsx)(n.code,{children:"/reservestate"})," endpoint"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo curl -sX GET http://localhost:1633/reservestate | jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Copy the ",(0,t.jsx)(n.code,{children:"storageRadius"})," value from the output (this represents the ACTUAL depth for your node, in other words, the depth to which your node is responsible for storing files. The ",(0,t.jsx)(n.code,{children:"radius"})," value is the hypothetical depth your node would be at if every postage batch was fully utilised.)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "radius": 15,\n "storageRadius": 10,\n "commitment": 128332464128\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Call the endpoint like so:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo curl -sX GET http://localhost:1633/rchash/10/aaaa/aaaa | jq\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the sampler runs successfully, you should see output like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "Sample": {\n "Items": [\n "000003dac2b2f75842e410474dfa4c1e6e0b9970d81b57b33564c5620667ba96",\n "00000baace30916f7445dbcc44d9b55cb699925acfbe157e4498c63bde834f40",\n "0000126f48fb1e99e471efc683565e4b245703c922b9956f89cbe09e1238e983",\n "000012db04a281b7cc0e6436a49bdc5b06ff85396fcb327330ca307e409d2a04",\n "000014f365b1a381dda85bbeabdd3040fb1395ca9e222e72a597f4cc76ecf6c2",\n "00001869a9216b3da6814a877fdbc31f156fc2e983b52bc68ffc6d3f3cc79af0",\n "0000198c0456230b555d5261091cf9206e75b4ad738495a60640b425ecdf408f",\n "00001a523bd1b688472c6ea5a3c87c697db64d54744829372ac808de8ec1d427"\n ],\n "Hash": "7f7d93c6235855fedc34e32c6b67253e27910ca4e3b8f2d942efcd758a6d8829"\n },\n "Time": "2m54.087909745s"\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["If the ",(0,t.jsx)(n.code,{children:"Time"})," value is higher than 6 minutes, then the hardware specifications for the node may need to be upgraded."]}),"\n",(0,t.jsxs)(n.p,{children:["If there is an evictions related error such as the one below, try running the call to the ",(0,t.jsx)(n.code,{children:"/rchash/"})," endpoint again."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'error: "level"="error" "logger"="node/storageincentives" "msg"="make sample" "error"="sampler: failed creating sample: sampler stopped due to ongoing evictions"\n'})}),"\n",(0,t.jsx)(n.p,{children:"While evictions are a normal part of Bee's standard operation, the event of an eviction will interrupt the sampler process."}),"\n",(0,t.jsxs)(n.p,{children:["If you are still experiencing problems, you can find more help in the ",(0,t.jsx)(n.a,{href:"https://discord.gg/kHRyMNpw7t",children:"node-operators"})," Discord channel (for your safety, do not accept advice from anyone sending a private message on Discord)."]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},81920:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/staking-swarmscan-7a08f2c5be1d57dbe9c9b64f8fb3c608.png"},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.7e1ed731.js b/assets/js/runtime~main.2b756c69.js similarity index 76% rename from assets/js/runtime~main.7e1ed731.js rename to assets/js/runtime~main.2b756c69.js index c379d3ed..dd0f0bbb 100644 --- a/assets/js/runtime~main.7e1ed731.js +++ b/assets/js/runtime~main.2b756c69.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,f,b,d,c={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return c[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=c,r.c=t,e=[],r.O=(a,f,b,d)=>{if(!f){var c=1/0;for(i=0;i=d)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[f,b,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,b){if(1&b&&(e=this(e)),8&b)return e;if("object"==typeof e&&e){if(4&b&&e.__esModule)return e;if(16&b&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var c={};a=a||[null,f({}),f([]),f(f)];for(var t=2&b&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>c[a]=()=>e[a]));return c.default=()=>e,r.d(d,c),d},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({106:"f375a06e",264:"df2717bb",272:"f6879adf",421:"d474cb3a",593:"5292c32b",596:"a0798b91",714:"000d6678",766:"a7d5385f",769:"1783be55",791:"f7a6d479",849:"0058b4c6",877:"6bac647a",957:"c141421f",1235:"a7456010",1628:"5ee72a4b",1678:"ff1e3514",1914:"243e784f",1927:"e75f3413",2034:"06809660",2074:"51e16090",2138:"1a4e3797",2396:"9594edf7",2426:"032f5f3f",2433:"f7f0193b",2563:"2fb51a8e",2634:"c4f5d8e4",2774:"098f45c6",2854:"e4170b6f",2969:"f0ad3fbb",2974:"88edeb39",3047:"1c690199",3108:"0665e5d4",3115:"8497dad5",3230:"b35a7c50",3269:"10af94c2",3460:"b0c952a3",3583:"d181d228",3623:"a23930e7",3829:"8c5f7849",4154:"b57c29d7",4179:"5bb09754",4304:"275a8dd8",4311:"b2147b80",4536:"5f58f78d",4590:"4cb53170",4595:"89aa0649",5411:"da92f910",5452:"e88c9444",5527:"15b691b6",5575:"87c3baf4",5742:"aba21aa0",5878:"eae929fd",5929:"59713e80",5957:"4d578846",6298:"47fe8a44",6440:"a7e6bfea",6635:"211ef201",6673:"d6644dbd",6699:"78008a53",7013:"b8b11332",7098:"a7bd4aaa",7121:"6f20431d",7183:"a68c8598",7233:"b0d08c50",7473:"35bdca39",7484:"197c6470",7519:"d643000e",7824:"99b6ceef",7895:"98797543",8241:"8932e155",8401:"17896441",8528:"f168c850",8539:"df724892",8846:"3c3a6abf",8883:"e694b58a",8932:"45d8935a",8983:"2d03fd69",9030:"e76d947a",9048:"a94703ab",9130:"6ba57622",9272:"d555a461",9346:"3aa86a4e",9363:"20561a1f",9367:"1b0c73d8",9381:"e38a37f7",9429:"b57ec343",9629:"23136fa4",9647:"5e95c892",9750:"191458e8"}[e]||e)+"."+{106:"5aa1ca7c",264:"7ec790e9",272:"5d6dfd58",416:"dcbb754b",421:"64bdaa83",593:"4f132f1e",596:"c7be84c1",714:"733cf097",766:"0d1841ff",769:"79daacc6",791:"2aeec6d1",849:"66a722c0",877:"32ccc941",957:"d2a1ccd2",1169:"229acd22",1176:"720b0dab",1207:"263e1268",1235:"0657152a",1245:"b0b268af",1303:"a67395f2",1331:"3ed28bac",1398:"72e4cd3d",1628:"260f5f47",1678:"95fed6b9",1914:"0c4b985f",1927:"f1f10350",1946:"db52ce41",2034:"629cd0d3",2074:"5be54119",2130:"6d5eb029",2138:"14f72b3d",2237:"f51eb88e",2376:"14981e3e",2396:"5d80e4a7",2426:"d271acc5",2433:"fea77b0a",2453:"99f545b0",2548:"61b63049",2563:"a135f3a6",2634:"a4ce9b79",2756:"f27683c4",2774:"9a0cdf52",2838:"f2b4b987",2843:"bc6ad154",2854:"15476025",2925:"984212c4",2969:"6ed80c7a",2974:"696de506",2983:"458917e3",3047:"5ffb7190",3068:"51abbdc6",3108:"343f1f91",3115:"c143ad9c",3230:"9941a481",3269:"f2f24f18",3460:"561408c9",3583:"d1b3d0e7",3623:"94c750b8",3626:"7c4e66e5",3706:"2eb2c015",3829:"313bf0b6",4154:"5ab21d8a",4162:"c89bd0b9",4179:"e339b4d1",4304:"d95e6543",4311:"2e6b1e4e",4536:"8740cfc7",4590:"162ffa2a",4595:"dab8b68d",4741:"571f4af4",4943:"192b1fc9",5411:"cf7f72ad",5452:"15f400c9",5527:"7b31708e",5575:"a4c07e79",5742:"149d4ec6",5878:"be00a9f7",5929:"ccc1a7f4",5957:"44edba23",6298:"7276f55f",6420:"bd99f30c",6440:"a5a7bdee",6635:"4d81c63e",6673:"9499612f",6699:"9fa372ba",6788:"df2e2724",6803:"3757e69d",6911:"965be4da",7013:"319e6b97",7098:"3339cb44",7121:"d98b5a17",7183:"ae91e846",7233:"c3b4eef8",7426:"afe19e78",7473:"f04ee808",7484:"efbc9c53",7519:"d446e865",7824:"050e340e",7895:"b058575e",8055:"c58cfabc",8158:"e40616bd",8241:"1bdfc846",8401:"901bc284",8478:"8ad0349a",8528:"4eb8c53a",8539:"2d625697",8635:"9bf77743",8810:"f27d31b0",8846:"732a433a",8869:"01feebe9",8883:"b526c11f",8913:"1a661a19",8932:"277db7da",8983:"9af7fc0b",9030:"ca9ff988",9048:"364c6e9c",9130:"a70390a8",9272:"4f78c977",9346:"e7ebb29f",9363:"5342e21e",9367:"5df6020c",9381:"2bc64e2e",9429:"389f6634",9629:"5b12b125",9647:"4b59a626",9689:"a9bf4169",9750:"c4d2bac7"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),b={},d="bee-docs:",r.l=(e,a,f,c)=>{if(b[e])b[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var d=b[e];if(delete b[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(f))),a)return a(f)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={17896441:"8401",98797543:"7895",f375a06e:"106",df2717bb:"264",f6879adf:"272",d474cb3a:"421","5292c32b":"593",a0798b91:"596","000d6678":"714",a7d5385f:"766","1783be55":"769",f7a6d479:"791","0058b4c6":"849","6bac647a":"877",c141421f:"957",a7456010:"1235","5ee72a4b":"1628",ff1e3514:"1678","243e784f":"1914",e75f3413:"1927","06809660":"2034","51e16090":"2074","1a4e3797":"2138","9594edf7":"2396","032f5f3f":"2426",f7f0193b:"2433","2fb51a8e":"2563",c4f5d8e4:"2634","098f45c6":"2774",e4170b6f:"2854",f0ad3fbb:"2969","88edeb39":"2974","1c690199":"3047","0665e5d4":"3108","8497dad5":"3115",b35a7c50:"3230","10af94c2":"3269",b0c952a3:"3460",d181d228:"3583",a23930e7:"3623","8c5f7849":"3829",b57c29d7:"4154","5bb09754":"4179","275a8dd8":"4304",b2147b80:"4311","5f58f78d":"4536","4cb53170":"4590","89aa0649":"4595",da92f910:"5411",e88c9444:"5452","15b691b6":"5527","87c3baf4":"5575",aba21aa0:"5742",eae929fd:"5878","59713e80":"5929","4d578846":"5957","47fe8a44":"6298",a7e6bfea:"6440","211ef201":"6635",d6644dbd:"6673","78008a53":"6699",b8b11332:"7013",a7bd4aaa:"7098","6f20431d":"7121",a68c8598:"7183",b0d08c50:"7233","35bdca39":"7473","197c6470":"7484",d643000e:"7519","99b6ceef":"7824","8932e155":"8241",f168c850:"8528",df724892:"8539","3c3a6abf":"8846",e694b58a:"8883","45d8935a":"8932","2d03fd69":"8983",e76d947a:"9030",a94703ab:"9048","6ba57622":"9130",d555a461:"9272","3aa86a4e":"9346","20561a1f":"9363","1b0c73d8":"9367",e38a37f7:"9381",b57ec343:"9429","23136fa4":"9629","5e95c892":"9647","191458e8":"9750"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var b=r.o(e,a)?e[a]:void 0;if(0!==b)if(b)f.push(b[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var d=new Promise(((f,d)=>b=e[a]=[f,d]));f.push(b[2]=d);var c=r.p+r.u(a),t=new Error;r.l(c,(f=>{if(r.o(e,a)&&(0!==(b=e[a])&&(e[a]=void 0),b)){var d=f&&("load"===f.type?"missing":f.type),c=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+c+")",t.name="ChunkLoadError",t.type=d,t.request=c,b[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var b,d,c=f[0],t=f[1],o=f[2],n=0;if(c.some((a=>0!==e[a]))){for(b in t)r.o(t,b)&&(r.m[b]=t[b]);if(o)var i=o(r)}for(a&&a(f);n{"use strict";var e,a,f,d,b,c={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return c[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=c,r.c=t,e=[],r.O=(a,f,d,b)=>{if(!f){var c=1/0;for(i=0;i=b)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[f,d,b]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var c={};a=a||[null,f({}),f([]),f(f)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>c[a]=()=>e[a]));return c.default=()=>e,r.d(b,c),b},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({106:"f375a06e",264:"df2717bb",272:"f6879adf",421:"d474cb3a",593:"5292c32b",596:"a0798b91",714:"000d6678",766:"a7d5385f",769:"1783be55",791:"f7a6d479",849:"0058b4c6",877:"6bac647a",957:"c141421f",1235:"a7456010",1628:"5ee72a4b",1678:"ff1e3514",1914:"243e784f",1927:"e75f3413",2034:"06809660",2074:"51e16090",2138:"1a4e3797",2396:"9594edf7",2426:"032f5f3f",2433:"f7f0193b",2563:"2fb51a8e",2634:"c4f5d8e4",2774:"098f45c6",2854:"e4170b6f",2969:"f0ad3fbb",2974:"88edeb39",3047:"1c690199",3108:"0665e5d4",3115:"8497dad5",3230:"b35a7c50",3269:"10af94c2",3460:"b0c952a3",3583:"d181d228",3623:"a23930e7",3829:"8c5f7849",4154:"b57c29d7",4179:"5bb09754",4304:"275a8dd8",4311:"b2147b80",4536:"5f58f78d",4590:"4cb53170",4595:"89aa0649",5411:"da92f910",5452:"e88c9444",5527:"15b691b6",5575:"87c3baf4",5742:"aba21aa0",5878:"eae929fd",5929:"59713e80",5957:"4d578846",6298:"47fe8a44",6440:"a7e6bfea",6635:"211ef201",6673:"d6644dbd",6699:"78008a53",7013:"b8b11332",7098:"a7bd4aaa",7121:"6f20431d",7183:"a68c8598",7233:"b0d08c50",7473:"35bdca39",7484:"197c6470",7519:"d643000e",7824:"99b6ceef",7895:"98797543",8241:"8932e155",8401:"17896441",8528:"f168c850",8539:"df724892",8846:"3c3a6abf",8883:"e694b58a",8932:"45d8935a",8983:"2d03fd69",9030:"e76d947a",9048:"a94703ab",9130:"6ba57622",9272:"d555a461",9346:"3aa86a4e",9363:"20561a1f",9367:"1b0c73d8",9381:"e38a37f7",9429:"b57ec343",9629:"23136fa4",9647:"5e95c892",9750:"191458e8"}[e]||e)+"."+{106:"5aa1ca7c",264:"7ec790e9",272:"5d6dfd58",416:"dcbb754b",421:"64bdaa83",593:"4f132f1e",596:"c7be84c1",714:"733cf097",766:"0d1841ff",769:"79daacc6",791:"2aeec6d1",849:"66a722c0",877:"32ccc941",957:"d2a1ccd2",1169:"229acd22",1176:"720b0dab",1207:"263e1268",1235:"0657152a",1245:"b0b268af",1303:"a67395f2",1331:"3ed28bac",1398:"72e4cd3d",1628:"faa65b99",1678:"95fed6b9",1914:"0c4b985f",1927:"f1f10350",1946:"db52ce41",2034:"629cd0d3",2074:"5be54119",2130:"6d5eb029",2138:"14f72b3d",2237:"f51eb88e",2376:"14981e3e",2396:"5d80e4a7",2426:"d271acc5",2433:"fea77b0a",2453:"99f545b0",2548:"61b63049",2563:"a135f3a6",2634:"a4ce9b79",2756:"f27683c4",2774:"9a0cdf52",2838:"f2b4b987",2843:"bc6ad154",2854:"15476025",2925:"984212c4",2969:"6ed80c7a",2974:"696de506",2983:"458917e3",3047:"5ffb7190",3068:"51abbdc6",3108:"343f1f91",3115:"c143ad9c",3230:"9941a481",3269:"f2f24f18",3460:"561408c9",3583:"d1b3d0e7",3623:"94c750b8",3626:"7c4e66e5",3706:"2eb2c015",3829:"313bf0b6",4154:"5ab21d8a",4162:"c89bd0b9",4179:"e339b4d1",4304:"d95e6543",4311:"2e6b1e4e",4536:"8740cfc7",4590:"162ffa2a",4595:"dab8b68d",4741:"571f4af4",4943:"192b1fc9",5411:"cf7f72ad",5452:"15f400c9",5527:"7b31708e",5575:"a4c07e79",5742:"149d4ec6",5878:"be00a9f7",5929:"ccc1a7f4",5957:"44edba23",6298:"7276f55f",6420:"bd99f30c",6440:"a5a7bdee",6635:"4d81c63e",6673:"9499612f",6699:"9fa372ba",6788:"df2e2724",6803:"3757e69d",6911:"965be4da",7013:"319e6b97",7098:"3339cb44",7121:"d98b5a17",7183:"ae91e846",7233:"c3b4eef8",7426:"afe19e78",7473:"f04ee808",7484:"efbc9c53",7519:"d446e865",7824:"050e340e",7895:"b058575e",8055:"c58cfabc",8158:"e40616bd",8241:"1bdfc846",8401:"901bc284",8478:"8ad0349a",8528:"4eb8c53a",8539:"2d625697",8635:"9bf77743",8810:"f27d31b0",8846:"732a433a",8869:"01feebe9",8883:"b526c11f",8913:"1a661a19",8932:"277db7da",8983:"9af7fc0b",9030:"ca9ff988",9048:"364c6e9c",9130:"a70390a8",9272:"4f78c977",9346:"e7ebb29f",9363:"5342e21e",9367:"5df6020c",9381:"2bc64e2e",9429:"389f6634",9629:"5b12b125",9647:"4b59a626",9689:"a9bf4169",9750:"c4d2bac7"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},b="bee-docs:",r.l=(e,a,f,c)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var b=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(f))),a)return a(f)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={17896441:"8401",98797543:"7895",f375a06e:"106",df2717bb:"264",f6879adf:"272",d474cb3a:"421","5292c32b":"593",a0798b91:"596","000d6678":"714",a7d5385f:"766","1783be55":"769",f7a6d479:"791","0058b4c6":"849","6bac647a":"877",c141421f:"957",a7456010:"1235","5ee72a4b":"1628",ff1e3514:"1678","243e784f":"1914",e75f3413:"1927","06809660":"2034","51e16090":"2074","1a4e3797":"2138","9594edf7":"2396","032f5f3f":"2426",f7f0193b:"2433","2fb51a8e":"2563",c4f5d8e4:"2634","098f45c6":"2774",e4170b6f:"2854",f0ad3fbb:"2969","88edeb39":"2974","1c690199":"3047","0665e5d4":"3108","8497dad5":"3115",b35a7c50:"3230","10af94c2":"3269",b0c952a3:"3460",d181d228:"3583",a23930e7:"3623","8c5f7849":"3829",b57c29d7:"4154","5bb09754":"4179","275a8dd8":"4304",b2147b80:"4311","5f58f78d":"4536","4cb53170":"4590","89aa0649":"4595",da92f910:"5411",e88c9444:"5452","15b691b6":"5527","87c3baf4":"5575",aba21aa0:"5742",eae929fd:"5878","59713e80":"5929","4d578846":"5957","47fe8a44":"6298",a7e6bfea:"6440","211ef201":"6635",d6644dbd:"6673","78008a53":"6699",b8b11332:"7013",a7bd4aaa:"7098","6f20431d":"7121",a68c8598:"7183",b0d08c50:"7233","35bdca39":"7473","197c6470":"7484",d643000e:"7519","99b6ceef":"7824","8932e155":"8241",f168c850:"8528",df724892:"8539","3c3a6abf":"8846",e694b58a:"8883","45d8935a":"8932","2d03fd69":"8983",e76d947a:"9030",a94703ab:"9048","6ba57622":"9130",d555a461:"9272","3aa86a4e":"9346","20561a1f":"9363","1b0c73d8":"9367",e38a37f7:"9381",b57ec343:"9429","23136fa4":"9629","5e95c892":"9647","191458e8":"9750"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)f.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var b=new Promise(((f,b)=>d=e[a]=[f,b]));f.push(d[2]=b);var c=r.p+r.u(a),t=new Error;r.l(c,(f=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var b=f&&("load"===f.type?"missing":f.type),c=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+b+": "+c+")",t.name="ChunkLoadError",t.type=b,t.request=c,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var d,b,c=f[0],t=f[1],o=f[2],n=0;if(c.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(f);n - + diff --git a/docs/bee/bee-faq/index.html b/docs/bee/bee-faq/index.html index 6543b526..9b0efa80 100644 --- a/docs/bee/bee-faq/index.html +++ b/docs/bee/bee-faq/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/build-from-source/index.html b/docs/bee/installation/build-from-source/index.html index efb1cd00..bbdd0749 100644 --- a/docs/bee/installation/build-from-source/index.html +++ b/docs/bee/installation/build-from-source/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/connectivity/index.html b/docs/bee/installation/connectivity/index.html index 0221e55a..f4cf6ad0 100644 --- a/docs/bee/installation/connectivity/index.html +++ b/docs/bee/installation/connectivity/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/docker/index.html b/docs/bee/installation/docker/index.html index 982338d2..c515af27 100644 --- a/docs/bee/installation/docker/index.html +++ b/docs/bee/installation/docker/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/fund-your-node/index.html b/docs/bee/installation/fund-your-node/index.html index a31eb319..0572fecc 100644 --- a/docs/bee/installation/fund-your-node/index.html +++ b/docs/bee/installation/fund-your-node/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/hive/index.html b/docs/bee/installation/hive/index.html index d632d89a..1b688004 100644 --- a/docs/bee/installation/hive/index.html +++ b/docs/bee/installation/hive/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/install/index.html b/docs/bee/installation/install/index.html index e8b8c927..57c92544 100644 --- a/docs/bee/installation/install/index.html +++ b/docs/bee/installation/install/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/quick-start/index.html b/docs/bee/installation/quick-start/index.html index 4400f1e9..b6b3b0fc 100644 --- a/docs/bee/installation/quick-start/index.html +++ b/docs/bee/installation/quick-start/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/installation/verify/index.html b/docs/bee/installation/verify/index.html index b4632bc3..4984fba5 100644 --- a/docs/bee/installation/verify/index.html +++ b/docs/bee/installation/verify/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/backups/index.html b/docs/bee/working-with-bee/backups/index.html index 206cc3a0..fd64d3e7 100644 --- a/docs/bee/working-with-bee/backups/index.html +++ b/docs/bee/working-with-bee/backups/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/bcrypt/index.html b/docs/bee/working-with-bee/bcrypt/index.html index 5f772cf7..e117f991 100644 --- a/docs/bee/working-with-bee/bcrypt/index.html +++ b/docs/bee/working-with-bee/bcrypt/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/bee-api/index.html b/docs/bee/working-with-bee/bee-api/index.html index 3d3943e4..092d8602 100644 --- a/docs/bee/working-with-bee/bee-api/index.html +++ b/docs/bee/working-with-bee/bee-api/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/bee-dashboard/index.html b/docs/bee/working-with-bee/bee-dashboard/index.html index 18cc8c45..508efc7a 100644 --- a/docs/bee/working-with-bee/bee-dashboard/index.html +++ b/docs/bee/working-with-bee/bee-dashboard/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/cashing-out/index.html b/docs/bee/working-with-bee/cashing-out/index.html index 88dafd63..9def6bdf 100644 --- a/docs/bee/working-with-bee/cashing-out/index.html +++ b/docs/bee/working-with-bee/cashing-out/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/configuration/index.html b/docs/bee/working-with-bee/configuration/index.html index b6435d0b..ec36b7a4 100644 --- a/docs/bee/working-with-bee/configuration/index.html +++ b/docs/bee/working-with-bee/configuration/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/introduction/index.html b/docs/bee/working-with-bee/introduction/index.html index 3adf5b80..5b68fa58 100644 --- a/docs/bee/working-with-bee/introduction/index.html +++ b/docs/bee/working-with-bee/introduction/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/light-nodes/index.html b/docs/bee/working-with-bee/light-nodes/index.html index 368f6846..be40bc5e 100644 --- a/docs/bee/working-with-bee/light-nodes/index.html +++ b/docs/bee/working-with-bee/light-nodes/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/logs-and-files/index.html b/docs/bee/working-with-bee/logs-and-files/index.html index a52bc376..1f923446 100644 --- a/docs/bee/working-with-bee/logs-and-files/index.html +++ b/docs/bee/working-with-bee/logs-and-files/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/monitoring/index.html b/docs/bee/working-with-bee/monitoring/index.html index fddb2aaa..f875666a 100644 --- a/docs/bee/working-with-bee/monitoring/index.html +++ b/docs/bee/working-with-bee/monitoring/index.html @@ -10,7 +10,7 @@ - + diff --git a/docs/bee/working-with-bee/staking/index.html b/docs/bee/working-with-bee/staking/index.html index 362e5bcb..abf447f5 100644 --- a/docs/bee/working-with-bee/staking/index.html +++ b/docs/bee/working-with-bee/staking/index.html @@ -10,7 +10,7 @@ - + @@ -60,6 +60,48 @@

Withdraw available stake

If there is any stake available for withdrawal, you can withdraw it using the DELETE method on /stake/withdrawable:

curl -X DELETE http://localhost:1633/stake/withdrawable
+

Reserve Doubling

+

The reserve doubling feature enables nodes to store chunks from a neighboring "sister" area, effectively increasing their reserve capacity twofold. By maintaining chunks from this sister neighborhood, a node becomes eligible to join the redistribution game whenever the sister neighborhood is chosen, effectively doubling its chances of participating.

+

Although reserve doubling demands twice the disk storage and increases bandwidth usage for chunk syncing (with no additional bandwidth needed for chunk forwarding), its effect on CPU and RAM consumption remains minimal. This feature provides node operators with greater flexibility to optimize their nodes, aiming to achieve a higher reward-to-resource usage ratio.

+

Step by Step Guide

+

In order to double a node's reserve which has previously been operating without doubling, the reserve-capacity-doubling option must be updated from the default of 0 to 1 and restarted. There is also an increase in the xBZZ stake requirement from the minimum of 10 xBZZ to 20 xBZZ.

+

Step 1: Stake at least 20 xBZZ

+

For doubling the reserve of a node which was previously operating which already has 10 xBZZ staked, simply stake an additional 10 xBZZ for a total of 20 xBZZ stake:

+
info

As always, make sure that to properly convert the stake parameter to PLUR where 1 PLUR is equal to 1e-16 xBZZ. As in our example below, we have converted from 10 xBZZ to 100000000000000000 PLUR.

+
curl -X POST localhost:1633/stake/100000000000000000
+

Or for a new node with zero staked xBZZ, the entire 20 xBZZ can be staked at once:

+
curl -X POST localhost:1633/stake/200000000000000000
+

We can use the GET /stake endpoint to confirm the total stake for our node:

+
curl -s  http://localhost:1633/stake | jq
+
{
"stakedAmount": "200000000000000000"
}
+

Step 2: Set reserve-capacity-doubling to 1.

+

The reserve doubling feature can be enabled by setting the new reserve-capacity-doubling config option to 1 using the configuration method of your choice.

+

Step 3: Restart node

+

After ensuring the node has at least 20 xBZZ staked and the reserve-capacity-doubling option has been set to 1, restart the node.

+

After restarting your node, it should then begin syncing chunks from its sister neighborhood.

+

The /status/neighborhoods endpoint can be used to confirm that the node has doubled its reserve and is now syncing with its sister neighborhood:

+
{
"neighborhoods": [
{
"neighborhood": "01111101011",
"reserveSizeWithinRadius": 1148351,
"proximity": 10
},
{
"neighborhood": "01111101010",
"reserveSizeWithinRadius": 1147423,
"proximity": 11
}
]
}
+

The expected output should contain two neighborhoods, the node's original neighborhood along with its sister neighborhood.

+

We can also check the /status endpoint to confirm our node is syncing new chunks:

+
curl -s  http://localhost:1633/status | jq
+
{
"overlay": "be177e61b13b1caa20690311a909bd674a3c1ef5f00d60414f261856a8ad5c30",
"proximity": 256,
"beeMode": "full",
"reserveSize": 4192792,
"reserveSizeWithinRadius": 2295023,
"pullsyncRate": 1.3033333333333332,
"storageRadius": 10,
"connectedPeers": 18,
"neighborhoodSize": 1,
"batchCommitment": 388104192,
"isReachable": true,
"lastSyncedBlock": 6982430
}
+

We can see that the pullsyncRate value is above zero, meaning that our node is currently syncing chunks, as expected.

+

Reserve Doubling Reversing & Withdrawable Stake

+

Due to certain implementation details, the order in which a node's reserve is doubled and then reversed can have an impact on the amount of withdrawable stake.

+

When doubling a node's reserve, stake should be added AFTER +setting reserve-capacity-doubling to 1. If instead, xBZZ is first staked with reserve-capacity-doubling set to 0, and the reserve is then doubled by increasing from 0 to 1 without the addition of more stake, this will prevent stake from being withdrawable when the doubling is reversed.

+

In order to maximize the amount of withdrawable stake after reversing a reserve doubling, follow the step from the previous section in the exact order described when doubling.

+

How to free up withdrawable stake from a node with >= 20 xBZZ stake that currently has zero withdrawable stake:

+

In the case that a node with 20 xBZZ stake was doubled directly by increasing reserve-capacity-doubling from 0 to 1, the surplus xBZZ over the minimum required 10 xBZZ cannot be made withdrawable by simply reversing the reserve-capacity-doubling from 1 back to 0.

+

In this case, you will need to first send a very small staking transaction of a single PLUR while reserve-capacity-doubling is set to 1, and after that, change reserve-capacity-doubling from 1 to 0. This works because every time any amount of stake is added, it forces to staking contract to redo its calculations.

+

The detailed steps are:

+
    +
  1. Issue a staking transaction for 1 PLUR while reserve-capacity-doubling is set to 1. +
    curl -X POST localhost:1633/stake/1
    +
  2. +
  3. Stop node and set reserve-capacity-doubling to 0.
  4. +
  5. Restart node. The 10 xBZZ should now be withdrawable.
  6. +

Maximize rewards

There are two main factors which determine the chances for a staking node to win a reward — neighborhood selection and stake density. Both of these should be considered together before starting up a Bee node for the first time. See the incentives page for more context.

Neighborhood selection

@@ -163,6 +205,6 @@