{"id":29560887,"url":"https://github.com/decred/dcrstakepool","last_synced_at":"2025-10-14T15:43:06.450Z","repository":{"id":3989622,"uuid":"54925829","full_name":"decred/dcrstakepool","owner":"decred","description":"Stakepool for Decred.","archived":false,"fork":false,"pushed_at":"2023-07-05T21:02:43.000Z","size":4561,"stargazers_count":74,"open_issues_count":40,"forks_count":74,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-08-11T23:21:41.698Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/decred.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-28T21:44:13.000Z","updated_at":"2024-11-30T12:20:42.000Z","dependencies_parsed_at":"2024-06-18T21:20:47.461Z","dependency_job_id":"b55f61f0-ba9a-4fcd-a157-09ca82a34cd9","html_url":"https://github.com/decred/dcrstakepool","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/decred/dcrstakepool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decred%2Fdcrstakepool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decred%2Fdcrstakepool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decred%2Fdcrstakepool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decred%2Fdcrstakepool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/decred","download_url":"https://codeload.github.com/decred/dcrstakepool/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/decred%2Fdcrstakepool/sbom","scorecard":{"id":331583,"data":{"date":"2025-08-11","repo":{"name":"github.com/decred/dcrstakepool","commit":"4c8a2c32098b5e8d01fb3dfce49c5aed9e5e46fb"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/decred/dcrstakepool/go.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/decred/dcrstakepool/go.yml/master?enable=pin","Warn: downloadThenRun not pinned by hash: .github/workflows/go.yml:19","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"10 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2020-0017 / GHSA-w73w-5m7g-f7qc","Warn: Project is vulnerable to: GO-2025-3607 / GHSA-rq77-p4h8-4crw","Warn: Project is vulnerable to: GO-2021-0227 / GHSA-3vm4-22fp-5rfm","Warn: Project is vulnerable to: GO-2022-0968 / GHSA-gwc9-m7rh-j2ww","Warn: Project is vulnerable to: GO-2021-0356 / GHSA-8c26-wmh5-6g9v","Warn: Project is vulnerable to: GO-2024-2961","Warn: Project is vulnerable to: GO-2023-2402 / GHSA-45x7-px36-x8w8","Warn: Project is vulnerable to: GO-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2023-2153 / GHSA-m425-mq94-257g / GHSA-qppj-fm5r-hxr3"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T03:46:43.159Z","repository_id":3989622,"created_at":"2025-08-18T03:46:43.160Z","updated_at":"2025-08-18T03:46:43.160Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279019347,"owners_count":26086711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-18T15:39:16.491Z","updated_at":"2025-10-14T15:43:06.401Z","avatar_url":"https://github.com/decred.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"dcrstakepool\n============\n\n[![Build Status](https://github.com/decred/dcrstakepool/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/dcrstakepool/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/decred/dcrstakepool)](https://goreportcard.com/report/github.com/decred/dcrstakepool)\n[![Doc](https://img.shields.io/badge/doc-reference-blue.svg)](https://pkg.go.dev/github.com/decred/dcrstakepool)\n\n## :warning: Deprecation Notice :warning:\n\n**dcrstakepool is a deprecated project and support will soon be removed from\nwallets. All VSP operators should switch to\n[vspd](https://github.com/decred/vspd). Visit the [Decred\nBlog](https://blog.decred.org/2020/06/02/A-More-Private-Way-to-Stake/) to find\nout more about this change.**\n\n## Overview\n\ndcrstakepool is a web application which coordinates generating 1-of-2 multisig\naddresses on a pool of [dcrwallet](https://github.com/decred/dcrwallet) servers\nso users can purchase [proof-of-stake tickets](https://docs.decred.org/mining/proof-of-stake/)\non the [Decred](https://decred.org/) network and have the pool of wallet servers\nvote on their behalf when the ticket is selected.\n\n**NB:** In late 2018, [a proposal](https://proposals.decred.org/proposals/522652954ea7998f3fca95b9c4ca8907820eb785877dcf7fba92307131818c75)\nwas approved by stakeholders to rename \"Stakepool\" to \"Voting Service Provider\", a.k.a. \"VSP\".\nThese names are used interchangably in this repository.\n\n## Architecture\n\n![Voting Service Architecture](docs/img/architecture.png)\n\n- It is highly recommended to use at least 2 dcrd+dcrwallet+stakepoold\n  nodes (backend servers) for production use on mainnet.\n  One backend server can be used on testnet.\n- Running dcrstakepool on mainnet is documented further at\n  [https://docs.decred.org](https://docs.decred.org/advanced/operating-a-vsp/).\n- The architecture is subject to change in the future to lessen the dependence\n  on MySQL.\n\n## Test Harness\n\nA test harness is provided in `./harness.sh`. The test harness uses tmux to start\na dcrd node, multiple dcrwallet and stakepoold instances, and finally a dcrstakepool\ninstance. It uses hard-coded wallet seeds and pubkeys, and as a result it is only\nsuitable for use on testnet. Further documentation can be found in `./harness.sh`.\n\n## Requirements\n\n- [Go](https://golang.org) 1.15 or newer.\n- MySQL.\n- A web server, such as nginx, to proxy to dcrstakepool.\n\n## Installation\n\n### Build from source\n\nBuilding or updating from source requires the following build dependencies:\n\n- **Go 1.15 or newer**\n\nBuilding or updating from source requires only an installation of Go\n([instructions](https://golang.org/doc/install)). It is recommended to add\n`$GOPATH/bin` to your `PATH` at this point.\n\nTo build and install from a checked-out repo, run `go install . ./backend/stakepoold`\nin the repo's root directory.\n\n* Set the `GO111MODULE=on` environment variable if building from within\n  `GOPATH`.\n\n## Updating\n\nPlease defer to the 1.5.0 [release notes](docs/release-note-1.5.0.md/#recommended-upgrade-path).\n\n## Setup\n\n### Pre-requisites\n\nThese instructions assume you are familiar with dcrd/dcrwallet.\n\n- Create basic dcrd/dcrwallet/dcrctl config files with usernames, passwords,\n  rpclisten, and network set appropriately within them or run example commands\n  with additional flags as necessary.\n\n- Build/install dcrd and dcrwallet from latest master.\n\n- Run dcrd instances and let them fully sync.\n\n### Voting service fees/cold wallet\n\n- Setup a new wallet for receiving payment for voting service fees.  **This should\n  be completely separate from the voting service infrastructure.**\n- From your local machine...\n\n```bash\n$ dcrwallet --create\n$ dcrwallet\n```\n\n- Get the master pubkey for the account you wish to use. This will be needed to\n  configure dcrwallet and dcrstakepool.\n\n```bash\n$ dcrctl --wallet createnewaccount stakepoolfees\n$ dcrctl --wallet getmasterpubkey stakepoolfees\n```\n\n- Mark 10000 addresses in use for the account so the wallet will recognize\n  transactions to those addresses. Fees from UserId 1 will go to address 1,\n  UserId 2 to address 2, and so on.\n\n```bash\n$ dcrctl --wallet accountsyncaddressindex stakepoolfees 0 10000\n```\n\n### Voting service voting wallets\n\n- Create the wallets.  All wallets should have the same seed.  **Backup the seed\n  for disaster recovery!**\n- Log into wallet servers separately and create wallets one at a time using the\n  same seed.\n\n```bash\n$ ssh walletserver1\n$ dcrwallet --create\n```\n\n- Start a properly configured dcrwallet and unlock it. See\n  sample-dcrwallet.conf.\n- From your local machine...\n\n```bash\n$ cp sample-dcrwallet.conf dcrwallet.conf\n$ vim dcrwallet.conf\n$ scp dcrwallet.conf walletserver1:~/.dcrwallet/\n$ ssh walletserver1\n$ dcrwallet\n```\n\n- Get the master pubkey from the default account.  This will be used for\n  votingwalletextpub in dcrstakepool.conf.\n\n```bash\n$ ssh walletserver1\n$ dcrctl --wallet getmasterpubkey default\n```\n\n### MySQL\n\n- Log into your frontend\n- Install, configure, and start MySQL\n- Add stakepool user and create the stakepool database\n\n```bash\n$ ssh frontendserver\n$ mysql -uroot -p\n\nMySQL\u003e CREATE USER 'stakepool'@'localhost' IDENTIFIED BY 'password';\nMySQL\u003e GRANT ALL PRIVILEGES ON *.* TO 'stakepool'@'localhost' WITH GRANT OPTION;\nMySQL\u003e FLUSH PRIVILEGES;\nMySQL\u003e CREATE DATABASE stakepool;\n```\n\n### Nginx/web server\n\n- Adapt sample-nginx.conf or setup a different web server in a proxy\n  configuration. To prepare pre-zipped files to save the reverse proxy the\n  trouble of compressing data on-the-fly, see the zipassets.sh script.\n\n### stakepoold setup\n\n- Copy sample config and edit appropriately.\n- From your local machine...\n\n```bash\n$ mkdir .stakepoold\n$ cp sample-stakepoold.conf .stakepoold/stakepoold.conf\n$ vim .stakepoold/stakepoold.conf\n$ scp -r .stakepoold walletserver1:~/\n$ scp -r .stakepoold walletserver2:~/\n```\n\n- Build and copy the stakepoold executable to each wallet server.\n- From your local machine...\n\n```bash\n$ cd backend/stakepoold/\n$ go build\n$ scp stakepoold walletserver1:~/\n$ scp stakepoold walletserver2:~/\n```\n\n### dcrstakepool setup\n\n- Create the .dcrstakepool directory and copy dcrwallet certs to it:\n\n```bash\n$ ssh frontendserver\n$ mkdir ~/.dcrstakepool\n$ cd ~/.dcrstakepool\n$ scp walletserver1:~/.dcrwallet/rpc.cert wallet1.cert\n$ scp walletserver2:~/.dcrwallet/rpc.cert wallet2.cert\n$ scp walletserver1:~/.stakepoold/rpc.cert stakepoold1.cert\n$ scp walletserver2:~/.stakepoold/rpc.cert stakepoold2.cert\n```\n\n- Copy sample config and edit appropriately.\n- From your local machine...\n\n```bash\n$ cp sample-dcrstakepool.conf dcrstakepool.conf\n$ vim dcrstakepool.conf\n$ scp dcrstakepool.conf frontendserver:~/.dcrstakepool/\n```\n\n- Build and copy the entire dcrstakepool folder to your frontend.\n- From your local machine...\n\n```bash\n$ go build\n$ scp -r ../dcrstakepool frontendserver:~/\n```\n\n## Running\n\n### stakepoold\n\nLog into all servers and run stakepoold one at a time.\n\n```bash\n$ ssh walletserver1\n$ ./stakepoold\n```\n\n### dcrstakepool\n\nLog into your frontend and run dcrstakepool\n\n```bash\n$ ssh frontendserver\n$ cd dcrstakepool\n$ ./dcrstakepool\n```\n\nTo run `dcrstakepool` from another folder, such as `/opt/dcrstakepool`, it is\nnecessary to copy (1) the `dcrstakepool` executable generated by `go build`, (2)\nthe `public` folder, and (3) the `views` folder into the other folder.\n\nBy default, `dcrstakepool` looks for the `public` and `views` folders in the\nsame parent directory as the `dcrstakepool` executable. If you wish to run\ndcrstakepool from a different directory you will need to change **publicpath**\nand **templatepath** from their relative paths to an absolute path.\n\n## Development\n\nIf you are modifying templates, sending the USR1 signal to the dcrstakepool\nprocess will trigger a template reload.\n\n### Protoc\n\nThe RPC interface between dcrstakepool and stakepoold is defined in\n`./backend/stakepoold/rpc/api.proto`.\nIf modifications are made to this file, `api.pb.go` needs to be regenerated\nusing the script `./backend/stakepoold/rpc/regen.sh`.\nThe following tools are required to run the script:\n\n- [libprotoc](https://github.com/protocolbuffers/protobuf) 3.11.4 or later\n- [protoc-gen-go](https://github.com/golang/protobuf) 1.3.4 or later\n\n## Operations\n\n- dcrstakepool will connect to the database or error out if it cannot do so.\n\n- dcrstakepool will create the stakepool.Users table automatically if it doesn't\n  exist.\n\n- dcrstakepool attempts to connect to all of the stakepoold servers on startup or\n  error out if it cannot do so.\n\n- dcrstakepool takes a user's pubkey, validates it, calls getnewaddress on all\n  the wallet servers, then createmultisig, and finally importscript.  If any of\n  these RPCs fail or returns inconsistent results, the RPC client built-in to\n  dcrstakepool will shut down and will not operate until it has been restarted.\n  Wallets should be verified to be in sync before restarting.\n\n- User API Tokens have an issuer field set to baseURL from the configuration file.\n  Changing the baseURL requires all API Tokens to be re-generated.\n\n## Adding Invalid Tickets\n\n### For Newer versions / git tip\n\nIf a user pays an incorrect fee, login as an account that meets the\nadminUserIps and adminUserIds restrictions and click the 'Add Low Fee Tickets'\nlink in the menu.  You will be presented with a list of tickets that are\nsuitable for adding.  Check the appropriate one(s) and click the submit button.\nUpon success, you should see the stakepoold logs reflect that the new tickets\nwere processed.\n\n### For v1.1.1 and below\n\nIf a user pays an incorrect fee you may add their tickets like so (requires dcrd\nrunning with `txindex=1`):\n\n```bash\ndcrctl --wallet stakepooluserinfo \"MultiSigAddress\" | grep -Pzo '(?\u003c=\"invalid\": \\[)[^\\]]*' | tr -d , | xargs -Itickethash dcrctl --wallet getrawtransaction tickethash | xargs -Itickethex dcrctl --wallet addticket \"tickethex\"\n```\n\n## Backups, monitoring, security considerations\n\n- MySQL should be backed up often and regularly (probably at least hourly).\n  Backups should be transferred off-site.  If using binary backups, do a test\n  restore. For .sql files, verify visually.\n\n- A monitoring system with alerting should be pointed at dcrstakepool and\n  tested/verified to be operating properly.  There is a hidden /status page\n  which throws 500 if the RPC client is shutdown.  If your monitoring system\n  supports it, add additional points of verification such as: checking that the\n  /stats page loads and has expected information in it, create a test account\n  and setup automated login testing, etc.\n\n- Wallets should never be used for anything else (they should always have a\n  balance of 0).\n\n## Disaster Recovery\n\n**Always keep at least one wallet voting while performing maintenance / restoration!**\n\n- In the case of a total failure of a wallet server:\n  - Restore the failed wallet(s) from seed.\n  - Restart the dcrstakepool process to allow automatic syncing to occur.\n\n## Getting help\n\nTo get help with `dcrstakepool` please create a\n[GitHub issue](https://github.com/decred/dcrstakepool/issues)\nor the join the [Decred community](https://decred.org/community/)\nusing your preferred chat platform.\n\n## License\n\ndcrstakepool is licensed under the [copyfree](http://copyfree.org) MIT/X11 and\nISC Licenses.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdecred%2Fdcrstakepool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdecred%2Fdcrstakepool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdecred%2Fdcrstakepool/lists"}