├── .bingo ├── .gitignore ├── README.md ├── Variables.mk ├── bingo.mod ├── buf.mod ├── go.mod ├── gomplate.mod ├── govvv.mod ├── gox.mod ├── protoc-gen-buf-breaking.mod ├── protoc-gen-buf-lint.mod ├── protoc-gen-go-grpc.mod ├── protoc-gen-go.mod └── variables.env ├── .dockerignore ├── .github ├── dependabot.yml ├── release-drafter.yml ├── weekly-digest.yml └── workflows │ ├── buf.yml │ ├── docker.yml │ ├── ensure-docs.yml │ ├── release-drafter.yml │ ├── release.yml │ ├── review.yml │ └── test.yml ├── .gitignore ├── .golangci.yml ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── api ├── client │ ├── admin │ │ ├── admin.go │ │ ├── data.go │ │ ├── indices.go │ │ ├── options.go │ │ ├── records.go │ │ ├── storageinfo.go │ │ ├── storagejobs.go │ │ ├── users.go │ │ └── wallet.go │ ├── admin_test.go │ ├── client.go │ ├── client_test.go │ ├── data.go │ ├── deals.go │ ├── storageconfig.go │ ├── storageinfo.go │ ├── storagejobs.go │ ├── utils_test.go │ ├── wallet.go │ └── wallet_test.go ├── gen │ └── powergate │ │ ├── admin │ │ └── v1 │ │ │ ├── admin.pb.go │ │ │ └── admin_grpc.pb.go │ │ └── user │ │ └── v1 │ │ ├── user.pb.go │ │ └── user_grpc.pb.go └── server │ ├── admin │ ├── hs.go │ ├── indices.go │ ├── jobs.go │ ├── records.go │ ├── service.go │ ├── storageinfo.go │ ├── users.go │ └── wallet.go │ ├── server.go │ ├── user │ ├── data.go │ ├── deals.go │ ├── service.go │ ├── storageconfig.go │ ├── storageinfo.go │ ├── storagejobs.go │ ├── util.go │ └── wallet.go │ └── util │ └── util.go ├── buf.yaml ├── buildinfo └── buildinfo.go ├── chainstore ├── chainstore.go └── chainstore_test.go ├── chainsync ├── chainsync.go └── chainsync_test.go ├── cli-docs └── pow │ ├── pow.md │ ├── pow_admin.md │ ├── pow_admin_data.md │ ├── pow_admin_data_gcstaged.md │ ├── pow_admin_data_pinnedcids.md │ ├── pow_admin_storage-info.md │ ├── pow_admin_storage-info_get.md │ ├── pow_admin_storage-info_list.md │ ├── pow_admin_storage-jobs.md │ ├── pow_admin_storage-jobs_list.md │ ├── pow_admin_storage-jobs_summary.md │ ├── pow_admin_users.md │ ├── pow_admin_users_create.md │ ├── pow_admin_users_list.md │ ├── pow_admin_users_regenerate.md │ ├── pow_admin_wallet.md │ ├── pow_admin_wallet_addrs.md │ ├── pow_admin_wallet_new.md │ ├── pow_admin_wallet_send.md │ ├── pow_config.md │ ├── pow_config_apply.md │ ├── pow_config_default.md │ ├── pow_config_remove.md │ ├── pow_config_set-default.md │ ├── pow_data.md │ ├── pow_data_get.md │ ├── pow_data_info.md │ ├── pow_data_log.md │ ├── pow_data_replace.md │ ├── pow_data_stage.md │ ├── pow_data_summary.md │ ├── pow_deals.md │ ├── pow_deals_retrievals.md │ ├── pow_deals_storage.md │ ├── pow_id.md │ ├── pow_offline.md │ ├── pow_offline_car.md │ ├── pow_offline_commp.md │ ├── pow_offline_prepare.md │ ├── pow_storage-info.md │ ├── pow_storage-info_get.md │ ├── pow_storage-info_list.md │ ├── pow_storage-jobs.md │ ├── pow_storage-jobs_cancel-executing.md │ ├── pow_storage-jobs_cancel-queued.md │ ├── pow_storage-jobs_cancel.md │ ├── pow_storage-jobs_get.md │ ├── pow_storage-jobs_list.md │ ├── pow_storage-jobs_storage-config.md │ ├── pow_storage-jobs_summary.md │ ├── pow_storage-jobs_watch.md │ ├── pow_version.md │ ├── pow_wallet.md │ ├── pow_wallet_addrs.md │ ├── pow_wallet_balance.md │ ├── pow_wallet_new-addr.md │ ├── pow_wallet_send.md │ ├── pow_wallet_sign.md │ └── pow_wallet_verify.md ├── cmd ├── migrtest │ ├── README.md │ └── main.go ├── pow │ ├── cmd │ │ ├── admin │ │ │ ├── admin.go │ │ │ ├── data │ │ │ │ ├── data.go │ │ │ │ ├── gcstaged │ │ │ │ │ └── gcstaged.go │ │ │ │ └── pinnedcids │ │ │ │ │ └── pinnedcids.go │ │ │ ├── storageinfo │ │ │ │ ├── get │ │ │ │ │ └── get.go │ │ │ │ ├── list │ │ │ │ │ └── list.go │ │ │ │ └── storageinfo.go │ │ │ ├── storagejobs │ │ │ │ ├── list │ │ │ │ │ └── list.go │ │ │ │ ├── storagejobs.go │ │ │ │ └── summary │ │ │ │ │ └── summary.go │ │ │ ├── users │ │ │ │ ├── create │ │ │ │ │ └── create.go │ │ │ │ ├── list │ │ │ │ │ └── list.go │ │ │ │ ├── regenerate │ │ │ │ │ └── regenerate.go │ │ │ │ └── users.go │ │ │ └── wallet │ │ │ │ ├── addrs │ │ │ │ └── addrs.go │ │ │ │ ├── new │ │ │ │ └── new.go │ │ │ │ ├── send │ │ │ │ └── send.go │ │ │ │ └── wallet.go │ │ ├── config │ │ │ ├── apply │ │ │ │ └── apply.go │ │ │ ├── config.go │ │ │ ├── getdefault │ │ │ │ └── getdefault.go │ │ │ ├── remove │ │ │ │ └── remove.go │ │ │ └── setdefault │ │ │ │ └── setdefault.go │ │ ├── data │ │ │ ├── data.go │ │ │ ├── get │ │ │ │ └── get.go │ │ │ ├── info │ │ │ │ └── info.go │ │ │ ├── log │ │ │ │ └── log.go │ │ │ ├── replace │ │ │ │ └── replace.go │ │ │ ├── stage │ │ │ │ └── stage.go │ │ │ └── summary │ │ │ │ ├── summary.go │ │ │ │ └── tui.go │ │ ├── deals │ │ │ ├── deals.go │ │ │ ├── retrievals │ │ │ │ └── retrievals.go │ │ │ └── storage │ │ │ │ └── storage.go │ │ ├── id │ │ │ └── id.go │ │ ├── pow.go │ │ ├── prepare │ │ │ ├── prepare.go │ │ │ └── prepare_test.go │ │ ├── storageinfo │ │ │ ├── get │ │ │ │ └── get.go │ │ │ ├── list │ │ │ │ └── list.go │ │ │ └── storageinfo.go │ │ ├── storagejobs │ │ │ ├── cancel │ │ │ │ └── cancel.go │ │ │ ├── cancelexecuting │ │ │ │ └── cancelexecuting.go │ │ │ ├── cancelqueued │ │ │ │ └── cancelqueued.go │ │ │ ├── get │ │ │ │ └── get.go │ │ │ ├── list │ │ │ │ └── list.go │ │ │ ├── storageconfig │ │ │ │ └── storageconfig.go │ │ │ ├── storagejobs.go │ │ │ ├── summary │ │ │ │ └── summary.go │ │ │ └── watch │ │ │ │ └── watch.go │ │ ├── version │ │ │ └── version.go │ │ └── wallet │ │ │ ├── addrs │ │ │ └── addrs.go │ │ │ ├── balance │ │ │ └── balance.go │ │ │ ├── newaddr │ │ │ └── newaddr.go │ │ │ ├── send │ │ │ └── send.go │ │ │ ├── sign │ │ │ └── sign.go │ │ │ ├── verify │ │ │ └── verify.go │ │ │ └── wallet.go │ ├── common │ │ └── common.go │ └── main.go ├── powbench │ ├── README.md │ ├── main.go │ └── runner │ │ ├── runner.go │ │ └── runner_test.go ├── powcfg │ ├── main.go │ ├── ratelim │ │ └── ratelim.go │ ├── testdata │ │ └── badgerdumpv1 │ │ │ ├── 000000.vlog │ │ │ ├── 000002.sst │ │ │ ├── KEYREGISTRY │ │ │ └── MANIFEST │ ├── transform.go │ ├── transform_test.go │ └── transformations.go └── powd │ └── main.go ├── dataprep └── dataprep.go ├── deals ├── module │ ├── deals.go │ ├── deals_test.go │ ├── dealwatcher │ │ ├── dealwatcher.go │ │ └── metrics.go │ ├── metrics.go │ ├── module.go │ ├── records.go │ ├── retrieve.go │ ├── store │ │ ├── metrics.go │ │ ├── store.go │ │ └── store_test.go │ └── util.go ├── options.go └── types.go ├── dist └── install.tmpl ├── docker ├── LICENSE ├── Makefile ├── dashboards │ └── System_Monitoring.json ├── docker-compose-localnet.yaml ├── docker-compose.yaml ├── grafana │ ├── config.monitoring │ └── provisioning │ │ ├── dashboards │ │ ├── TextileFC.json │ │ └── dashboard.yml │ │ └── datasources │ │ └── datasource.yml ├── ipfs-image.yaml ├── powergate-build-context.yaml ├── powergate-image.yaml └── prometheus │ └── prometheus.yml ├── docs └── manual_installation.md ├── fchost ├── config.go ├── fchost.go └── fchost_test.go ├── ffs ├── Design.md ├── api │ ├── api.go │ ├── api_actions.go │ ├── api_deals.go │ ├── api_jobs.go │ ├── api_logs.go │ ├── api_retrieval.go │ ├── api_storageinfo.go │ ├── api_wallet.go │ ├── istore.go │ ├── option.go │ └── types.go ├── auth │ └── auth.go ├── coreipfs │ ├── coreipfs.go │ ├── coreipfs_test.go │ └── internal │ │ └── pinstore │ │ └── pinstore.go ├── filcold │ ├── filcold.go │ └── metrics.go ├── integrationtest │ ├── config │ │ └── config_test.go │ ├── filters │ │ └── filters_test.go │ ├── general │ │ ├── cov.pprof │ │ └── general_test.go │ ├── importing │ │ └── importing_test.go │ ├── integrationtest.go │ ├── logger │ │ └── logger_test.go │ ├── manager │ │ └── manager.go │ ├── renew │ │ └── renew_test.go │ ├── repair │ │ └── repair_test.go │ ├── repfactor │ │ └── repfactor_test.go │ ├── replace │ │ └── replace_test.go │ ├── retrieval │ │ └── retrieval_test.go │ ├── scheduler │ │ └── scheduler_test.go │ ├── unfreeze │ │ └── unfreeze_test.go │ └── wallet │ │ └── wallet_test.go ├── interfaces.go ├── joblogger │ └── joblogger.go ├── manager │ ├── manager.go │ └── manager_test.go ├── minerselector │ ├── fixed │ │ └── fixed.go │ ├── reptop │ │ └── reptop.go │ └── sr2 │ │ ├── sr2.go │ │ └── sr2_test.go ├── scheduler │ ├── internal │ │ ├── astore │ │ │ └── astore.go │ │ ├── cistore │ │ │ └── cistore.go │ │ ├── ristore │ │ │ └── cistore.go │ │ ├── rjstore │ │ │ ├── rjstore.go │ │ │ └── rjstore_test.go │ │ ├── sjstore │ │ │ ├── metrics.go │ │ │ ├── sjstore.go │ │ │ └── sjstore_test.go │ │ └── trackstore │ │ │ ├── trackstore.go │ │ │ └── trackstore_test.go │ ├── scheduler.go │ ├── scheduler_import.go │ ├── scheduler_retrieval.go │ └── scheduler_storage.go └── types.go ├── filchain └── filchain.go ├── gateway ├── Makefile ├── assets.go ├── gateway.go └── public │ ├── css │ ├── all.min.css │ └── style.css │ ├── html │ ├── 404.gohtml │ ├── asks.gohtml │ ├── error.gohtml │ ├── faults.gohtml │ ├── index.gohtml │ ├── miners.gohtml │ └── reputation.gohtml │ └── img │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── hex.svg │ └── site.webmanifest ├── go.mod ├── go.sum ├── index ├── ask │ ├── internal │ │ └── store │ │ │ └── store.go │ ├── runner │ │ ├── metrics.go │ │ ├── runner.go │ │ └── runner_test.go │ └── types.go ├── faults │ ├── module │ │ ├── faults.go │ │ └── faults_test.go │ └── types.go └── miner │ ├── lotusidx │ ├── meta.go │ ├── metrics.go │ ├── miner.go │ ├── miner_test.go │ ├── onchain.go │ └── store │ │ └── store.go │ └── types.go ├── iplocation ├── iplocation.go └── maxmind │ ├── GeoLite2-City.mmdb │ ├── maxmind.go │ └── maxmind_test.go ├── lotus ├── client.go ├── client_test.go └── metrics.go ├── migration ├── migration.go ├── migration1.go ├── migration1_joblogger.go ├── migration1_joblogger_test.go ├── migration1_pinstore.go ├── migration1_pinstore_test.go ├── migration1_starteddeals.go ├── migration1_starteddeals_test.go ├── migration1_storageinfo.go ├── migration1_storageinfo_test.go ├── migration1_trackstore.go ├── migration1_trackstore_test.go ├── migration2.go ├── migration2_storageinfo_test.go ├── migration3.go ├── migration3_test.go ├── migration4.go ├── migration4_test.go ├── migration5.go ├── migration_test.go └── testdata │ ├── badgerdumpv0 │ ├── 000000.vlog │ ├── 000002.sst │ ├── KEYREGISTRY │ └── MANIFEST │ ├── badgerdumpv1 │ ├── 000000.vlog │ ├── 000002.sst │ ├── KEYREGISTRY │ └── MANIFEST │ ├── v1_JobLogger.post │ ├── v1_JobLogger.pre │ ├── v1_Pinstore.post │ ├── v1_Pinstore.pre │ ├── v1_StartedDeals.post │ ├── v1_StartedDeals.pre │ ├── v1_StorageInfo.post │ ├── v1_StorageInfo.pre │ ├── v1_Trackstore.post │ ├── v1_Trackstore.pre │ ├── v2_StorageInfo.post │ ├── v2_StorageInfo.pre │ ├── v3_StorageJobs.post │ ├── v3_StorageJobs.pre │ ├── v4_Records.post │ └── v4_Records.pre ├── proto └── powergate │ ├── admin │ └── v1 │ │ └── admin.proto │ └── user │ └── v1 │ └── user.proto ├── reputation ├── internal │ └── source │ │ ├── source.go │ │ └── store.go └── reputation.go ├── scripts ├── gen-js-protos.sh └── gen-py-protos.sh ├── signaler └── signaler.go ├── tests ├── auth.go ├── docker.go ├── flaky.go ├── ldevnet.go ├── mocks │ └── mocks.go └── txmapds.go ├── txndstransform └── txndstransform.go ├── util ├── util.go └── util_test.go └── wallet ├── lotuswallet ├── metrics.go └── wallet.go └── type.go /.bingo/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Ignore everything 3 | * 4 | 5 | # But not these files: 6 | !.gitignore 7 | !*.mod 8 | !README.md 9 | !Variables.mk 10 | !variables.env 11 | 12 | *tmp.mod 13 | -------------------------------------------------------------------------------- /.bingo/README.md: -------------------------------------------------------------------------------- 1 | # Project Development Dependencies. 2 | 3 | This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo. 4 | 5 | * Run `bingo get` to install all tools having each own module file in this directory. 6 | * Run `bingo get ` to install that have own module file in this directory. 7 | * For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $() variable where is the .bingo/.mod. 8 | * For shell: Run `source .bingo/variables.env` to source all environment variable for each tool. 9 | * For go: Import `.bingo/variables.go` to for variable names. 10 | * See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies. 11 | 12 | ## Requirements 13 | 14 | * Go 1.14+ 15 | -------------------------------------------------------------------------------- /.bingo/bingo.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.16 4 | 5 | require github.com/bwplotka/bingo v0.5.1 6 | -------------------------------------------------------------------------------- /.bingo/buf.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.14 4 | 5 | require github.com/bufbuild/buf v0.46.0 // cmd/buf 6 | -------------------------------------------------------------------------------- /.bingo/go.mod: -------------------------------------------------------------------------------- 1 | module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files. -------------------------------------------------------------------------------- /.bingo/gomplate.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.14 4 | 5 | require github.com/hairyhenderson/gomplate/v3 v3.8.0 // cmd/gomplate 6 | -------------------------------------------------------------------------------- /.bingo/govvv.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.14 4 | 5 | require github.com/ahmetb/govvv v0.3.0 6 | -------------------------------------------------------------------------------- /.bingo/gox.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.14 4 | 5 | require github.com/mitchellh/gox v1.0.1 6 | -------------------------------------------------------------------------------- /.bingo/protoc-gen-buf-breaking.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.16 4 | 5 | require github.com/bufbuild/buf v0.46.0 // cmd/protoc-gen-buf-breaking 6 | -------------------------------------------------------------------------------- /.bingo/protoc-gen-buf-lint.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.16 4 | 5 | require github.com/bufbuild/buf v0.46.0 // cmd/protoc-gen-buf-lint 6 | -------------------------------------------------------------------------------- /.bingo/protoc-gen-go-grpc.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.14 4 | 5 | require google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.1 6 | -------------------------------------------------------------------------------- /.bingo/protoc-gen-go.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.14 4 | 5 | require google.golang.org/protobuf v1.25.0 // cmd/protoc-gen-go 6 | -------------------------------------------------------------------------------- /.bingo/variables.env: -------------------------------------------------------------------------------- 1 | # Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.5.1. DO NOT EDIT. 2 | # All tools are designed to be build inside $GOBIN. 3 | # Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk. 4 | GOBIN=${GOBIN:=$(go env GOBIN)} 5 | 6 | if [ -z "$GOBIN" ]; then 7 | GOBIN="$(go env GOPATH)/bin" 8 | fi 9 | 10 | 11 | BINGO="${GOBIN}/bingo-v0.5.1" 12 | 13 | BUF="${GOBIN}/buf-v0.46.0" 14 | 15 | GOMPLATE="${GOBIN}/gomplate-v3.8.0" 16 | 17 | GOVVV="${GOBIN}/govvv-v0.3.0" 18 | 19 | GOX="${GOBIN}/gox-v1.0.1" 20 | 21 | PROTOC_GEN_BUF_BREAKING="${GOBIN}/protoc-gen-buf-breaking-v0.46.0" 22 | 23 | PROTOC_GEN_BUF_LINT="${GOBIN}/protoc-gen-buf-lint-v0.46.0" 24 | 25 | PROTOC_GEN_GO_GRPC="${GOBIN}/protoc-gen-go-grpc-v1.0.1" 26 | 27 | PROTOC_GEN_GO="${GOBIN}/protoc-gen-go-v1.25.0" 28 | 29 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/docker-compose.yaml 2 | **/docker-compose-devnet.yaml 3 | **/Dockerfile 4 | exe/bench 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | target-branch: "master" 9 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: "v$RESOLVED_VERSION 🌈" 2 | tag-template: "v$RESOLVED_VERSION" 3 | categories: 4 | - title: "🚀 Features" 5 | labels: 6 | - "feature" 7 | - "enhancement" 8 | - title: "🐛 Bug Fixes" 9 | labels: 10 | - "fix" 11 | - "bugfix" 12 | - "bug" 13 | - title: "🧰 Maintenance" 14 | label: "chore" 15 | change-template: "- $TITLE @$AUTHOR (#$NUMBER)" 16 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 17 | version-resolver: 18 | major: 19 | labels: 20 | - "rd-major" 21 | minor: 22 | labels: 23 | - "rd-minor" 24 | patch: 25 | labels: 26 | - "rd-patch" 27 | default: patch 28 | exclude-labels: 29 | - "skip-changelog" 30 | template: | 31 | ## Changes 32 | 33 | $CHANGES 34 | 35 | 🙏 A big thank you to all the contributors to this release: 36 | 37 | $CONTRIBUTORS 38 | -------------------------------------------------------------------------------- /.github/weekly-digest.yml: -------------------------------------------------------------------------------- 1 | publishDay: fri 2 | canPublishIssues: true 3 | canPublishPullRequests: true 4 | canPublishContributors: true 5 | canPublishStargazers: true 6 | canPublishCommits: true 7 | -------------------------------------------------------------------------------- /.github/workflows/buf.yml: -------------------------------------------------------------------------------- 1 | name: Buf 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Set up Go 14 | uses: actions/setup-go@v1 15 | with: 16 | go-version: 1.16 17 | - name: checkout 18 | if: success() 19 | uses: actions/checkout@v1 20 | with: 21 | ref: master 22 | - name: checkout-master 23 | if: success() 24 | run: git checkout master 25 | - name: checkout 26 | if: success() 27 | uses: actions/checkout@v1 28 | - name: make local 29 | if: success() 30 | run: make buf-local 31 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image 2 | on: 3 | release: 4 | types: [published] 5 | push: 6 | branches: 7 | - master 8 | jobs: 9 | docker: 10 | name: Docker publishing 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Get git sha 15 | id: git_sha 16 | run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" 17 | - name: Check outputs 18 | run: echo ${{ steps.git_sha.outputs.sha_short }} 19 | - name: Fail if no git sha 20 | run: exit 1 21 | if: ${{ steps.git_sha.outputs.sha_short == 0 }} 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v1 24 | - name: Login to DockerHub 25 | uses: docker/login-action@v1 26 | with: 27 | username: ${{ secrets.DOCKER_USERNAME }} 28 | password: ${{ secrets.DOCKER_PASSWORD }} 29 | - name: Build and push 30 | id: docker_build 31 | uses: docker/build-push-action@v2 32 | with: 33 | push: true 34 | tags: textile/powergate:latest,textile/powergate:sha-${{ steps.git_sha.outputs.sha_short }} 35 | -------------------------------------------------------------------------------- /.github/workflows/ensure-docs.yml: -------------------------------------------------------------------------------- 1 | name: Ensure docs 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | ensure-pow-docs: 11 | name: pow 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Install Go 15 | uses: actions/setup-go@v2 16 | with: 17 | go-version: 1.17.x 18 | - name: check out code 19 | uses: actions/checkout@v1 20 | - name: generate docs 21 | run: make docs-pow 22 | - name: detect changes 23 | id: changes 24 | uses: UnicornGlobal/has-changes-action@v1.0.11 25 | - name: check changes 26 | if: steps.changes.outputs.changed == 1 27 | run: exit 1 28 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - master 8 | 9 | jobs: 10 | update_release_draft: 11 | runs-on: ubuntu-latest 12 | steps: 13 | # Drafts your next Release notes as Pull Requests are merged into "master" 14 | - uses: release-drafter/release-drafter@v5 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/review.yml: -------------------------------------------------------------------------------- 1 | name: Review 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | jobs: 8 | golangci-lint: 9 | name: golangci-lint 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - uses: golangci/golangci-lint-action@v2 14 | with: 15 | version: v1.29 16 | spell-check: 17 | name: spell-check 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v1 21 | - uses: reviewdog/action-misspell@v1 22 | with: 23 | reporter: github-pr-review 24 | github_token: ${{ secrets.github_token }} 25 | locale: "US" 26 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | test: 11 | name: compile & test 12 | runs-on: self-hosted 13 | steps: 14 | - name: Check out code 15 | uses: actions/checkout@v1 16 | - name: Compile CLI on Windows 17 | run: GOOS=windows go build ./cmd/pow 18 | - name: Test 19 | run: make test 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | cover.out 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | # vendor/ 17 | 18 | # vscode config folder 19 | .vscode/ 20 | 21 | # File names that can be used for testing. 22 | myfile 23 | myfile2 24 | 25 | # StorageConfig name that can be used for testing. 26 | pconfig.pow 27 | 28 | tags 29 | 30 | build/ 31 | tmp 32 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters-settings: 2 | misspell: 3 | locale: US 4 | 5 | linters: 6 | enable: 7 | - golint 8 | - misspell 9 | - bodyclose 10 | - unconvert 11 | - goconst 12 | - goimports 13 | - unparam 14 | - whitespace 15 | - godot 16 | 17 | issues: 18 | exclude-use-default: false 19 | 20 | exclude-rules: 21 | - path: cmd/powbench/runner/runner_test.go 22 | linters: 23 | - unused 24 | 25 | run: 26 | timeout: 30m 27 | skip-files: 28 | - gateway/assets.go 29 | 30 | service: 31 | golangci-lint-version: 1.27.x # use the fixed version to not introduce new linters unexpectedly 32 | 33 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guidelines 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1-experimental 2 | 3 | FROM golang:1.16-buster as builder 4 | 5 | RUN mkdir /app 6 | WORKDIR /app 7 | 8 | COPY go.mod go.sum ./ 9 | RUN go mod download -x 10 | COPY . . 11 | RUN --mount=type=cache,target=/root/.cache/go-build \ 12 | POW_BUILD_FLAGS="CGO_ENABLED=0 GOOS=linux" make build-powd 13 | RUN --mount=type=cache,target=/root/.cache/go-build \ 14 | POW_BUILD_FLAGS="CGO_ENABLED=0 GOOS=linux" make build-pow 15 | 16 | FROM alpine 17 | COPY --from=builder /app/iplocation/maxmind/GeoLite2-City.mmdb /app/GeoLite2-City.mmdb 18 | COPY --from=builder /app/powd /app/powd 19 | COPY --from=builder /app/pow /app/pow 20 | WORKDIR /app 21 | ENTRYPOINT ["./powd"] 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 textile.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /api/client/admin/admin.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 5 | ) 6 | 7 | // Admin provides access to Powergate admin APIs. 8 | type Admin struct { 9 | StorageJobs *StorageJobs 10 | StorageInfo *StorageInfo 11 | Users *Users 12 | Wallet *Wallet 13 | Data *Data 14 | Records *Records 15 | Indices *Indices 16 | } 17 | 18 | // NewAdmin creates a new admin API. 19 | func NewAdmin(client adminPb.AdminServiceClient) *Admin { 20 | return &Admin{ 21 | StorageJobs: &StorageJobs{client: client}, 22 | StorageInfo: &StorageInfo{client: client}, 23 | Users: &Users{client: client}, 24 | Wallet: &Wallet{client: client}, 25 | Data: &Data{client: client}, 26 | Records: &Records{client: client}, 27 | Indices: &Indices{client: client}, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /api/client/admin/data.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | 6 | proto "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 7 | ) 8 | 9 | // Data provides access to Powergate data admin APIs. 10 | type Data struct { 11 | client proto.AdminServiceClient 12 | } 13 | 14 | // GCStaged unpins staged data not related to queued or executing jobs. 15 | func (w *Data) GCStaged(ctx context.Context) (*proto.GCStagedResponse, error) { 16 | return w.client.GCStaged(ctx, &proto.GCStagedRequest{}) 17 | } 18 | 19 | // PinnedCids returns pinned cids information of hot-storage. 20 | func (w *Data) PinnedCids(ctx context.Context) (*proto.PinnedCidsResponse, error) { 21 | return w.client.PinnedCids(ctx, &proto.PinnedCidsRequest{}) 22 | } 23 | -------------------------------------------------------------------------------- /api/client/admin/indices.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 8 | ) 9 | 10 | // Indices provides APIs to fetch indices data. 11 | type Indices struct { 12 | client adminPb.AdminServiceClient 13 | } 14 | 15 | // GetMiners return a list of miner addresses that satisfies the provided filters. 16 | func (i *Indices) GetMiners(ctx context.Context, opts ...GetMinersOption) (*adminPb.GetMinersResponse, error) { 17 | cfg := defaultCfgGetMiners 18 | for _, o := range opts { 19 | if err := o(&cfg); err != nil { 20 | return nil, fmt.Errorf("applying configuration option: %s", err) 21 | } 22 | } 23 | req := &adminPb.GetMinersRequest{ 24 | WithPower: cfg.withPower, 25 | } 26 | 27 | return i.client.GetMiners(ctx, req) 28 | } 29 | 30 | // GetMinerInfo returns all known indices data for the provider miner addresses. 31 | func (i *Indices) GetMinerInfo(ctx context.Context, miners ...string) (*adminPb.GetMinerInfoResponse, error) { 32 | req := &adminPb.GetMinerInfoRequest{ 33 | Miners: miners, 34 | } 35 | 36 | return i.client.GetMinerInfo(ctx, req) 37 | } 38 | -------------------------------------------------------------------------------- /api/client/admin/options.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | var ( 4 | defaultCfgGetMiners = cfgGetMiners{ 5 | withPower: true, 6 | } 7 | ) 8 | 9 | type cfgGetMiners struct { 10 | withPower bool 11 | } 12 | 13 | // GetMinersOption configures filters for getting miners. 14 | type GetMinersOption func(*cfgGetMiners) error 15 | 16 | // WithPowerGreaterThanZero filters miners that have power greater 17 | // than zero. 18 | func WithPowerGreaterThanZero(withPower bool) GetMinersOption { 19 | return func(cfg *cfgGetMiners) error { 20 | cfg.withPower = withPower 21 | return nil 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/client/admin/records.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 8 | "google.golang.org/protobuf/types/known/timestamppb" 9 | ) 10 | 11 | // Records provides APIs to fetch generated records from the deals module. 12 | type Records struct { 13 | client adminPb.AdminServiceClient 14 | } 15 | 16 | // GetUpdatedRetrievalRecordsSince returns the retrieval records that 17 | // were created or modified since the specified date. 18 | func (c *Records) GetUpdatedRetrievalRecordsSince(ctx context.Context, since time.Time, limit int) (*adminPb.GetUpdatedRetrievalRecordsSinceResponse, error) { 19 | req := &adminPb.GetUpdatedRetrievalRecordsSinceRequest{ 20 | Since: timestamppb.New(since), 21 | Limit: int32(limit), 22 | } 23 | return c.client.GetUpdatedRetrievalRecordsSince(ctx, req) 24 | } 25 | 26 | // GetUpdatedStorageDealRecordsSince returns the storage-deal records that 27 | // were created or modified since the specified date. 28 | func (c *Records) GetUpdatedStorageDealRecordsSince(ctx context.Context, since time.Time, limit int) (*adminPb.GetUpdatedStorageDealRecordsSinceResponse, error) { 29 | req := &adminPb.GetUpdatedStorageDealRecordsSinceRequest{ 30 | Since: timestamppb.New(since), 31 | Limit: int32(limit), 32 | } 33 | return c.client.GetUpdatedStorageDealRecordsSince(ctx, req) 34 | } 35 | -------------------------------------------------------------------------------- /api/client/admin/storageinfo.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | 6 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 7 | ) 8 | 9 | // StorageInfo provides access to Powergate storage indo APIs. 10 | type StorageInfo struct { 11 | client adminPb.AdminServiceClient 12 | } 13 | 14 | // Get returns the information about a stored Cid. If no information is available, 15 | // since the Cid was never stored, it returns an error with codes.NotFound. 16 | func (s *StorageInfo) Get(ctx context.Context, userID, cid string) (*adminPb.StorageInfoResponse, error) { 17 | return s.client.StorageInfo(ctx, &adminPb.StorageInfoRequest{UserId: userID, Cid: cid}) 18 | } 19 | 20 | // List returns a list of information about all stored cids, filtered by user ids and cids if provided. 21 | func (s *StorageInfo) List(ctx context.Context, userIDs, cids []string) (*adminPb.ListStorageInfoResponse, error) { 22 | return s.client.ListStorageInfo(ctx, &adminPb.ListStorageInfoRequest{UserIds: userIDs, Cids: cids}) 23 | } 24 | -------------------------------------------------------------------------------- /api/client/admin/users.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | 6 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 7 | ) 8 | 9 | // Users provides access to Powergate admin users APIs. 10 | type Users struct { 11 | client adminPb.AdminServiceClient 12 | } 13 | 14 | // Create creates a new Powergate user, returning the user ID and auth token. 15 | func (p *Users) Create(ctx context.Context) (*adminPb.CreateUserResponse, error) { 16 | return p.client.CreateUser(ctx, &adminPb.CreateUserRequest{}) 17 | } 18 | 19 | // RegenerateAuth invalidates an existing token replacing it with a new one. 20 | func (p *Users) RegenerateAuth(ctx context.Context, token string) (*adminPb.RegenerateAuthResponse, error) { 21 | return p.client.RegenerateAuth(ctx, &adminPb.RegenerateAuthRequest{Token: token}) 22 | } 23 | 24 | // List returns a list of existing users. 25 | func (p *Users) List(ctx context.Context) (*adminPb.UsersResponse, error) { 26 | return p.client.Users(ctx, &adminPb.UsersRequest{}) 27 | } 28 | -------------------------------------------------------------------------------- /api/client/admin/wallet.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 8 | ) 9 | 10 | // Wallet provides access to Powergate wallet admin APIs. 11 | type Wallet struct { 12 | client adminPb.AdminServiceClient 13 | } 14 | 15 | // NewAddress creates a new address. 16 | func (w *Wallet) NewAddress(ctx context.Context, addrType string) (*adminPb.NewAddressResponse, error) { 17 | req := &adminPb.NewAddressRequest{ 18 | AddressType: addrType, 19 | } 20 | return w.client.NewAddress(ctx, req) 21 | } 22 | 23 | // Addresses lists all addresses associated with this Powergate. 24 | func (w *Wallet) Addresses(ctx context.Context) (*adminPb.AddressesResponse, error) { 25 | return w.client.Addresses(ctx, &adminPb.AddressesRequest{}) 26 | } 27 | 28 | // SendFil sends FIL from an address associated with this Powergate to any other address. 29 | func (w *Wallet) SendFil(ctx context.Context, from, to string, amount *big.Int) (*adminPb.SendFilResponse, error) { 30 | req := &adminPb.SendFilRequest{ 31 | From: from, 32 | To: to, 33 | Amount: amount.String(), 34 | } 35 | return w.client.SendFil(ctx, req) 36 | } 37 | -------------------------------------------------------------------------------- /api/client/client_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestClient(t *testing.T) { 10 | done := setupServer(t, defaultServerConfig(t)) 11 | defer done() 12 | 13 | client, err := NewClient("127.0.0.1:5002") 14 | require.NoError(t, err) 15 | err = client.Close() 16 | require.NoError(t, err) 17 | } 18 | -------------------------------------------------------------------------------- /api/client/storageinfo.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | 6 | userPb "github.com/textileio/powergate/v2/api/gen/powergate/user/v1" 7 | ) 8 | 9 | // StorageInfo provides access to Powergate storage indo APIs. 10 | type StorageInfo struct { 11 | client userPb.UserServiceClient 12 | } 13 | 14 | // Get returns the information about a stored Cid. If no information is available, 15 | // since the Cid was never stored, it returns an error with codes.NotFound. 16 | func (s *StorageInfo) Get(ctx context.Context, cid string) (*userPb.StorageInfoResponse, error) { 17 | return s.client.StorageInfo(ctx, &userPb.StorageInfoRequest{Cid: cid}) 18 | } 19 | 20 | // List returns a list of information about all stored cids, filtered by cids if provided. 21 | func (s *StorageInfo) List(ctx context.Context, cids ...string) (*userPb.ListStorageInfoResponse, error) { 22 | return s.client.ListStorageInfo(ctx, &userPb.ListStorageInfoRequest{Cids: cids}) 23 | } 24 | -------------------------------------------------------------------------------- /api/client/wallet_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestFoo(t *testing.T) { 10 | require.True(t, true) 11 | } 12 | 13 | // func TestNewWallet(t *testing.T) { 14 | // w, done := setupWallet(t) 15 | // defer done() 16 | 17 | // res, err := w.NewAddress(ctx, "bls") 18 | // require.NoError(t, err) 19 | // require.Greater(t, len(res.Address), 0) 20 | // } 21 | 22 | // func TestList(t *testing.T) { 23 | // w, done := setupWallet(t) 24 | // defer done() 25 | 26 | // res, err := w.List(ctx) 27 | // require.NoError(t, err) 28 | // require.Greater(t, len(res.Addresses), 0) 29 | // } 30 | 31 | // func TestWalletBalance(t *testing.T) { 32 | // w, done := setupWallet(t) 33 | // defer done() 34 | 35 | // newAddressRes, err := w.NewAddress(ctx, "bls") 36 | // require.NoError(t, err) 37 | 38 | // _, err = w.Balance(ctx, newAddressRes.Address) 39 | // require.NoError(t, err) 40 | // } 41 | 42 | // func setupWallet(t *testing.T) (*Wallet, func()) { 43 | // serverDone := setupServer(t, defaultServerConfig(t)) 44 | // conn, done := setupConnection(t) 45 | // return &Wallet{walletClient: rpc.NewRPCServiceClient(conn), powergateClient: proto.NewPowergateServiceClient(conn)}, func() { 46 | // done() 47 | // serverDone() 48 | // } 49 | // } 50 | -------------------------------------------------------------------------------- /api/server/admin/hs.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | 6 | adminProto "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 7 | "google.golang.org/grpc/codes" 8 | "google.golang.org/grpc/status" 9 | ) 10 | 11 | // GCStaged runs a unpinning garbage collection and returns the unpinned cids. 12 | func (a *Service) GCStaged(ctx context.Context, req *adminProto.GCStagedRequest) (*adminProto.GCStagedResponse, error) { 13 | cids, err := a.s.GCStaged(ctx) 14 | if err != nil { 15 | return nil, status.Errorf(codes.Internal, "running FFS GC: %v", err) 16 | } 17 | 18 | cidsStr := make([]string, len(cids)) 19 | for i := range cids { 20 | cidsStr[i] = cids[i].String() 21 | } 22 | 23 | return &adminProto.GCStagedResponse{ 24 | UnpinnedCids: cidsStr, 25 | }, nil 26 | } 27 | 28 | // PinnedCids returns all the pinned cids in Hot-Storage. 29 | func (a *Service) PinnedCids(ctx context.Context, req *adminProto.PinnedCidsRequest) (*adminProto.PinnedCidsResponse, error) { 30 | pcids, err := a.s.PinnedCids(ctx) 31 | if err != nil { 32 | return nil, status.Errorf(codes.Internal, "getting pinned cids: %v", err) 33 | } 34 | 35 | res := &adminProto.PinnedCidsResponse{ 36 | Cids: make([]*adminProto.HSPinnedCid, len(pcids)), 37 | } 38 | 39 | for i, pc := range pcids { 40 | hspc := &adminProto.HSPinnedCid{ 41 | Cid: pc.Cid.String(), 42 | Users: make([]*adminProto.HSPinnedCidUser, len(pc.APIIDs)), 43 | } 44 | 45 | for j, up := range pc.APIIDs { 46 | upr := &adminProto.HSPinnedCidUser{ 47 | UserId: up.ID.String(), 48 | Staged: up.Staged, 49 | CreatedAt: up.CreatedAt, 50 | } 51 | hspc.Users[j] = upr 52 | } 53 | res.Cids[i] = hspc 54 | } 55 | 56 | return res, nil 57 | } 58 | -------------------------------------------------------------------------------- /api/server/admin/records.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | 6 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 7 | "github.com/textileio/powergate/v2/api/server/util" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/status" 10 | ) 11 | 12 | // GetUpdatedStorageDealRecordsSince returns all the storage deal records that got created or updated 13 | // since a provided point in time. 14 | func (a *Service) GetUpdatedStorageDealRecordsSince(ctx context.Context, req *adminPb.GetUpdatedStorageDealRecordsSinceRequest) (*adminPb.GetUpdatedStorageDealRecordsSinceResponse, error) { 15 | rs, err := a.dm.GetUpdatedStorageDealRecordsSince(req.Since.AsTime(), int(req.Limit)) 16 | if err != nil { 17 | return nil, status.Errorf(codes.Internal, "getting updated storage deal records: %s", err) 18 | } 19 | 20 | return &adminPb.GetUpdatedStorageDealRecordsSinceResponse{Records: util.ToRPCStorageDealRecords(rs)}, nil 21 | } 22 | 23 | // GetUpdatedRetrievalRecordsSince returns all the retrieval records that got created or updated 24 | // since a provided point in time. 25 | func (a *Service) GetUpdatedRetrievalRecordsSince(ctx context.Context, req *adminPb.GetUpdatedRetrievalRecordsSinceRequest) (*adminPb.GetUpdatedRetrievalRecordsSinceResponse, error) { 26 | rs, err := a.dm.GetUpdatedRetrievalRecordsSince(req.Since.AsTime(), int(req.Limit)) 27 | if err != nil { 28 | return nil, status.Errorf(codes.Internal, "getting updated retrieval records: %s", err) 29 | } 30 | 31 | return &adminPb.GetUpdatedRetrievalRecordsSinceResponse{Records: util.ToRPCRetrievalDealRecords(rs)}, nil 32 | } 33 | -------------------------------------------------------------------------------- /api/server/admin/service.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 5 | dealsModule "github.com/textileio/powergate/v2/deals/module" 6 | "github.com/textileio/powergate/v2/ffs/manager" 7 | "github.com/textileio/powergate/v2/ffs/scheduler" 8 | askIndex "github.com/textileio/powergate/v2/index/ask/runner" 9 | minerIndex "github.com/textileio/powergate/v2/index/miner/lotusidx" 10 | "github.com/textileio/powergate/v2/wallet" 11 | ) 12 | 13 | // Service implements the Admin API. 14 | type Service struct { 15 | adminPb.UnimplementedAdminServiceServer 16 | m *manager.Manager 17 | s *scheduler.Scheduler 18 | wm wallet.Module 19 | dm *dealsModule.Module 20 | mi *minerIndex.Index 21 | ai *askIndex.Runner 22 | } 23 | 24 | // New creates a new AdminService. 25 | func New(m *manager.Manager, s *scheduler.Scheduler, wm wallet.Module, dm *dealsModule.Module, mi *minerIndex.Index, ai *askIndex.Runner) *Service { 26 | return &Service{ 27 | m: m, 28 | s: s, 29 | wm: wm, 30 | dm: dm, 31 | mi: mi, 32 | ai: ai, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /api/server/admin/wallet.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | adminPb "github.com/textileio/powergate/v2/api/gen/powergate/admin/v1" 8 | "google.golang.org/grpc/codes" 9 | "google.golang.org/grpc/status" 10 | ) 11 | 12 | // NewAddress creates a new address. 13 | func (a *Service) NewAddress(ctx context.Context, req *adminPb.NewAddressRequest) (*adminPb.NewAddressResponse, error) { 14 | addr, err := a.wm.NewAddress(ctx, req.AddressType) 15 | if err != nil { 16 | return nil, status.Errorf(codes.Internal, "creating address: %v", err) 17 | } 18 | return &adminPb.NewAddressResponse{ 19 | Address: addr, 20 | }, nil 21 | } 22 | 23 | // Addresses lists all addresses associated with this Powergate. 24 | func (a *Service) Addresses(ctx context.Context, req *adminPb.AddressesRequest) (*adminPb.AddressesResponse, error) { 25 | addrs, err := a.wm.List(ctx) 26 | if err != nil { 27 | return nil, status.Errorf(codes.Internal, "listing addrs: %v", err) 28 | } 29 | return &adminPb.AddressesResponse{ 30 | Addresses: addrs, 31 | }, nil 32 | } 33 | 34 | // SendFil sends FIL from an address associated with this Powergate to any other address. 35 | func (a *Service) SendFil(ctx context.Context, req *adminPb.SendFilRequest) (*adminPb.SendFilResponse, error) { 36 | amt, ok := new(big.Int).SetString(req.Amount, 10) 37 | if !ok { 38 | return nil, status.Errorf(codes.InvalidArgument, "parsing amount %v", req.Amount) 39 | } 40 | cid, err := a.wm.SendFil(ctx, req.From, req.To, amt) 41 | if err != nil { 42 | return nil, status.Errorf(codes.Internal, "sending fil: %v", err) 43 | } 44 | return &adminPb.SendFilResponse{ 45 | Cid: cid.String(), 46 | }, nil 47 | } 48 | -------------------------------------------------------------------------------- /api/server/user/deals.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "context" 5 | 6 | userPb "github.com/textileio/powergate/v2/api/gen/powergate/user/v1" 7 | "github.com/textileio/powergate/v2/api/server/util" 8 | ) 9 | 10 | // StorageDealRecords calls ffs.ListStorageDealRecords. 11 | func (s *Service) StorageDealRecords(ctx context.Context, req *userPb.StorageDealRecordsRequest) (*userPb.StorageDealRecordsResponse, error) { 12 | i, err := s.getInstanceByToken(ctx) 13 | if err != nil { 14 | return nil, err 15 | } 16 | records, err := i.StorageDealRecords(buildListDealRecordsOptions(req.Config)...) 17 | if err != nil { 18 | return nil, err 19 | } 20 | return &userPb.StorageDealRecordsResponse{Records: util.ToRPCStorageDealRecords(records)}, nil 21 | } 22 | 23 | // RetrievalDealRecords calls ffs.ListRetrievalDealRecords. 24 | func (s *Service) RetrievalDealRecords(ctx context.Context, req *userPb.RetrievalDealRecordsRequest) (*userPb.RetrievalDealRecordsResponse, error) { 25 | i, err := s.getInstanceByToken(ctx) 26 | if err != nil { 27 | return nil, err 28 | } 29 | records, err := i.RetrievalDealRecords(buildListDealRecordsOptions(req.Config)...) 30 | if err != nil { 31 | return nil, err 32 | } 33 | return &userPb.RetrievalDealRecordsResponse{Records: util.ToRPCRetrievalDealRecords(records)}, nil 34 | } 35 | -------------------------------------------------------------------------------- /buf.yaml: -------------------------------------------------------------------------------- 1 | version: v1beta1 2 | build: 3 | roots: 4 | - proto 5 | lint: 6 | use: 7 | - DEFAULT 8 | breaking: 9 | use: 10 | - FILE 11 | -------------------------------------------------------------------------------- /buildinfo/buildinfo.go: -------------------------------------------------------------------------------- 1 | package buildinfo 2 | 3 | import "fmt" 4 | 5 | var ( 6 | // GitCommit is set by govvv at build time. 7 | GitCommit = "n/a" 8 | // GitBranch is set by govvv at build time. 9 | GitBranch = "n/a" 10 | // GitState is set by govvv at build time. 11 | GitState = "n/a" 12 | // GitSummary is set by govvv at build time. 13 | GitSummary = "n/a" 14 | // BuildDate is set by govvv at build time. 15 | BuildDate = "n/a" 16 | // Version is set by govvv at build time. 17 | Version = "n/a" 18 | ) 19 | 20 | // Summary prints a summary of all build info. 21 | func Summary() string { 22 | return fmt.Sprintf( 23 | "\tversion:\t%s\n\tbuild date:\t%s\n\tgit summary:\t%s\n\tgit branch:\t%s\n\tgit commit:\t%s\n\tgit state:\t%s", 24 | Version, 25 | BuildDate, 26 | GitSummary, 27 | GitBranch, 28 | GitCommit, 29 | GitState, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /chainsync/chainsync_test.go: -------------------------------------------------------------------------------- 1 | package chainsync 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "testing" 7 | "time" 8 | 9 | "github.com/filecoin-project/lotus/chain/types" 10 | logging "github.com/ipfs/go-log/v2" 11 | "github.com/stretchr/testify/require" 12 | "github.com/textileio/powergate/v2/tests" 13 | ) 14 | 15 | func TestMain(m *testing.M) { 16 | logging.SetAllLoggers(logging.LevelError) 17 | os.Exit(m.Run()) 18 | } 19 | 20 | func TestPrecede(t *testing.T) { 21 | clientBuilder, _, _ := tests.CreateLocalDevnet(t, 1, 300) 22 | time.Sleep(time.Second * 5) // Give time for at least 1 block to be mined. 23 | ctx := context.Background() 24 | c, cls, err := clientBuilder(context.Background()) 25 | require.NoError(t, err) 26 | defer cls() 27 | 28 | h, err := c.ChainHead(ctx) 29 | checkErr(t, err) 30 | 31 | csync := New(clientBuilder) 32 | head := h.Key() 33 | prevhead := types.NewTipSetKey(h.Blocks()[0].Parents...) 34 | yes, err := csync.Precedes(ctx, prevhead, head) 35 | checkErr(t, err) 36 | if !yes { 37 | t.Fatal("parent of head should precedes head") 38 | } 39 | 40 | yes, err = csync.Precedes(ctx, head, prevhead) 41 | checkErr(t, err) 42 | if yes { 43 | t.Fatal("head shouldn't preced parent of head") 44 | } 45 | } 46 | 47 | func checkErr(t *testing.T, err error) { 48 | t.Helper() 49 | if err != nil { 50 | t.Fatal(err) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /cli-docs/pow/pow.md: -------------------------------------------------------------------------------- 1 | ## pow 2 | 3 | A client for storage and retreival of powergate data 4 | 5 | ### Synopsis 6 | 7 | A client for storage and retreival of powergate data 8 | 9 | ``` 10 | pow [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for pow 17 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 18 | -t, --token string user auth token 19 | -v, --version display version information for pow and the connected server 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow admin](pow_admin.md) - Provides admin commands 25 | * [pow config](pow_config.md) - Provides commands to interact with cid storage configs 26 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 27 | * [pow deals](pow_deals.md) - Provides commands to view Filecoin deal information 28 | * [pow id](pow_id.md) - Returns the user id 29 | * [pow offline](pow_offline.md) - Provides commands to prepare data for Filecoin onbarding 30 | * [pow storage-info](pow_storage-info.md) - Provides commands to get and query cid storage info. 31 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 32 | * [pow version](pow_version.md) - Display version information for pow and the connected server 33 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 34 | 35 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin.md: -------------------------------------------------------------------------------- 1 | ## pow admin 2 | 3 | Provides admin commands 4 | 5 | ### Synopsis 6 | 7 | Provides admin commands 8 | 9 | ### Options 10 | 11 | ``` 12 | --admin-token string admin auth token 13 | -h, --help help for admin 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 20 | -t, --token string user auth token 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [pow](pow.md) - A client for storage and retreival of powergate data 26 | * [pow admin data](pow_admin_data.md) - Provides admin data commands 27 | * [pow admin storage-info](pow_admin_storage-info.md) - Provides admin storage info commands 28 | * [pow admin storage-jobs](pow_admin_storage-jobs.md) - Provides admin jobs commands 29 | * [pow admin users](pow_admin_users.md) - Provides admin users commands 30 | * [pow admin wallet](pow_admin_wallet.md) - Provides admin wallet commands 31 | 32 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_data.md: -------------------------------------------------------------------------------- 1 | ## pow admin data 2 | 3 | Provides admin data commands 4 | 5 | ### Synopsis 6 | 7 | Provides admin data commands 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for data 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --admin-token string admin auth token 19 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 20 | -t, --token string user auth token 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [pow admin](pow_admin.md) - Provides admin commands 26 | * [pow admin data gcstaged](pow_admin_data_gcstaged.md) - Unpins unused staged data. 27 | * [pow admin data pinnedcids](pow_admin_data_pinnedcids.md) - List pinned cids information in hot-storage. 28 | 29 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_data_gcstaged.md: -------------------------------------------------------------------------------- 1 | ## pow admin data gcstaged 2 | 3 | Unpins unused staged data. 4 | 5 | ### Synopsis 6 | 7 | Unpins staged data not used by queued or executing jobs. 8 | 9 | ``` 10 | pow admin data gcstaged [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for gcstaged 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin data](pow_admin_data.md) - Provides admin data commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_data_pinnedcids.md: -------------------------------------------------------------------------------- 1 | ## pow admin data pinnedcids 2 | 3 | List pinned cids information in hot-storage. 4 | 5 | ### Synopsis 6 | 7 | List pinned cids information in hot-storage. 8 | 9 | ``` 10 | pow admin data pinnedcids [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for pinnedcids 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin data](pow_admin_data.md) - Provides admin data commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_storage-info.md: -------------------------------------------------------------------------------- 1 | ## pow admin storage-info 2 | 3 | Provides admin storage info commands 4 | 5 | ### Synopsis 6 | 7 | Provides admin storage info commands 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for storage-info 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --admin-token string admin auth token 19 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 20 | -t, --token string user auth token 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [pow admin](pow_admin.md) - Provides admin commands 26 | * [pow admin storage-info get](pow_admin_storage-info_get.md) - Returns the information about a stored cid. 27 | * [pow admin storage-info list](pow_admin_storage-info_list.md) - Returns a list of information about all stored cids, filtered by user ids and cids if provided. 28 | 29 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_storage-info_get.md: -------------------------------------------------------------------------------- 1 | ## pow admin storage-info get 2 | 3 | Returns the information about a stored cid. 4 | 5 | ### Synopsis 6 | 7 | Returns the information about a stored cid. 8 | 9 | ``` 10 | pow admin storage-info get [user-id] [cid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for get 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin storage-info](pow_admin_storage-info.md) - Provides admin storage info commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_storage-info_list.md: -------------------------------------------------------------------------------- 1 | ## pow admin storage-info list 2 | 3 | Returns a list of information about all stored cids, filtered by user ids and cids if provided. 4 | 5 | ### Synopsis 6 | 7 | Returns a list of information about all stored cids, filtered by user ids and cids if provided. 8 | 9 | ``` 10 | pow admin storage-info list [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --cids strings filter results by provided cids. 17 | -h, --help help for list 18 | --user-ids strings filter results by provided user ids. 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --admin-token string admin auth token 25 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 26 | -t, --token string user auth token 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [pow admin storage-info](pow_admin_storage-info.md) - Provides admin storage info commands 32 | 33 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_storage-jobs.md: -------------------------------------------------------------------------------- 1 | ## pow admin storage-jobs 2 | 3 | Provides admin jobs commands 4 | 5 | ### Synopsis 6 | 7 | Provides admin jobs commands 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for storage-jobs 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --admin-token string admin auth token 19 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 20 | -t, --token string user auth token 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [pow admin](pow_admin.md) - Provides admin commands 26 | * [pow admin storage-jobs list](pow_admin_storage-jobs_list.md) - List storage jobs according to query flag options. 27 | * [pow admin storage-jobs summary](pow_admin_storage-jobs_summary.md) - Give a summary of storage jobs in all states 28 | 29 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_storage-jobs_list.md: -------------------------------------------------------------------------------- 1 | ## pow admin storage-jobs list 2 | 3 | List storage jobs according to query flag options. 4 | 5 | ### Synopsis 6 | 7 | List storage jobs according to query flag options. 8 | 9 | ``` 10 | pow admin storage-jobs list [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -a, --ascending sort results ascending by time 17 | -c, --cid string return results only for the specified cid 18 | -h, --help help for list 19 | -l, --limit uint limit the number of results returned 20 | -s, --select string return only results using the specified selector: all, queued, executing, final (default "all") 21 | -u, --user string return results only for the specified user id 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --admin-token string admin auth token 28 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 29 | -t, --token string user auth token 30 | ``` 31 | 32 | ### SEE ALSO 33 | 34 | * [pow admin storage-jobs](pow_admin_storage-jobs.md) - Provides admin jobs commands 35 | 36 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_storage-jobs_summary.md: -------------------------------------------------------------------------------- 1 | ## pow admin storage-jobs summary 2 | 3 | Give a summary of storage jobs in all states 4 | 5 | ### Synopsis 6 | 7 | Give a summary of storage jobs in all states 8 | 9 | ``` 10 | pow admin storage-jobs summary [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -c, --cid string optional cid filter to apply 17 | -h, --help help for summary 18 | -u, --user-id string optional user id filter to apply 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --admin-token string admin auth token 25 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 26 | -t, --token string user auth token 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [pow admin storage-jobs](pow_admin_storage-jobs.md) - Provides admin jobs commands 32 | 33 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_users.md: -------------------------------------------------------------------------------- 1 | ## pow admin users 2 | 3 | Provides admin users commands 4 | 5 | ### Synopsis 6 | 7 | Provides admin users commands 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for users 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --admin-token string admin auth token 19 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 20 | -t, --token string user auth token 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [pow admin](pow_admin.md) - Provides admin commands 26 | * [pow admin users create](pow_admin_users_create.md) - Create a Powergate user. 27 | * [pow admin users list](pow_admin_users_list.md) - List all Powergate users. 28 | * [pow admin users regenerate](pow_admin_users_regenerate.md) - Invalidates an existing token and replaces it with a new one. 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_users_create.md: -------------------------------------------------------------------------------- 1 | ## pow admin users create 2 | 3 | Create a Powergate user. 4 | 5 | ### Synopsis 6 | 7 | Create a Powergate user. 8 | 9 | ``` 10 | pow admin users create [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for create 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin users](pow_admin_users.md) - Provides admin users commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_users_list.md: -------------------------------------------------------------------------------- 1 | ## pow admin users list 2 | 3 | List all Powergate users. 4 | 5 | ### Synopsis 6 | 7 | List all Powergate users. 8 | 9 | ``` 10 | pow admin users list [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for list 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin users](pow_admin_users.md) - Provides admin users commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_users_regenerate.md: -------------------------------------------------------------------------------- 1 | ## pow admin users regenerate 2 | 3 | Invalidates an existing token and replaces it with a new one. 4 | 5 | ### Synopsis 6 | 7 | Invalidates an existing token and replaces it with a new one. 8 | 9 | ``` 10 | pow admin users regenerate [token-to-regenerate] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for regenerate 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin users](pow_admin_users.md) - Provides admin users commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_wallet.md: -------------------------------------------------------------------------------- 1 | ## pow admin wallet 2 | 3 | Provides admin wallet commands 4 | 5 | ### Synopsis 6 | 7 | Provides admin wallet commands 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for wallet 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --admin-token string admin auth token 19 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 20 | -t, --token string user auth token 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [pow admin](pow_admin.md) - Provides admin commands 26 | * [pow admin wallet addrs](pow_admin_wallet_addrs.md) - List all addresses associated with this Powergate. 27 | * [pow admin wallet new](pow_admin_wallet_new.md) - Creates a new walllet address. 28 | * [pow admin wallet send](pow_admin_wallet_send.md) - Sends FIL from an address associated with this Powergate to any other address. 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_wallet_addrs.md: -------------------------------------------------------------------------------- 1 | ## pow admin wallet addrs 2 | 3 | List all addresses associated with this Powergate. 4 | 5 | ### Synopsis 6 | 7 | List all addresses associated with this Powergate. 8 | 9 | ``` 10 | pow admin wallet addrs [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for addrs 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin wallet](pow_admin_wallet.md) - Provides admin wallet commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_wallet_new.md: -------------------------------------------------------------------------------- 1 | ## pow admin wallet new 2 | 3 | Creates a new walllet address. 4 | 5 | ### Synopsis 6 | 7 | Creates a new wallet address. 8 | 9 | ``` 10 | pow admin wallet new [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -f, --format string Optionally specify address format bls or secp256k1 (default "bls") 17 | -h, --help help for new 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --admin-token string admin auth token 24 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 25 | -t, --token string user auth token 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [pow admin wallet](pow_admin_wallet.md) - Provides admin wallet commands 31 | 32 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_admin_wallet_send.md: -------------------------------------------------------------------------------- 1 | ## pow admin wallet send 2 | 3 | Sends FIL from an address associated with this Powergate to any other address. 4 | 5 | ### Synopsis 6 | 7 | Sends FIL from an address associated with this Powergate to any other address. 8 | 9 | ``` 10 | pow admin wallet send [from] [to] [amount] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for send 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --admin-token string admin auth token 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow admin wallet](pow_admin_wallet.md) - Provides admin wallet commands 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_config.md: -------------------------------------------------------------------------------- 1 | ## pow config 2 | 3 | Provides commands to interact with cid storage configs 4 | 5 | ### Synopsis 6 | 7 | Provides commands to interact with cid storage configs 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for config 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow config apply](pow_config_apply.md) - Apply the default or provided storage config to the specified cid 26 | * [pow config default](pow_config_default.md) - Returns the default storage config 27 | * [pow config remove](pow_config_remove.md) - Removes a Cid from being tracked as an active storage 28 | * [pow config set-default](pow_config_set-default.md) - Sets the default storage config from stdin or a file 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_config_apply.md: -------------------------------------------------------------------------------- 1 | ## pow config apply 2 | 3 | Apply the default or provided storage config to the specified cid 4 | 5 | ### Synopsis 6 | 7 | Apply the default or provided storage config to the specified cid 8 | 9 | ``` 10 | pow config apply [cid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -c, --conf string Optional path to a file containing storage config json, falls back to stdin, uses the user default by default 17 | -h, --help help for apply 18 | -i, --import-deals strings Comma-separated list of deal ids to import 19 | -e, --noexec If set, it doesn't create a job to ensure the new configuration 20 | -o, --override If set, override any pre-existing storage configuration for the cid 21 | -w, --watch Watch the progress of the resulting job 22 | ``` 23 | 24 | ### Options inherited from parent commands 25 | 26 | ``` 27 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 28 | -t, --token string user auth token 29 | ``` 30 | 31 | ### SEE ALSO 32 | 33 | * [pow config](pow_config.md) - Provides commands to interact with cid storage configs 34 | 35 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_config_default.md: -------------------------------------------------------------------------------- 1 | ## pow config default 2 | 3 | Returns the default storage config 4 | 5 | ### Synopsis 6 | 7 | Returns the default storage config 8 | 9 | ``` 10 | pow config default [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for default 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow config](pow_config.md) - Provides commands to interact with cid storage configs 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_config_remove.md: -------------------------------------------------------------------------------- 1 | ## pow config remove 2 | 3 | Removes a Cid from being tracked as an active storage 4 | 5 | ### Synopsis 6 | 7 | Removes a Cid from being tracked as an active storage. The Cid should have both Hot and Cold storage disabled, if that isn't the case it will return ErrActiveInStorage 8 | 9 | ``` 10 | pow config remove [cid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for remove 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow config](pow_config.md) - Provides commands to interact with cid storage configs 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_config_set-default.md: -------------------------------------------------------------------------------- 1 | ## pow config set-default 2 | 3 | Sets the default storage config from stdin or a file 4 | 5 | ### Synopsis 6 | 7 | Sets the default storage config from stdin or a file 8 | 9 | ``` 10 | pow config set-default [optional file] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for set-default 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow config](pow_config.md) - Provides commands to interact with cid storage configs 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data.md: -------------------------------------------------------------------------------- 1 | ## pow data 2 | 3 | Provides commands to interact with general data APIs 4 | 5 | ### Synopsis 6 | 7 | Provides commands to interact with general data APIs 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for data 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow data get](pow_data_get.md) - Get data stored by the user by cid 26 | * [pow data info](pow_data_info.md) - Get information about the current storage state of a cid 27 | * [pow data log](pow_data_log.md) - Display logs for specified cid 28 | * [pow data replace](pow_data_replace.md) - Applies a StorageConfig for c2 equal to that of c1, and removes c1 29 | * [pow data stage](pow_data_stage.md) - Temporarily stage data in Hot Storage in preparation for applying a cid storage config 30 | * [pow data summary](pow_data_summary.md) - Get a summary about the current storage and jobs state of cids 31 | 32 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data_get.md: -------------------------------------------------------------------------------- 1 | ## pow data get 2 | 3 | Get data stored by the user by cid 4 | 5 | ### Synopsis 6 | 7 | Get data stored by the user by cid 8 | 9 | ``` 10 | pow data get [cid] [output file path] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -f, --folder Indicates that the retrieved Cid is a folder 17 | -h, --help help for get 18 | --ipfsrevproxy string Powergate IPFS reverse proxy DNS address. If port 443, is assumed is a HTTPS endpoint. (default "localhost:6002") 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 25 | -t, --token string user auth token 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 31 | 32 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data_info.md: -------------------------------------------------------------------------------- 1 | ## pow data info 2 | 3 | Get information about the current storage state of a cid 4 | 5 | ### Synopsis 6 | 7 | Get information about the current storage state of a cid 8 | 9 | ``` 10 | pow data info cid [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for info 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data_log.md: -------------------------------------------------------------------------------- 1 | ## pow data log 2 | 3 | Display logs for specified cid 4 | 5 | ### Synopsis 6 | 7 | Display logs for specified cid 8 | 9 | ``` 10 | pow data log [cid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for log 17 | -j, --jid string Display information for only this job id 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data_replace.md: -------------------------------------------------------------------------------- 1 | ## pow data replace 2 | 3 | Applies a StorageConfig for c2 equal to that of c1, and removes c1 4 | 5 | ### Synopsis 6 | 7 | Applies a StorageConfig for c2 equal to that of c1, and removes c1. This operation is more efficient than manually removing and adding in two separate operations 8 | 9 | ``` 10 | pow data replace [cid1] [cid2] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for replace 17 | -w, --watch Watch the progress of the resulting job 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data_stage.md: -------------------------------------------------------------------------------- 1 | ## pow data stage 2 | 3 | Temporarily stage data in Hot Storage in preparation for applying a cid storage config 4 | 5 | ### Synopsis 6 | 7 | Temporarily stage data in Hot Storage in preparation for applying a cid storage config 8 | 9 | ``` 10 | pow data stage [path|url] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for stage 17 | --ipfsrevproxy string Powergate IPFS reverse proxy multiaddr (default "127.0.0.1:6002") 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_data_summary.md: -------------------------------------------------------------------------------- 1 | ## pow data summary 2 | 3 | Get a summary about the current storage and jobs state of cids 4 | 5 | ### Synopsis 6 | 7 | Get a summary about the current storage and jobs state of cids 8 | 9 | ``` 10 | pow data summary [optional cid1,cid2,...] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for summary 17 | -j, --json output data in raw json instead of an interactive ui 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 24 | -t, --token string user auth token 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [pow data](pow_data.md) - Provides commands to interact with general data APIs 30 | 31 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_deals.md: -------------------------------------------------------------------------------- 1 | ## pow deals 2 | 3 | Provides commands to view Filecoin deal information 4 | 5 | ### Synopsis 6 | 7 | Provides commands to view Filecoin deal information 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for deals 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow deals retrievals](pow_deals_retrievals.md) - List retrieval deal records for the user 26 | * [pow deals storage](pow_deals_storage.md) - List storage deal records for the user 27 | 28 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_deals_retrievals.md: -------------------------------------------------------------------------------- 1 | ## pow deals retrievals 2 | 3 | List retrieval deal records for the user 4 | 5 | ### Synopsis 6 | 7 | List retrieval deal records for the user 8 | 9 | ``` 10 | pow deals retrievals [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --addrs strings limit the records to deals initiated from the specified wallet addresses 17 | -a, --ascending sort records ascending, default is descending 18 | --cids strings limit the records to deals for the specified data cids 19 | -h, --help help for retrievals 20 | -e, --include-failed include failed retrievals 21 | ``` 22 | 23 | ### Options inherited from parent commands 24 | 25 | ``` 26 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 27 | -t, --token string user auth token 28 | ``` 29 | 30 | ### SEE ALSO 31 | 32 | * [pow deals](pow_deals.md) - Provides commands to view Filecoin deal information 33 | 34 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_deals_storage.md: -------------------------------------------------------------------------------- 1 | ## pow deals storage 2 | 3 | List storage deal records for the user 4 | 5 | ### Synopsis 6 | 7 | List storage deal records for the user 8 | 9 | ``` 10 | pow deals storage [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --addrs strings limit the records to deals initiated from the specified wallet addresses, treated as and AND operation if --cids is also provided 17 | -a, --ascending sort records ascending, default is sort descending 18 | --cids strings limit the records to deals for the specified data cids, treated as and AND operation if --addrs is also provided 19 | -h, --help help for storage 20 | -e, --include-failed include failed deals 21 | -f, --include-final include final deals 22 | -p, --include-pending include pending deals 23 | ``` 24 | 25 | ### Options inherited from parent commands 26 | 27 | ``` 28 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 29 | -t, --token string user auth token 30 | ``` 31 | 32 | ### SEE ALSO 33 | 34 | * [pow deals](pow_deals.md) - Provides commands to view Filecoin deal information 35 | 36 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_id.md: -------------------------------------------------------------------------------- 1 | ## pow id 2 | 3 | Returns the user id 4 | 5 | ### Synopsis 6 | 7 | Returns the user id 8 | 9 | ``` 10 | pow id [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for id 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow](pow.md) - A client for storage and retreival of powergate data 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_offline.md: -------------------------------------------------------------------------------- 1 | ## pow offline 2 | 3 | Provides commands to prepare data for Filecoin onbarding 4 | 5 | ### Synopsis 6 | 7 | Provides commands to prepare data for Filecoin onbarding 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for offline 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow offline car](pow_offline_car.md) - car generates a CAR file from the data 26 | * [pow offline commp](pow_offline_commp.md) - commP calculates the piece size and cid for a CAR file 27 | * [pow offline prepare](pow_offline_prepare.md) - prepare generates a CAR file for data 28 | 29 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_offline_car.md: -------------------------------------------------------------------------------- 1 | ## pow offline car 2 | 3 | car generates a CAR file from the data 4 | 5 | ### Synopsis 6 | 7 | Generates a CAR file from the data source. This data-source can be a file/folder path or a Cid. 8 | 9 | If a file/folder path is provided, this command will DAGify the data and generate the CAR file. 10 | If a Cid is provided, an extra --ipfs-api flag should be provided to connect to the IPFS node that contains this Cid data. 11 | 12 | ``` 13 | pow offline car [path | cid] [output path] [flags] 14 | ``` 15 | 16 | ### Options 17 | 18 | ``` 19 | --aggregate aggregates a folder of files 20 | -h, --help help for car 21 | --ipfs-api string IPFS HTTP API multiaddress that stores the cid (only for Cid processing instead of file/folder path) 22 | --quiet avoid pretty output 23 | --tmpdir string path of folder where a temporal blockstore is created for processing data (default "/tmp") 24 | ``` 25 | 26 | ### Options inherited from parent commands 27 | 28 | ``` 29 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 30 | -t, --token string user auth token 31 | ``` 32 | 33 | ### SEE ALSO 34 | 35 | * [pow offline](pow_offline.md) - Provides commands to prepare data for Filecoin onbarding 36 | 37 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_offline_commp.md: -------------------------------------------------------------------------------- 1 | ## pow offline commp 2 | 3 | commP calculates the piece size and cid for a CAR file 4 | 5 | ### Synopsis 6 | 7 | commP calculates the piece-size and PieceCID for a CAR file. 8 | 9 | This command calculates the piece-size and piece-cid (CommP) from a CAR file. 10 | This command only makes sense to run for a CAR file, so it does some quick check if the input file *seems* to be well-formated. 11 | You can use the --skip-car-validation, but usually shouldn't be done unless you know what you're doing (e.g.: benchmarks, or other tests) 12 | 13 | ``` 14 | pow offline commp [path] [flags] 15 | ``` 16 | 17 | ### Options 18 | 19 | ``` 20 | -h, --help help for commp 21 | --json avoid pretty output and use json formatting 22 | --skip-car-validation skips CAR validation when processing a path 23 | ``` 24 | 25 | ### Options inherited from parent commands 26 | 27 | ``` 28 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 29 | -t, --token string user auth token 30 | ``` 31 | 32 | ### SEE ALSO 33 | 34 | * [pow offline](pow_offline.md) - Provides commands to prepare data for Filecoin onbarding 35 | 36 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-info.md: -------------------------------------------------------------------------------- 1 | ## pow storage-info 2 | 3 | Provides commands to get and query cid storage info. 4 | 5 | ### Synopsis 6 | 7 | Provides commands to get and query cid storage info. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for storage-info 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow storage-info get](pow_storage-info_get.md) - Returns the information about a stored cid. 26 | * [pow storage-info list](pow_storage-info_list.md) - Returns a list of information about all stored cids, filtered by cids if provided. 27 | 28 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-info_get.md: -------------------------------------------------------------------------------- 1 | ## pow storage-info get 2 | 3 | Returns the information about a stored cid. 4 | 5 | ### Synopsis 6 | 7 | Returns the information about a stored cid. 8 | 9 | ``` 10 | pow storage-info get [cid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for get 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-info](pow_storage-info.md) - Provides commands to get and query cid storage info. 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-info_list.md: -------------------------------------------------------------------------------- 1 | ## pow storage-info list 2 | 3 | Returns a list of information about all stored cids, filtered by cids if provided. 4 | 5 | ### Synopsis 6 | 7 | Returns a list of information about all stored cids, filtered by cids if provided. 8 | 9 | ``` 10 | pow storage-info list [optional cid1,cid2,...] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for list 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-info](pow_storage-info.md) - Provides commands to get and query cid storage info. 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs 2 | 3 | Provides commands to query for storage jobs in various states 4 | 5 | ### Synopsis 6 | 7 | Provides commands to query for storage jobs in various statess 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for storage-jobs 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow storage-jobs cancel](pow_storage-jobs_cancel.md) - Cancel an executing storage job 26 | * [pow storage-jobs cancel-executing](pow_storage-jobs_cancel-executing.md) - Cancel all executing jobs 27 | * [pow storage-jobs cancel-queued](pow_storage-jobs_cancel-queued.md) - Cancel all queued jobs 28 | * [pow storage-jobs get](pow_storage-jobs_get.md) - Get a storage job's current status 29 | * [pow storage-jobs list](pow_storage-jobs_list.md) - List storage jobs according to query flag options. 30 | * [pow storage-jobs storage-config](pow_storage-jobs_storage-config.md) - Get the StorageConfig associated with the specified job 31 | * [pow storage-jobs summary](pow_storage-jobs_summary.md) - Give a summary of storage jobs in all states 32 | * [pow storage-jobs watch](pow_storage-jobs_watch.md) - Watch for storage job status updates 33 | 34 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_cancel-executing.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs cancel-executing 2 | 3 | Cancel all executing jobs 4 | 5 | ### Synopsis 6 | 7 | Cancel all executing jobs 8 | 9 | ``` 10 | pow storage-jobs cancel-executing [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for cancel-executing 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_cancel-queued.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs cancel-queued 2 | 3 | Cancel all queued jobs 4 | 5 | ### Synopsis 6 | 7 | Cancel all queued jobs 8 | 9 | ``` 10 | pow storage-jobs cancel-queued [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for cancel-queued 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_cancel.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs cancel 2 | 3 | Cancel an executing storage job 4 | 5 | ### Synopsis 6 | 7 | Cancel an executing storage job 8 | 9 | ``` 10 | pow storage-jobs cancel [jobid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for cancel 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_get.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs get 2 | 3 | Get a storage job's current status 4 | 5 | ### Synopsis 6 | 7 | Get a storage job's current status 8 | 9 | ``` 10 | pow storage-jobs get [jobid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for get 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_list.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs list 2 | 3 | List storage jobs according to query flag options. 4 | 5 | ### Synopsis 6 | 7 | List storage jobs according to query flag options. 8 | 9 | ``` 10 | pow storage-jobs list [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -a, --ascending sort results ascending by time 17 | -c, --cid string return results only for the specified cid 18 | -h, --help help for list 19 | -l, --limit uint limit the number of results returned 20 | -s, --select string return only results using the specified selector: all, queued, executing, final (default "all") 21 | ``` 22 | 23 | ### Options inherited from parent commands 24 | 25 | ``` 26 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 27 | -t, --token string user auth token 28 | ``` 29 | 30 | ### SEE ALSO 31 | 32 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 33 | 34 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_storage-config.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs storage-config 2 | 3 | Get the StorageConfig associated with the specified job 4 | 5 | ### Synopsis 6 | 7 | Get the StorageConfig associated with the specified job 8 | 9 | ``` 10 | pow storage-jobs storage-config [job-id] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for storage-config 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_summary.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs summary 2 | 3 | Give a summary of storage jobs in all states 4 | 5 | ### Synopsis 6 | 7 | Give a summary of storage jobs in all states 8 | 9 | ``` 10 | pow storage-jobs summary [optional cid] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for summary 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_storage-jobs_watch.md: -------------------------------------------------------------------------------- 1 | ## pow storage-jobs watch 2 | 3 | Watch for storage job status updates 4 | 5 | ### Synopsis 6 | 7 | Watch for storage job status updates 8 | 9 | ``` 10 | pow storage-jobs watch [jobid,...] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for watch 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow storage-jobs](pow_storage-jobs.md) - Provides commands to query for storage jobs in various states 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_version.md: -------------------------------------------------------------------------------- 1 | ## pow version 2 | 3 | Display version information for pow and the connected server 4 | 5 | ### Synopsis 6 | 7 | Display version information for pow and the connected server 8 | 9 | ``` 10 | pow version [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for version 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow](pow.md) - A client for storage and retreival of powergate data 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet.md: -------------------------------------------------------------------------------- 1 | ## pow wallet 2 | 3 | Provides commands about filecoin wallets 4 | 5 | ### Synopsis 6 | 7 | Provides commands about filecoin wallets 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for wallet 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 19 | -t, --token string user auth token 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [pow](pow.md) - A client for storage and retreival of powergate data 25 | * [pow wallet addrs](pow_wallet_addrs.md) - Print all wallet addresses for the current user 26 | * [pow wallet balance](pow_wallet_balance.md) - Print the balance of the specified wallet address 27 | * [pow wallet new-addr](pow_wallet_new-addr.md) - Create a new wallet address 28 | * [pow wallet send](pow_wallet_send.md) - Send fil from one managed address to any other address 29 | * [pow wallet sign](pow_wallet_sign.md) - Signs a message with user wallet addresses. 30 | * [pow wallet verify](pow_wallet_verify.md) - Verifies the signature of a message signed with a user wallet address. 31 | 32 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet_addrs.md: -------------------------------------------------------------------------------- 1 | ## pow wallet addrs 2 | 3 | Print all wallet addresses for the current user 4 | 5 | ### Synopsis 6 | 7 | Print all wallet addresses for the current user 8 | 9 | ``` 10 | pow wallet addrs [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for addrs 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet_balance.md: -------------------------------------------------------------------------------- 1 | ## pow wallet balance 2 | 3 | Print the balance of the specified wallet address 4 | 5 | ### Synopsis 6 | 7 | Print the balance of the specified wallet address 8 | 9 | ``` 10 | pow wallet balance [address] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for balance 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet_new-addr.md: -------------------------------------------------------------------------------- 1 | ## pow wallet new-addr 2 | 3 | Create a new wallet address 4 | 5 | ### Synopsis 6 | 7 | Create a new wallet address 8 | 9 | ``` 10 | pow wallet new-addr [name] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -d, --default Make the new address the user default 17 | -f, --format string Optionally specify address format bls or secp256k1 18 | -h, --help help for new-addr 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 25 | -t, --token string user auth token 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 31 | 32 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet_send.md: -------------------------------------------------------------------------------- 1 | ## pow wallet send 2 | 3 | Send fil from one managed address to any other address 4 | 5 | ### Synopsis 6 | 7 | Send fil from one managed address to any other address 8 | 9 | ``` 10 | pow wallet send [from address] [to address] [amount] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for send 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet_sign.md: -------------------------------------------------------------------------------- 1 | ## pow wallet sign 2 | 3 | Signs a message with user wallet addresses. 4 | 5 | ### Synopsis 6 | 7 | Signs a message using all wallet addresses associated with the user 8 | 9 | ``` 10 | pow wallet sign [hex-encoded-message] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for sign 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 29 | 30 | -------------------------------------------------------------------------------- /cli-docs/pow/pow_wallet_verify.md: -------------------------------------------------------------------------------- 1 | ## pow wallet verify 2 | 3 | Verifies the signature of a message signed with a user wallet address. 4 | 5 | ### Synopsis 6 | 7 | Verifies the signature of a message signed with a user wallet address. 8 | 9 | ``` 10 | pow wallet verify [addr] [hex-encoded-message] [hex-encoded-signature] [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for verify 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --serverAddress string address of the powergate service api (default "127.0.0.1:5002") 23 | -t, --token string user auth token 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [pow wallet](pow_wallet.md) - Provides commands about filecoin wallets 29 | 30 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/admin.go: -------------------------------------------------------------------------------- 1 | package admin 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/data" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/storageinfo" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/storagejobs" 8 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/users" 9 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/wallet" 10 | ) 11 | 12 | func init() { 13 | Cmd.PersistentFlags().String("admin-token", "", "admin auth token") 14 | 15 | Cmd.AddCommand( 16 | data.Cmd, 17 | storagejobs.Cmd, 18 | storageinfo.Cmd, 19 | users.Cmd, 20 | wallet.Cmd, 21 | ) 22 | } 23 | 24 | // Cmd is the command. 25 | var Cmd = &cobra.Command{ 26 | Use: "admin", 27 | Short: "Provides admin commands", 28 | Long: `Provides admin commands`, 29 | } 30 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/data/data.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/data/gcstaged" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/data/pinnedcids" 7 | ) 8 | 9 | func init() { 10 | Cmd.AddCommand(gcstaged.Cmd, pinnedcids.Cmd) 11 | } 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "data", 16 | Short: "Provides admin data commands", 17 | Long: `Provides admin data commands`, 18 | } 19 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/data/gcstaged/gcstaged.go: -------------------------------------------------------------------------------- 1 | package gcstaged 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "gcstaged", 16 | Short: "Unpins unused staged data.", 17 | Long: `Unpins staged data not used by queued or executing jobs.`, 18 | Args: cobra.NoArgs, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Admin.Data.GCStaged(c.AdminAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/data/pinnedcids/pinnedcids.go: -------------------------------------------------------------------------------- 1 | package pinnedcids 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "pinnedcids", 16 | Short: "List pinned cids information in hot-storage.", 17 | Long: "List pinned cids information in hot-storage.", 18 | Args: cobra.NoArgs, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Admin.Data.PinnedCids(c.AdminAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/storageinfo/get/get.go: -------------------------------------------------------------------------------- 1 | package get 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "get [user-id] [cid]", 16 | Short: "Returns the information about a stored cid.", 17 | Long: `Returns the information about a stored cid.`, 18 | Args: cobra.ExactArgs(2), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Admin.StorageInfo.Get(c.MustAuthCtx(ctx), args[0], args[1]) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res.StorageInfo) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/storageinfo/list/list.go: -------------------------------------------------------------------------------- 1 | package list 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | func init() { 14 | Cmd.Flags().StringSlice("user-ids", nil, "filter results by provided user ids.") 15 | Cmd.Flags().StringSlice("cids", nil, "filter results by provided cids.") 16 | } 17 | 18 | // Cmd is the command. 19 | var Cmd = &cobra.Command{ 20 | Use: "list", 21 | Short: "Returns a list of information about all stored cids, filtered by user ids and cids if provided.", 22 | Long: `Returns a list of information about all stored cids, filtered by user ids and cids if provided.`, 23 | Args: cobra.NoArgs, 24 | PreRun: func(cmd *cobra.Command, args []string) { 25 | err := viper.BindPFlags(cmd.Flags()) 26 | c.CheckErr(err) 27 | }, 28 | Run: func(cmd *cobra.Command, args []string) { 29 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 30 | defer cancel() 31 | 32 | userIDs := viper.GetStringSlice("user-ids") 33 | cids := viper.GetStringSlice("cids") 34 | 35 | res, err := c.PowClient.Admin.StorageInfo.List(c.MustAuthCtx(ctx), userIDs, cids) 36 | c.CheckErr(err) 37 | 38 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 39 | c.CheckErr(err) 40 | 41 | fmt.Println(string(json)) 42 | }, 43 | } 44 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/storageinfo/storageinfo.go: -------------------------------------------------------------------------------- 1 | package storageinfo 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/storageinfo/get" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/storageinfo/list" 7 | ) 8 | 9 | func init() { 10 | Cmd.AddCommand(get.Cmd, list.Cmd) 11 | } 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "storage-info", 16 | Short: "Provides admin storage info commands", 17 | Long: `Provides admin storage info commands`, 18 | } 19 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/storagejobs/storagejobs.go: -------------------------------------------------------------------------------- 1 | package storagejobs 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/storagejobs/list" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/storagejobs/summary" 7 | ) 8 | 9 | func init() { 10 | Cmd.AddCommand(summary.Cmd, list.Cmd) 11 | } 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "storage-jobs", 16 | Aliases: []string{"storage-job"}, 17 | Short: "Provides admin jobs commands", 18 | Long: `Provides admin jobs commands`, 19 | } 20 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/storagejobs/summary/summary.go: -------------------------------------------------------------------------------- 1 | package summary 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | "github.com/textileio/powergate/v2/api/client/admin" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | func init() { 15 | Cmd.Flags().StringP("user-id", "u", "", "optional user id filter to apply") 16 | Cmd.Flags().StringP("cid", "c", "", "optional cid filter to apply") 17 | } 18 | 19 | // Cmd is the command. 20 | var Cmd = &cobra.Command{ 21 | Use: "summary", 22 | Short: "Give a summary of storage jobs in all states", 23 | Long: `Give a summary of storage jobs in all states`, 24 | Args: cobra.NoArgs, 25 | PreRun: func(cmd *cobra.Command, args []string) { 26 | err := viper.BindPFlags(cmd.Flags()) 27 | c.CheckErr(err) 28 | }, 29 | Run: func(cmd *cobra.Command, args []string) { 30 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 31 | defer cancel() 32 | 33 | var opts []admin.SummaryOption 34 | if viper.IsSet("user-id") { 35 | opts = append(opts, admin.WithUserID(viper.GetString("user-id"))) 36 | } 37 | if viper.IsSet("cid") { 38 | opts = append(opts, admin.WithCid(viper.GetString("cid"))) 39 | } 40 | 41 | res, err := c.PowClient.Admin.StorageJobs.Summary(c.AdminAuthCtx(ctx), opts...) 42 | c.CheckErr(err) 43 | 44 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 45 | c.CheckErr(err) 46 | 47 | fmt.Println(string(json)) 48 | }, 49 | } 50 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/users/create/create.go: -------------------------------------------------------------------------------- 1 | package create 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "create", 16 | Short: "Create a Powergate user.", 17 | Long: `Create a Powergate user.`, 18 | Args: cobra.NoArgs, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Admin.Users.Create(c.AdminAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/users/list/list.go: -------------------------------------------------------------------------------- 1 | package list 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "list", 16 | Short: "List all Powergate users.", 17 | Long: `List all Powergate users.`, 18 | Args: cobra.NoArgs, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Admin.Users.List(c.AdminAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/users/regenerate/regenerate.go: -------------------------------------------------------------------------------- 1 | package regenerate 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "regenerate [token-to-regenerate]", 17 | Short: "Invalidates an existing token and replaces it with a new one.", 18 | Long: `Invalidates an existing token and replaces it with a new one.`, 19 | Args: cobra.ExactArgs(1), 20 | PreRun: func(cmd *cobra.Command, args []string) { 21 | err := viper.BindPFlags(cmd.Flags()) 22 | c.CheckErr(err) 23 | }, 24 | Run: func(cmd *cobra.Command, args []string) { 25 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 26 | defer cancel() 27 | 28 | if len(args) != 1 { 29 | c.Fatal(errors.New("token argument is mandatory")) 30 | } 31 | 32 | res, err := c.PowClient.Admin.Users.RegenerateAuth(c.AdminAuthCtx(ctx), args[0]) 33 | c.CheckErr(err) 34 | 35 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 36 | c.CheckErr(err) 37 | 38 | fmt.Println(string(json)) 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/users/users.go: -------------------------------------------------------------------------------- 1 | package users 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/users/create" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/users/list" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/users/regenerate" 8 | ) 9 | 10 | func init() { 11 | Cmd.AddCommand(create.Cmd, list.Cmd, regenerate.Cmd) 12 | } 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "users", 17 | Aliases: []string{"user"}, 18 | Short: "Provides admin users commands", 19 | Long: `Provides admin users commands`, 20 | } 21 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/wallet/addrs/addrs.go: -------------------------------------------------------------------------------- 1 | package addrs 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "addrs", 16 | Short: "List all addresses associated with this Powergate.", 17 | Long: `List all addresses associated with this Powergate.`, 18 | Args: cobra.NoArgs, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Admin.Wallet.Addresses(c.AdminAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/wallet/new/new.go: -------------------------------------------------------------------------------- 1 | package new 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | func init() { 14 | Cmd.Flags().StringP("format", "f", "bls", "Optionally specify address format bls or secp256k1") 15 | } 16 | 17 | // Cmd is the command. 18 | var Cmd = &cobra.Command{ 19 | Use: "new", 20 | Short: "Creates a new walllet address.", 21 | Long: `Creates a new wallet address.`, 22 | Args: cobra.NoArgs, 23 | PreRun: func(cmd *cobra.Command, args []string) { 24 | err := viper.BindPFlags(cmd.Flags()) 25 | c.CheckErr(err) 26 | }, 27 | Run: func(cmd *cobra.Command, args []string) { 28 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 29 | defer cancel() 30 | 31 | format := viper.GetString("format") 32 | 33 | res, err := c.PowClient.Admin.Wallet.NewAddress(c.AdminAuthCtx(ctx), format) 34 | c.CheckErr(err) 35 | 36 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 37 | c.CheckErr(err) 38 | 39 | fmt.Println(string(json)) 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/wallet/send/send.go: -------------------------------------------------------------------------------- 1 | package send 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | 8 | "google.golang.org/protobuf/encoding/protojson" 9 | 10 | "github.com/spf13/cobra" 11 | "github.com/spf13/viper" 12 | c "github.com/textileio/powergate/v2/cmd/pow/common" 13 | ) 14 | 15 | // Cmd is the command. 16 | var Cmd = &cobra.Command{ 17 | Use: "send [from] [to] [amount]", 18 | Short: "Sends FIL from an address associated with this Powergate to any other address.", 19 | Long: `Sends FIL from an address associated with this Powergate to any other address.`, 20 | Args: cobra.ExactArgs(3), 21 | PreRun: func(cmd *cobra.Command, args []string) { 22 | err := viper.BindPFlags(cmd.Flags()) 23 | c.CheckErr(err) 24 | }, 25 | Run: func(cmd *cobra.Command, args []string) { 26 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 27 | defer cancel() 28 | 29 | amount, ok := new(big.Int).SetString(args[2], 10) 30 | if !ok { 31 | c.CheckErr(fmt.Errorf("parsing amount %v", args[2])) 32 | } 33 | 34 | res, err := c.PowClient.Admin.Wallet.SendFil(c.AdminAuthCtx(ctx), args[0], args[1], amount) 35 | c.CheckErr(err) 36 | 37 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 38 | c.CheckErr(err) 39 | 40 | fmt.Println(string(json)) 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /cmd/pow/cmd/admin/wallet/wallet.go: -------------------------------------------------------------------------------- 1 | package wallet 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/wallet/addrs" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/wallet/new" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/admin/wallet/send" 8 | ) 9 | 10 | func init() { 11 | Cmd.AddCommand(addrs.Cmd, new.Cmd, send.Cmd) 12 | } 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "wallet", 17 | Short: "Provides admin wallet commands", 18 | Long: `Provides admin wallet commands`, 19 | } 20 | -------------------------------------------------------------------------------- /cmd/pow/cmd/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/config/apply" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/config/getdefault" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/config/remove" 8 | "github.com/textileio/powergate/v2/cmd/pow/cmd/config/setdefault" 9 | ) 10 | 11 | func init() { 12 | Cmd.AddCommand(apply.Cmd, getdefault.Cmd, remove.Cmd, setdefault.Cmd) 13 | } 14 | 15 | // Cmd is the command. 16 | var Cmd = &cobra.Command{ 17 | Use: "config", 18 | Short: "Provides commands to interact with cid storage configs", 19 | Long: `Provides commands to interact with cid storage configs`, 20 | } 21 | -------------------------------------------------------------------------------- /cmd/pow/cmd/config/getdefault/getdefault.go: -------------------------------------------------------------------------------- 1 | package getdefault 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "default", 17 | Short: "Returns the default storage config", 18 | Long: `Returns the default storage config`, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.StorageConfig.Default(c.MustAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res.DefaultStorageConfig) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/config/remove/remove.go: -------------------------------------------------------------------------------- 1 | package remove 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | ) 11 | 12 | // Cmd is the command. 13 | var Cmd = &cobra.Command{ 14 | Use: "remove [cid]", 15 | Short: "Removes a Cid from being tracked as an active storage", 16 | Long: `Removes a Cid from being tracked as an active storage. The Cid should have both Hot and Cold storage disabled, if that isn't the case it will return ErrActiveInStorage`, 17 | Args: cobra.ExactArgs(1), 18 | PreRun: func(cmd *cobra.Command, args []string) { 19 | err := viper.BindPFlags(cmd.Flags()) 20 | c.CheckErr(err) 21 | }, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) 24 | defer cancel() 25 | _, err := c.PowClient.StorageConfig.Remove(c.MustAuthCtx(ctx), args[0]) 26 | c.CheckErr(err) 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /cmd/pow/cmd/config/setdefault/setdefault.go: -------------------------------------------------------------------------------- 1 | package setdefault 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "io" 7 | "os" 8 | "time" 9 | 10 | logging "github.com/ipfs/go-log/v2" 11 | "github.com/spf13/cobra" 12 | "github.com/spf13/viper" 13 | userPb "github.com/textileio/powergate/v2/api/gen/powergate/user/v1" 14 | c "github.com/textileio/powergate/v2/cmd/pow/common" 15 | "google.golang.org/protobuf/encoding/protojson" 16 | ) 17 | 18 | var ( 19 | log = logging.Logger("setdefault") 20 | ) 21 | 22 | // Cmd is the command. 23 | var Cmd = &cobra.Command{ 24 | Use: "set-default [optional file]", 25 | Short: "Sets the default storage config from stdin or a file", 26 | Long: `Sets the default storage config from stdin or a file`, 27 | Args: cobra.MaximumNArgs(1), 28 | PreRun: func(cmd *cobra.Command, args []string) { 29 | err := viper.BindPFlags(cmd.Flags()) 30 | c.CheckErr(err) 31 | }, 32 | Run: func(cmd *cobra.Command, args []string) { 33 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) 34 | defer cancel() 35 | 36 | var reader io.Reader 37 | if len(args) > 0 { 38 | file, err := os.Open(args[0]) 39 | defer func() { 40 | if err := file.Close(); err != nil { 41 | log.Errorf("closing config file: %s", err) 42 | } 43 | }() 44 | reader = file 45 | c.CheckErr(err) 46 | } else { 47 | reader = cmd.InOrStdin() 48 | } 49 | 50 | buf := new(bytes.Buffer) 51 | _, err := buf.ReadFrom(reader) 52 | c.CheckErr(err) 53 | 54 | config := &userPb.StorageConfig{} 55 | err = protojson.UnmarshalOptions{}.Unmarshal(buf.Bytes(), config) 56 | c.CheckErr(err) 57 | 58 | _, err = c.PowClient.StorageConfig.SetDefault(c.MustAuthCtx(ctx), config) 59 | c.CheckErr(err) 60 | }, 61 | } 62 | -------------------------------------------------------------------------------- /cmd/pow/cmd/data/data.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/data/get" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/data/info" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/data/log" 8 | "github.com/textileio/powergate/v2/cmd/pow/cmd/data/replace" 9 | "github.com/textileio/powergate/v2/cmd/pow/cmd/data/stage" 10 | "github.com/textileio/powergate/v2/cmd/pow/cmd/data/summary" 11 | ) 12 | 13 | func init() { 14 | Cmd.AddCommand(get.Cmd, info.Cmd, log.Cmd, replace.Cmd, stage.Cmd, summary.Cmd) 15 | } 16 | 17 | // Cmd is the command. 18 | var Cmd = &cobra.Command{ 19 | Use: "data", 20 | Short: "Provides commands to interact with general data APIs", 21 | Long: `Provides commands to interact with general data APIs`, 22 | } 23 | -------------------------------------------------------------------------------- /cmd/pow/cmd/data/info/info.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "info cid", 16 | Short: "Get information about the current storage state of a cid", 17 | Long: `Get information about the current storage state of a cid`, 18 | Args: cobra.ExactArgs(1), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Data.CidInfo(c.MustAuthCtx(ctx), args[0]) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/data/log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | 10 | "github.com/spf13/cobra" 11 | "github.com/spf13/viper" 12 | "github.com/textileio/powergate/v2/api/client" 13 | c "github.com/textileio/powergate/v2/cmd/pow/common" 14 | ) 15 | 16 | func init() { 17 | Cmd.Flags().StringP("jid", "j", "", "Display information for only this job id") 18 | } 19 | 20 | // Cmd is the command. 21 | var Cmd = &cobra.Command{ 22 | Use: "log [cid]", 23 | Aliases: []string{"logs"}, 24 | Short: "Display logs for specified cid", 25 | Long: `Display logs for specified cid`, 26 | Args: cobra.ExactArgs(1), 27 | PreRun: func(cmd *cobra.Command, args []string) { 28 | err := viper.BindPFlags(cmd.Flags()) 29 | c.CheckErr(err) 30 | }, 31 | Run: func(cmd *cobra.Command, args []string) { 32 | opts := []client.WatchLogsOption{client.WithHistory(true)} 33 | jid := viper.GetString("jid") 34 | if jid != "" { 35 | opts = append(opts, client.WithJobIDFilter(jid)) 36 | } 37 | 38 | ch := make(chan client.WatchLogsEvent) 39 | ctx, cancel := context.WithCancel(context.Background()) 40 | defer cancel() 41 | 42 | err := c.PowClient.Data.WatchLogs(c.MustAuthCtx(ctx), ch, args[0], opts...) 43 | c.CheckErr(err) 44 | 45 | interrupt := make(chan os.Signal) 46 | signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM) 47 | go func() { 48 | <-interrupt 49 | cancel() 50 | os.Exit(0) 51 | }() 52 | 53 | for { 54 | event, ok := <-ch 55 | if !ok { 56 | break 57 | } 58 | if event.Err != nil { 59 | c.Fatal(event.Err) 60 | break 61 | } 62 | ts := time.Unix(event.Res.LogEntry.Time, 0) 63 | c.Message("%v - %v", ts.Format("2006-01-02T15:04:05"), event.Res.LogEntry.Message) 64 | } 65 | }, 66 | } 67 | -------------------------------------------------------------------------------- /cmd/pow/cmd/data/replace/replace.go: -------------------------------------------------------------------------------- 1 | package replace 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | func init() { 15 | Cmd.Flags().BoolP("watch", "w", false, "Watch the progress of the resulting job") 16 | } 17 | 18 | // Cmd is the command. 19 | var Cmd = &cobra.Command{ 20 | Use: "replace [cid1] [cid2]", 21 | Short: "Applies a StorageConfig for c2 equal to that of c1, and removes c1", 22 | Long: `Applies a StorageConfig for c2 equal to that of c1, and removes c1. This operation is more efficient than manually removing and adding in two separate operations`, 23 | Args: cobra.ExactArgs(2), 24 | PreRun: func(cmd *cobra.Command, args []string) { 25 | err := viper.BindPFlags(cmd.Flags()) 26 | c.CheckErr(err) 27 | }, 28 | Run: func(cmd *cobra.Command, args []string) { 29 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) 30 | defer cancel() 31 | 32 | res, err := c.PowClient.Data.ReplaceData(c.MustAuthCtx(ctx), args[0], args[1]) 33 | c.CheckErr(err) 34 | 35 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 36 | c.CheckErr(err) 37 | 38 | fmt.Println(string(json)) 39 | 40 | if viper.GetBool("watch") { 41 | c.WatchJobIds(res.JobId) 42 | } 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /cmd/pow/cmd/deals/deals.go: -------------------------------------------------------------------------------- 1 | package deals 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/deals/retrievals" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/deals/storage" 7 | ) 8 | 9 | func init() { 10 | Cmd.AddCommand(retrievals.Cmd, storage.Cmd) 11 | } 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "deals", 16 | Short: "Provides commands to view Filecoin deal information", 17 | Long: `Provides commands to view Filecoin deal information`, 18 | } 19 | -------------------------------------------------------------------------------- /cmd/pow/cmd/id/id.go: -------------------------------------------------------------------------------- 1 | package id 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "id", 17 | Short: "Returns the user id", 18 | Long: `Returns the user id`, 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.UserID(c.MustAuthCtx(ctx)) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storageinfo/get/get.go: -------------------------------------------------------------------------------- 1 | package get 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "get [cid]", 16 | Short: "Returns the information about a stored cid.", 17 | Long: `Returns the information about a stored cid.`, 18 | Args: cobra.ExactArgs(1), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.StorageInfo.Get(c.MustAuthCtx(ctx), args[0]) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res.StorageInfo) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storageinfo/list/list.go: -------------------------------------------------------------------------------- 1 | package list 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "list [optional cid1,cid2,...]", 17 | Short: "Returns a list of information about all stored cids, filtered by cids if provided.", 18 | Long: `Returns a list of information about all stored cids, filtered by cids if provided.`, 19 | Args: cobra.MaximumNArgs(1), 20 | PreRun: func(cmd *cobra.Command, args []string) { 21 | err := viper.BindPFlags(cmd.Flags()) 22 | c.CheckErr(err) 23 | }, 24 | Run: func(cmd *cobra.Command, args []string) { 25 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 26 | defer cancel() 27 | 28 | var cids []string 29 | if len(args) > 0 { 30 | cids = strings.Split(args[0], ",") 31 | } 32 | 33 | res, err := c.PowClient.StorageInfo.List(c.MustAuthCtx(ctx), cids...) 34 | c.CheckErr(err) 35 | 36 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 37 | c.CheckErr(err) 38 | 39 | fmt.Println(string(json)) 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storageinfo/storageinfo.go: -------------------------------------------------------------------------------- 1 | package storageinfo 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storageinfo/get" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storageinfo/list" 7 | ) 8 | 9 | func init() { 10 | Cmd.AddCommand(get.Cmd, list.Cmd) 11 | } 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "storage-info", 16 | Short: "Provides commands to get and query cid storage info.", 17 | Long: `Provides commands to get and query cid storage info.`, 18 | } 19 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/cancel/cancel.go: -------------------------------------------------------------------------------- 1 | package cancel 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | ) 11 | 12 | // Cmd is the command. 13 | var Cmd = &cobra.Command{ 14 | Use: "cancel [jobid]", 15 | Short: "Cancel an executing storage job", 16 | Long: `Cancel an executing storage job`, 17 | Args: cobra.ExactArgs(1), 18 | PreRun: func(cmd *cobra.Command, args []string) { 19 | err := viper.BindPFlags(cmd.Flags()) 20 | c.CheckErr(err) 21 | }, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 24 | defer cancel() 25 | 26 | _, err := c.PowClient.StorageJobs.Cancel(c.MustAuthCtx(ctx), args[0]) 27 | c.CheckErr(err) 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/cancelexecuting/cancelexecuting.go: -------------------------------------------------------------------------------- 1 | package cancelexecuting 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | "github.com/textileio/powergate/v2/api/client" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "cancel-executing", 16 | Short: "Cancel all executing jobs", 17 | Long: "Cancel all executing jobs", 18 | Args: cobra.ExactArgs(0), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx := c.MustAuthCtx(context.Background()) 25 | 26 | js, err := c.PowClient.StorageJobs.List(ctx, client.ListConfig{Select: client.Executing}) 27 | c.CheckErr(err) 28 | 29 | for _, j := range js.StorageJobs { 30 | ctx, cancel := context.WithTimeout(ctx, time.Second*10) 31 | defer cancel() 32 | 33 | _, err := c.PowClient.StorageJobs.Cancel(ctx, j.Id) 34 | c.CheckErr(err) 35 | } 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/cancelqueued/cancelqueued.go: -------------------------------------------------------------------------------- 1 | package cancelqueued 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | "github.com/textileio/powergate/v2/api/client" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "cancel-queued", 16 | Short: "Cancel all queued jobs", 17 | Long: "Cancel all queued jobs", 18 | Args: cobra.ExactArgs(0), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx := c.MustAuthCtx(context.Background()) 25 | 26 | js, err := c.PowClient.StorageJobs.List(ctx, client.ListConfig{Select: client.Queued}) 27 | c.CheckErr(err) 28 | 29 | for _, j := range js.StorageJobs { 30 | ctx, cancel := context.WithTimeout(ctx, time.Second*10) 31 | defer cancel() 32 | 33 | _, err := c.PowClient.StorageJobs.Cancel(ctx, j.Id) 34 | c.CheckErr(err) 35 | } 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/get/get.go: -------------------------------------------------------------------------------- 1 | package get 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "get [jobid]", 16 | Short: "Get a storage job's current status", 17 | Long: `Get a storage job's current status`, 18 | Args: cobra.ExactArgs(1), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.StorageJobs.Get(c.MustAuthCtx(ctx), args[0]) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res.StorageJob) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/storageconfig/storageconfig.go: -------------------------------------------------------------------------------- 1 | package storageconfig 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "storage-config [job-id]", 16 | Short: "Get the StorageConfig associated with the specified job", 17 | Long: `Get the StorageConfig associated with the specified job`, 18 | Args: cobra.ExactArgs(1), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.StorageJobs.StorageConfig(c.MustAuthCtx(ctx), args[0]) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res.StorageConfig) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/storagejobs.go: -------------------------------------------------------------------------------- 1 | package storagejobs 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/cancel" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/cancelexecuting" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/cancelqueued" 8 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/get" 9 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/list" 10 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/storageconfig" 11 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/summary" 12 | "github.com/textileio/powergate/v2/cmd/pow/cmd/storagejobs/watch" 13 | ) 14 | 15 | func init() { 16 | Cmd.AddCommand( 17 | cancel.Cmd, 18 | cancelexecuting.Cmd, 19 | cancelqueued.Cmd, 20 | get.Cmd, 21 | list.Cmd, 22 | storageconfig.Cmd, 23 | summary.Cmd, 24 | watch.Cmd, 25 | ) 26 | } 27 | 28 | // Cmd is the command. 29 | var Cmd = &cobra.Command{ 30 | Use: "storage-jobs", 31 | Aliases: []string{"storage-job"}, 32 | Short: "Provides commands to query for storage jobs in various states", 33 | Long: `Provides commands to query for storage jobs in various statess`, 34 | } 35 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/summary/summary.go: -------------------------------------------------------------------------------- 1 | package summary 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | "github.com/textileio/powergate/v2/api/client" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "summary [optional cid]", 17 | Short: "Give a summary of storage jobs in all states", 18 | Long: `Give a summary of storage jobs in all states`, 19 | Args: cobra.RangeArgs(0, 1), 20 | PreRun: func(cmd *cobra.Command, args []string) { 21 | err := viper.BindPFlags(cmd.Flags()) 22 | c.CheckErr(err) 23 | }, 24 | Run: func(cmd *cobra.Command, args []string) { 25 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 26 | defer cancel() 27 | 28 | var opts []client.SummaryOption 29 | if len(args) > 0 { 30 | opts = append(opts, client.WithCid(args[0])) 31 | } 32 | 33 | res, err := c.PowClient.StorageJobs.Summary(c.MustAuthCtx(ctx), opts...) 34 | c.CheckErr(err) 35 | 36 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 37 | c.CheckErr(err) 38 | 39 | fmt.Println(string(json)) 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /cmd/pow/cmd/storagejobs/watch/watch.go: -------------------------------------------------------------------------------- 1 | package watch 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/spf13/cobra" 7 | "github.com/spf13/viper" 8 | c "github.com/textileio/powergate/v2/cmd/pow/common" 9 | ) 10 | 11 | // Cmd is the command. 12 | var Cmd = &cobra.Command{ 13 | Use: "watch [jobid,...]", 14 | Short: "Watch for storage job status updates", 15 | Long: `Watch for storage job status updates`, 16 | Args: cobra.ExactArgs(1), 17 | PreRun: func(cmd *cobra.Command, args []string) { 18 | err := viper.BindPFlags(cmd.Flags()) 19 | c.CheckErr(err) 20 | }, 21 | Run: func(cmd *cobra.Command, args []string) { 22 | jobIds := strings.Split(args[0], ",") 23 | c.WatchJobIds(jobIds...) 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/addrs/addrs.go: -------------------------------------------------------------------------------- 1 | package addrs 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "addrs", 16 | Short: "Print all wallet addresses for the current user", 17 | Long: `Print all wallet addresses for the current user`, 18 | PreRun: func(cmd *cobra.Command, args []string) { 19 | err := viper.BindPFlags(cmd.Flags()) 20 | c.CheckErr(err) 21 | }, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 24 | defer cancel() 25 | 26 | res, err := c.PowClient.Wallet.Addresses(c.MustAuthCtx(ctx)) 27 | c.CheckErr(err) 28 | 29 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 30 | c.CheckErr(err) 31 | 32 | fmt.Println(string(json)) 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/balance/balance.go: -------------------------------------------------------------------------------- 1 | package balance 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | c "github.com/textileio/powergate/v2/cmd/pow/common" 10 | "google.golang.org/protobuf/encoding/protojson" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "balance [address]", 16 | Short: "Print the balance of the specified wallet address", 17 | Long: `Print the balance of the specified wallet address`, 18 | Args: cobra.ExactArgs(1), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | res, err := c.PowClient.Wallet.Balance(ctx, args[0]) 28 | c.CheckErr(err) 29 | 30 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 31 | c.CheckErr(err) 32 | 33 | fmt.Println(string(json)) 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/newaddr/newaddr.go: -------------------------------------------------------------------------------- 1 | package newaddr 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "time" 8 | 9 | "github.com/spf13/cobra" 10 | "github.com/spf13/viper" 11 | "github.com/textileio/powergate/v2/api/client" 12 | c "github.com/textileio/powergate/v2/cmd/pow/common" 13 | "google.golang.org/protobuf/encoding/protojson" 14 | ) 15 | 16 | func init() { 17 | Cmd.Flags().StringP("format", "f", "", "Optionally specify address format bls or secp256k1") 18 | Cmd.Flags().BoolP("default", "d", false, "Make the new address the user default") 19 | } 20 | 21 | // Cmd is the command. 22 | var Cmd = &cobra.Command{ 23 | Use: "new-addr [name]", 24 | Short: "Create a new wallet address", 25 | Long: `Create a new wallet address`, 26 | PreRun: func(cmd *cobra.Command, args []string) { 27 | err := viper.BindPFlags(cmd.Flags()) 28 | c.CheckErr(err) 29 | }, 30 | Run: func(cmd *cobra.Command, args []string) { 31 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*60) 32 | defer cancel() 33 | 34 | if len(args) != 1 { 35 | c.Fatal(errors.New("must provide a name for the address")) 36 | } 37 | 38 | format := viper.GetString("format") 39 | makeDefault := viper.GetBool("default") 40 | 41 | var opts []client.NewAddressOption 42 | if format != "" { 43 | opts = append(opts, client.WithAddressType(format)) 44 | } 45 | if makeDefault { 46 | opts = append(opts, client.WithMakeDefault(makeDefault)) 47 | } 48 | 49 | res, err := c.PowClient.Wallet.NewAddress(c.MustAuthCtx(ctx), args[0], opts...) 50 | c.CheckErr(err) 51 | 52 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 53 | c.CheckErr(err) 54 | 55 | fmt.Println(string(json)) 56 | }, 57 | } 58 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/send/send.go: -------------------------------------------------------------------------------- 1 | package send 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | 8 | "google.golang.org/protobuf/encoding/protojson" 9 | 10 | "github.com/spf13/cobra" 11 | "github.com/spf13/viper" 12 | c "github.com/textileio/powergate/v2/cmd/pow/common" 13 | ) 14 | 15 | // Cmd is the command. 16 | var Cmd = &cobra.Command{ 17 | Use: "send [from address] [to address] [amount]", 18 | Short: "Send fil from one managed address to any other address", 19 | Long: `Send fil from one managed address to any other address`, 20 | Args: cobra.ExactArgs(3), 21 | PreRun: func(cmd *cobra.Command, args []string) { 22 | err := viper.BindPFlags(cmd.Flags()) 23 | c.CheckErr(err) 24 | }, 25 | Run: func(cmd *cobra.Command, args []string) { 26 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 27 | defer cancel() 28 | 29 | from := args[0] 30 | to := args[1] 31 | 32 | amount, ok := new(big.Int).SetString(args[2], 10) 33 | if !ok { 34 | c.CheckErr(fmt.Errorf("parsing amount %v", args[2])) 35 | } 36 | 37 | res, err := c.PowClient.Wallet.SendFil(c.MustAuthCtx(ctx), from, to, amount) 38 | c.CheckErr(err) 39 | 40 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 41 | c.CheckErr(err) 42 | 43 | fmt.Println(string(json)) 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/sign/sign.go: -------------------------------------------------------------------------------- 1 | package sign 2 | 3 | import ( 4 | "context" 5 | "encoding/hex" 6 | "os" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | ) 12 | 13 | // Cmd is the command. 14 | var Cmd = &cobra.Command{ 15 | Use: "sign [hex-encoded-message]", 16 | Short: "Signs a message with user wallet addresses.", 17 | Long: "Signs a message using all wallet addresses associated with the user", 18 | Args: cobra.ExactArgs(1), 19 | PreRun: func(cmd *cobra.Command, args []string) { 20 | err := viper.BindPFlags(cmd.Flags()) 21 | c.CheckErr(err) 22 | }, 23 | Run: func(cmd *cobra.Command, args []string) { 24 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 25 | defer cancel() 26 | 27 | b, err := hex.DecodeString(args[0]) 28 | c.CheckErr(err) 29 | 30 | res, err := c.PowClient.Wallet.Addresses(c.MustAuthCtx(ctx)) 31 | c.CheckErr(err) 32 | 33 | data := make([][]string, len(res.Addresses)) 34 | for i, a := range res.Addresses { 35 | signRes, err := c.PowClient.Wallet.SignMessage(c.MustAuthCtx(ctx), a.Address, b) 36 | c.CheckErr(err) 37 | data[i] = []string{a.Address, hex.EncodeToString(signRes.Signature)} 38 | } 39 | 40 | c.RenderTable(os.Stdout, []string{"address", "signature"}, data) 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/verify/verify.go: -------------------------------------------------------------------------------- 1 | package verify 2 | 3 | import ( 4 | "context" 5 | "encoding/hex" 6 | "fmt" 7 | 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/viper" 10 | c "github.com/textileio/powergate/v2/cmd/pow/common" 11 | "google.golang.org/protobuf/encoding/protojson" 12 | ) 13 | 14 | // Cmd is the command. 15 | var Cmd = &cobra.Command{ 16 | Use: "verify [addr] [hex-encoded-message] [hex-encoded-signature]", 17 | Short: "Verifies the signature of a message signed with a user wallet address.", 18 | Long: "Verifies the signature of a message signed with a user wallet address.", 19 | Args: cobra.ExactArgs(3), 20 | PreRun: func(cmd *cobra.Command, args []string) { 21 | err := viper.BindPFlags(cmd.Flags()) 22 | c.CheckErr(err) 23 | }, 24 | Run: func(cmd *cobra.Command, args []string) { 25 | ctx, cancel := context.WithTimeout(context.Background(), c.CmdTimeout) 26 | defer cancel() 27 | 28 | mb, err := hex.DecodeString(args[1]) 29 | c.CheckErr(err) 30 | sb, err := hex.DecodeString(args[2]) 31 | c.CheckErr(err) 32 | 33 | res, err := c.PowClient.Wallet.VerifyMessage(c.MustAuthCtx(ctx), args[0], mb, sb) 34 | c.CheckErr(err) 35 | 36 | json, err := protojson.MarshalOptions{Multiline: true, Indent: " ", EmitUnpopulated: true}.Marshal(res) 37 | c.CheckErr(err) 38 | 39 | fmt.Println(string(json)) 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /cmd/pow/cmd/wallet/wallet.go: -------------------------------------------------------------------------------- 1 | package wallet 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/textileio/powergate/v2/cmd/pow/cmd/wallet/addrs" 6 | "github.com/textileio/powergate/v2/cmd/pow/cmd/wallet/balance" 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd/wallet/newaddr" 8 | "github.com/textileio/powergate/v2/cmd/pow/cmd/wallet/send" 9 | "github.com/textileio/powergate/v2/cmd/pow/cmd/wallet/sign" 10 | "github.com/textileio/powergate/v2/cmd/pow/cmd/wallet/verify" 11 | ) 12 | 13 | func init() { 14 | Cmd.AddCommand(addrs.Cmd, balance.Cmd, newaddr.Cmd, send.Cmd, sign.Cmd, verify.Cmd) 15 | } 16 | 17 | // Cmd is the command. 18 | var Cmd = &cobra.Command{ 19 | Use: "wallet", 20 | Short: "Provides commands about filecoin wallets", 21 | Long: `Provides commands about filecoin wallets`, 22 | } 23 | -------------------------------------------------------------------------------- /cmd/pow/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/textileio/powergate/v2/cmd/pow/cmd" 8 | ) 9 | 10 | func main() { 11 | if err := cmd.Cmd.Execute(); err != nil { 12 | fmt.Println(err) 13 | os.Exit(1) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cmd/powbench/README.md: -------------------------------------------------------------------------------- 1 | # Powergate bench 2 | 3 | Powergate `powbench` is an utility tool that allows to run benchmark scenarios against a properly configured Powergate server. 4 | 5 | To build and install `powbench`, from the root of the Powergate repo, run: 6 | 7 | ```bash 8 | > make install-powbench 9 | > powbench -h 10 | Usage of powbench: 11 | --maxParallel int Max parallel file storage (default 1) 12 | --minerAddr string Miner address to force Powergate to select for making deals (default "t01000") 13 | --pgAddr string Powergate server multiaddress (default "/ip4/127.0.0.1/tcp/5002") 14 | --randSeed int Random seed used to generate random samples data (default 42) 15 | --sampleSize int Size of randomly generated files in bytes (default 1024) 16 | --totalSamples int Total samples to run (default 3) 17 | ``` 18 | 19 | The targeted Powergate server should have enabled the auto-funding of newly created FFS instances wallet addresses. 20 | This means: 21 | - The Lotus node owned by Powergate must have a wallet address; the _master address_. 22 | - _master address_ should have funds. 23 | - This address will be used to automatically send funds to the new FFS instance that will run the benchmark. 24 | - Powergate should be started with two flags: 25 | - `--lotusmasteraddr`: with the above mentioned address. 26 | - `--walletinitialfund`: an reasonable amount of _attoFIL_ that will be transferred from the master address to the created FFS instance. It should be enough to fund _all_ deals that will be ran in the scenario. 27 | - _Note: env variables can be used instead of command line flags, i.e: `POWD_LOTUSMASTERADDR` and `POWD_WALLETINITIALFUND` respectively._ 28 | 29 | -------------------------------------------------------------------------------- /cmd/powcfg/ratelim/ratelim.go: -------------------------------------------------------------------------------- 1 | package ratelim 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | // RateLim allows to logically cap the maximum number of functions. 9 | // It returns a slice of error strings that happened during execution. 10 | type RateLim struct { 11 | c chan struct{} 12 | 13 | lock sync.Mutex 14 | errors []string 15 | } 16 | 17 | // New returns a new RateLim. 18 | func New(limit int) (*RateLim, error) { 19 | if limit <= 0 { 20 | return nil, fmt.Errorf("limit should be positive") 21 | } 22 | 23 | return &RateLim{c: make(chan struct{}, limit)}, nil 24 | } 25 | 26 | // Exec executes f when a slot is available within the defined 27 | // maximum limit. 28 | func (rl *RateLim) Exec(f func() error) { 29 | rl.c <- struct{}{} 30 | go func() { 31 | defer func() { <-rl.c }() 32 | err := f() 33 | if err != nil { 34 | rl.lock.Lock() 35 | rl.errors = append(rl.errors, err.Error()) 36 | rl.lock.Unlock() 37 | } 38 | }() 39 | } 40 | 41 | // Wait will block until all executing functions finish, and return 42 | // all error strings that happened during executions. RateLim can't 43 | // be reused after this call. 44 | func (rl *RateLim) Wait() []string { 45 | for i := 0; i < cap(rl.c); i++ { 46 | rl.c <- struct{}{} 47 | } 48 | return rl.errors 49 | } 50 | -------------------------------------------------------------------------------- /cmd/powcfg/testdata/badgerdumpv1/000000.vlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/cmd/powcfg/testdata/badgerdumpv1/000000.vlog -------------------------------------------------------------------------------- /cmd/powcfg/testdata/badgerdumpv1/000002.sst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/cmd/powcfg/testdata/badgerdumpv1/000002.sst -------------------------------------------------------------------------------- /cmd/powcfg/testdata/badgerdumpv1/KEYREGISTRY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/cmd/powcfg/testdata/badgerdumpv1/KEYREGISTRY -------------------------------------------------------------------------------- /cmd/powcfg/testdata/badgerdumpv1/MANIFEST: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/cmd/powcfg/testdata/badgerdumpv1/MANIFEST -------------------------------------------------------------------------------- /cmd/powcfg/transform_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/ipfs/go-datastore" 9 | badger "github.com/ipfs/go-ds-badger2" 10 | logger "github.com/ipfs/go-log/v2" 11 | cp "github.com/otiai10/copy" 12 | "github.com/stretchr/testify/require" 13 | "github.com/textileio/powergate/v2/ffs" 14 | ) 15 | 16 | func TestIpfsAddBump(t *testing.T) { 17 | logger.SetDebugLogging() 18 | _ = logger.SetLogLevel("badger", "error") 19 | 20 | for _, dryRun := range []bool{false, true} { 21 | dryRun := dryRun 22 | t.Run(fmt.Sprintf("dryrun %v", dryRun), func(t *testing.T) { 23 | t.Parallel() 24 | tmpDir := t.TempDir() 25 | err := cp.Copy("testdata/badgerdumpv1", tmpDir+"/badgerdump") 26 | require.NoError(t, err) 27 | 28 | opts := &badger.DefaultOptions 29 | ds, err := badger.NewDatastore(tmpDir+"/badgerdump", opts) 30 | require.NoError(t, err) 31 | defer func() { require.NoError(t, ds.Close()) }() 32 | 33 | modified, err := applyTransform(ds, dryRun, bumpIpfsAddTimeout(12345)) 34 | require.NoError(t, err) 35 | 36 | // Verify 37 | require.Equal(t, 678, modified) 38 | 39 | var cfg ffs.StorageConfig 40 | k := datastore.NewKey("/ffs/manager/api/274cb2c5-a0da-49fa-91a8-97b9d387d4fa/istore/cidstorageconfig/QmbtfAvVRVgEa9RH6vYpKg1HWbBQjxiZ6vNG1AAvt3vyfR") 41 | buf, err := ds.Get(k) 42 | require.NoError(t, err) 43 | err = json.Unmarshal(buf, &cfg) 44 | require.NoError(t, err) 45 | 46 | if dryRun { 47 | require.NotEqual(t, 12345, cfg.Hot.Ipfs.AddTimeout) 48 | return 49 | } 50 | require.Equal(t, 12345, cfg.Hot.Ipfs.AddTimeout) 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /cmd/powcfg/transformations.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/textileio/powergate/v2/ffs" 5 | ) 6 | 7 | // bumpIpfsAddTimeout is a transformation that updates Hot.Ipfs.AddTimeout 8 | // if the current value is less than a minimum desired value. 9 | func bumpIpfsAddTimeout(minValue int) Transform { 10 | return func(cfg *ffs.StorageConfig) (bool, error) { 11 | if cfg.Hot.Ipfs.AddTimeout >= minValue { 12 | return false, nil 13 | } 14 | 15 | cfg.Hot.Ipfs.AddTimeout = minValue 16 | 17 | return true, nil 18 | } 19 | } 20 | 21 | var _ = unsetFilecoinUnlimitedPrice 22 | 23 | // unsetFilecoinUnlimitedPrice is a transformation that sets 24 | // Cold.Filecoin.MaxPrice to maxPrice if the current value is 25 | // 0 (no limit). 26 | func unsetFilecoinUnlimitedPrice(maxPrice uint64) Transform { 27 | return func(cfg *ffs.StorageConfig) (bool, error) { 28 | if cfg.Cold.Filecoin.MaxPrice > 0 { 29 | return false, nil 30 | } 31 | 32 | cfg.Cold.Filecoin.MaxPrice = maxPrice 33 | 34 | return true, nil 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /deals/module/dealwatcher/metrics.go: -------------------------------------------------------------------------------- 1 | package dealwatcher 2 | 3 | import ( 4 | "go.opentelemetry.io/otel/attribute" 5 | "go.opentelemetry.io/otel/metric" 6 | "go.opentelemetry.io/otel/metric/global" 7 | ) 8 | 9 | var ( 10 | attrDealTracked = attribute.Key("tracked").String("yes") 11 | attrDealUntracked = attribute.Key("tracked").String("no") 12 | ) 13 | 14 | func (dw *DealWatcher) initMetrics() { 15 | meter := global.Meter("powergate") 16 | 17 | dw.metricDealUpdates = metric.Must(meter).NewInt64Counter("powergate.dealwatcher.updates.total") 18 | dw.metricDealUpdatesChanFailure = metric.Must(meter).NewInt64Counter("powergate.dealwatcher.updates.chan.failure.total") 19 | } 20 | -------------------------------------------------------------------------------- /deals/module/metrics.go: -------------------------------------------------------------------------------- 1 | package module 2 | 3 | import ( 4 | "go.opentelemetry.io/otel/metric" 5 | "go.opentelemetry.io/otel/metric/global" 6 | ) 7 | 8 | func (m *Module) initMetrics() { 9 | meter := global.Meter("powergate") 10 | m.metricDealTracking = metric.Must(meter).NewInt64UpDownCounter("powergate.deal.tracking") 11 | m.metricRetrievalTracking = metric.Must(meter).NewInt64UpDownCounter("powergate.retrieval.tracking") 12 | } 13 | -------------------------------------------------------------------------------- /deals/module/store/metrics.go: -------------------------------------------------------------------------------- 1 | package store 2 | 3 | import ( 4 | "go.opentelemetry.io/otel/attribute" 5 | "go.opentelemetry.io/otel/metric" 6 | "go.opentelemetry.io/otel/metric/global" 7 | ) 8 | 9 | var ( 10 | attrTypeStorage = attribute.Key("type").String("storage") 11 | attrTypeRetrieval = attribute.Key("type").String("retrieval") 12 | 13 | attrSuccess = attribute.Key("status").String("success") 14 | attrFailed = attribute.Key("status").String("failed") 15 | ) 16 | 17 | func (s *Store) initMetrics() { 18 | meter := global.Meter("powergate") 19 | 20 | s.metricFinalTotal = metric.Must(meter).NewInt64Counter("powergate.deals.record.final.total") 21 | s.metricVolumeBytes = metric.Must(meter).NewInt64Counter("powergate.deals.record.volume.bytes") 22 | } 23 | -------------------------------------------------------------------------------- /deals/module/util.go: -------------------------------------------------------------------------------- 1 | package module 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | type autodeleteFile struct { 9 | *os.File 10 | } 11 | 12 | func (af *autodeleteFile) Close() error { 13 | if err := af.File.Close(); err != nil { 14 | return fmt.Errorf("closing retrieval file: %s", err) 15 | } 16 | if err := os.Remove(af.File.Name()); err != nil { 17 | return fmt.Errorf("autodeleting retrieval file: %s", err) 18 | } 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /dist/install.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | # From https://github.com/ipfs/go-ipfs/blob/ccef991a194beaedf009b1d0702b1150db3da0a6/cmd/ipfs/dist/install.sh 5 | # 6 | # Installation script for powergate. It tries to move $bin in one of the 7 | # directories stored in $binpaths. 8 | 9 | INSTALL_DIR="$(dirname "$0")" 10 | 11 | file="$INSTALL_DIR/{{ .Env.POW_FILE }}" 12 | binpaths="/usr/local/bin /usr/bin" 13 | 14 | # This variable contains a nonzero length string in case the script fails 15 | # because of missing write permissions. 16 | is_write_perm_missing="" 17 | 18 | for binpath in $binpaths; do 19 | if mv "$file" "$binpath/$file" 2>/dev/null; then 20 | echo "Moved $file to $binpath" 21 | exit 0 22 | else 23 | if test -d "$binpath" && ! test -w "$binpath"; then 24 | is_write_perm_missing=1 25 | fi 26 | fi 27 | done 28 | 29 | echo "We cannot install $file in one of the directories $binpaths" 30 | 31 | if test -n "$is_write_perm_missing"; then 32 | echo "It seems that we do not have the necessary write permissions." 33 | echo "Perhaps try running this script as a privileged user:" 34 | echo 35 | echo " sudo $0" 36 | echo 37 | fi 38 | 39 | exit 1 -------------------------------------------------------------------------------- /docker/LICENSE: -------------------------------------------------------------------------------- 1 | Partially based on https://github.com/vegasbrianc/prometheus 2 | Corresponding LICENSE: 3 | 4 | MIT License 5 | 6 | Copyright (c) 2017 Brian Christner 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. -------------------------------------------------------------------------------- /docker/Makefile: -------------------------------------------------------------------------------- 1 | localnet-down: 2 | DOCKER_BUILDKIT=1 \ 3 | docker-compose -p localnet \ 4 | -f docker-compose-localnet.yaml \ 5 | -f ipfs-image.yaml \ 6 | -f powergate-build-context.yaml \ 7 | down 8 | .PHONY: localnet-down 9 | 10 | localnet: 11 | DOCKER_BUILDKIT=1 \ 12 | BIGSECTORS=true \ 13 | docker-compose -p localnet \ 14 | -f docker-compose-localnet.yaml \ 15 | -f ipfs-image.yaml \ 16 | -f powergate-build-context.yaml \ 17 | up --build -V 18 | .PHONY: localnet 19 | 20 | 21 | up: down 22 | DOCKER_BUILDKIT=1 \ 23 | LOTUS_IMAGE_TAG=v1.10.0 \ 24 | docker-compose \ 25 | -p mainnet \ 26 | -f docker-compose.yaml \ 27 | -f ipfs-image.yaml \ 28 | -f powergate-build-context.yaml \ 29 | up --build 30 | .PHONY: up 31 | 32 | down: 33 | DOCKER_BUILDKIT=1 \ 34 | LOTUS_IMAGE_TAG=v1.10.0 \ 35 | docker-compose \ 36 | -p mainnet \ 37 | -f docker-compose.yaml \ 38 | -f ipfs-image.yaml \ 39 | -f powergate-build-context.yaml \ 40 | down 41 | .PHONY: down 42 | 43 | 44 | up-calibration: down-calibration 45 | DOCKER_BUILDKIT=1 \ 46 | LOTUS_IMAGE_TAG=ntwk-calibration-d6c42 \ 47 | docker-compose \ 48 | -p calibration \ 49 | -f docker-compose.yaml \ 50 | -f ipfs-image.yaml \ 51 | -f powergate-build-context.yaml \ 52 | up --build 53 | .PHONY: up-calibration 54 | 55 | down-calibration: 56 | DOCKER_BUILDKIT=1 \ 57 | LOTUS_IMAGE_TAG=ntwk-calibration-d6c42 \ 58 | docker-compose \ 59 | -p calibration \ 60 | -f docker-compose.yaml \ 61 | -f ipfs-image.yaml \ 62 | -f powergate-build-context.yaml \ 63 | down 64 | .PHONY: down-calibration 65 | -------------------------------------------------------------------------------- /docker/docker-compose-localnet.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | powergate: 5 | ports: 6 | - 8889:8889 7 | - 8888:8888 8 | - 6060:6060 9 | - 5002:5002 10 | - 6002:6002 11 | - 7000:7000 12 | depends_on: 13 | - ipfs 14 | - lotus 15 | environment: 16 | - POWD_DEVNET=true 17 | - POWD_LOTUSHOST=/dns4/lotus/tcp/7777 18 | - POWD_IPFSAPIADDR=/dns4/ipfs/tcp/5001 19 | restart: unless-stopped 20 | 21 | ipfs: 22 | ports: 23 | - 5001:5001 24 | 25 | lotus: 26 | image: textile/lotus-devnet:v1.10.0 27 | ports: 28 | - 7777:7777 29 | environment: 30 | - TEXLOTUSDEVNET_SPEED=300 31 | - TEXLOTUSDEVNET_BIGSECTORS=${BIGSECTORS} 32 | - TEXLOTUSDEVNET_IPFSADDR=/dns4/ipfs/tcp/5001 33 | -------------------------------------------------------------------------------- /docker/grafana/config.monitoring: -------------------------------------------------------------------------------- 1 | GF_SECURITY_ADMIN_PASSWORD=foobar 2 | GF_USERS_ALLOW_SIGN_UP=false 3 | GF_AUTH_ANONYMOUS_ENABLED=true 4 | GF_AUTH_ANONYMOUS_ORG_NAME=Main Org. 5 | GF_AUTH_ANONYMOUS_ROLE=Viewer -------------------------------------------------------------------------------- /docker/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: false 10 | options: 11 | path: /etc/grafana/provisioning/dashboards 12 | -------------------------------------------------------------------------------- /docker/grafana/provisioning/datasources/datasource.yml: -------------------------------------------------------------------------------- 1 | # config file version 2 | apiVersion: 1 3 | 4 | # list of datasources that should be deleted from the database 5 | deleteDatasources: 6 | - name: Prometheus 7 | orgId: 1 8 | 9 | # list of datasources to insert/update depending 10 | # whats available in the database 11 | datasources: 12 | # name of the datasource. Required 13 | - name: Prometheus 14 | # datasource type. Required 15 | type: prometheus 16 | # access mode. direct or proxy. Required 17 | access: proxy 18 | # org id. will default to orgId 1 if not specified 19 | orgId: 1 20 | # url 21 | url: http://prometheus:9090 22 | # database password, if used 23 | password: 24 | # database user, if used 25 | user: 26 | # database name, if used 27 | database: 28 | # enable/disable basic auth 29 | basicAuth: false 30 | # basic auth username, if used 31 | basicAuthUser: 32 | # basic auth password, if used 33 | basicAuthPassword: 34 | # enable/disable with credentials headers 35 | withCredentials: 36 | # mark as default datasource. Max one per org 37 | isDefault: true 38 | # fields that will be converted to json and stored in json_data 39 | jsonData: 40 | graphiteVersion: "1.1" 41 | tlsAuth: false 42 | tlsAuthWithCACert: false 43 | # json object of data that will be encrypted. 44 | secureJsonData: 45 | tlsCACert: "..." 46 | tlsClientCert: "..." 47 | tlsClientKey: "..." 48 | version: 1 49 | # allow users to edit datasources from the UI. 50 | editable: true 51 | -------------------------------------------------------------------------------- /docker/ipfs-image.yaml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | 5 | ipfs: 6 | image: ipfs/go-ipfs:v0.7.0 7 | command: ["daemon", "--migrate=true", "--enable-pubsub-experiment"] 8 | -------------------------------------------------------------------------------- /docker/powergate-build-context.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | powergate: 5 | build: 6 | context: ../ 7 | -------------------------------------------------------------------------------- /docker/powergate-image.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | powergate: 5 | image: textile/powergate:latest 6 | -------------------------------------------------------------------------------- /docker/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | scrape_timeout: 10s 5 | 6 | external_labels: 7 | monitor: 'textile-fc' 8 | 9 | scrape_configs: 10 | - job_name: 'prometheus' 11 | scrape_interval: 5s 12 | static_configs: 13 | - targets: ['prometheus:9090'] 14 | 15 | - job_name: 'cadvisor' 16 | scrape_interval: 5s 17 | static_configs: 18 | - targets: ['cadvisor:8082'] 19 | 20 | - job_name: 'textile-fc' 21 | scrape_interval: 5s 22 | static_configs: 23 | - targets: ['powergate:8888'] 24 | -------------------------------------------------------------------------------- /fchost/fchost_test.go: -------------------------------------------------------------------------------- 1 | package fchost 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestPingBootstrapers(t *testing.T) { 11 | // This test is skipped since interopnet is getting reset 12 | // a lot and boostrap peers change very frequently. 13 | // We can re-enable this when the network becomes stable again. 14 | t.SkipNow() 15 | h, err := New("mainnet", false) 16 | require.NoError(t, err) 17 | err = h.Bootstrap() 18 | require.NoError(t, err) 19 | 20 | bsPeers, err := getBootstrapPeers("mainnet") 21 | require.NoError(t, err) 22 | for _, addr := range bsPeers { 23 | pong := h.Ping(context.Background(), addr.ID) 24 | if pong { 25 | return 26 | } 27 | } 28 | t.Fatalf("no bootstrap peers replied") 29 | } 30 | -------------------------------------------------------------------------------- /ffs/api/api_logs.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/ipfs/go-cid" 8 | "github.com/textileio/powergate/v2/ffs" 9 | ) 10 | 11 | // WatchLogs pushes human-friendly messages about Cid executions. The method is blocking 12 | // and will continue to send messages until the context is canceled. 13 | func (i *API) WatchLogs(ctx context.Context, ch chan<- ffs.LogEntry, c cid.Cid, opts ...GetLogsOption) error { 14 | _, err := i.is.getStorageConfigs(c) 15 | if err == ErrNotFound { 16 | return ErrNotFound 17 | } 18 | if err != nil { 19 | return fmt.Errorf("validating cid: %s", err) 20 | } 21 | 22 | config := &GetLogsConfig{} 23 | for _, o := range opts { 24 | o(config) 25 | } 26 | 27 | if config.history { 28 | lgs, err := i.sched.GetLogsByCid(ctx, i.cfg.ID, c) 29 | if err != nil { 30 | return fmt.Errorf("getting history logs of %s: %s", c, err) 31 | } 32 | for _, l := range lgs { 33 | if config.jid == ffs.EmptyJobID || config.jid == l.Jid { 34 | ch <- l 35 | } 36 | } 37 | } 38 | 39 | ichan := make(chan ffs.LogEntry, cap(ch)) 40 | go func() { 41 | err = i.sched.WatchLogs(ctx, ichan) 42 | close(ichan) 43 | }() 44 | for le := range ichan { 45 | if c == le.Cid && le.APIID == i.cfg.ID && (config.jid == ffs.EmptyJobID || config.jid == le.Jid) { 46 | ch <- le 47 | } 48 | } 49 | if err != nil { 50 | return fmt.Errorf("listening to cid logs: %s", err) 51 | } 52 | 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /ffs/api/api_storageinfo.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/ipfs/go-cid" 7 | "github.com/textileio/powergate/v2/ffs" 8 | "github.com/textileio/powergate/v2/ffs/scheduler" 9 | ) 10 | 11 | // StorageInfo returns the information about a stored Cid. If no information is available, 12 | // since the Cid was never stored, it returns ErrNotFound. 13 | func (i *API) StorageInfo(cid cid.Cid) (ffs.StorageInfo, error) { 14 | inf, err := i.sched.GetStorageInfo(i.cfg.ID, cid) 15 | if err == scheduler.ErrNotFound { 16 | return inf, ErrNotFound 17 | } 18 | if err != nil { 19 | return inf, fmt.Errorf("getting cid storage info: %s", err) 20 | } 21 | return inf, nil 22 | } 23 | 24 | // ListStorageInfo returns a list of information about all stored cids, filtered by cids if provided. 25 | func (i *API) ListStorageInfo(cids ...cid.Cid) ([]ffs.StorageInfo, error) { 26 | return i.sched.ListStorageInfo([]ffs.APIID{i.cfg.ID}, cids) 27 | } 28 | -------------------------------------------------------------------------------- /ffs/api/types.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/textileio/powergate/v2/ffs" 7 | ) 8 | 9 | var ( 10 | // ErrNotFound returned when instance configuration doesn't exist. 11 | ErrNotFound = errors.New("stored item not found") 12 | ) 13 | 14 | // InstanceConfig has general information about a Api instance. 15 | type InstanceConfig struct { 16 | ID ffs.APIID 17 | Addrs map[string]AddrInfo 18 | DefaultStorageConfig ffs.StorageConfig 19 | } 20 | 21 | // AddrInfo provides information about a wallet address. 22 | type AddrInfo struct { 23 | Name string 24 | Addr string 25 | Type string 26 | } 27 | 28 | // NewAddressConfig contains options for creating a new wallet address. 29 | type NewAddressConfig struct { 30 | makeDefault bool 31 | addressType string 32 | } 33 | 34 | // GetLogsConfig contains configuration for a stream-log 35 | // of human-friendly messages for a Cid execution. 36 | type GetLogsConfig struct { 37 | jid ffs.JobID 38 | history bool 39 | } 40 | -------------------------------------------------------------------------------- /ffs/filcold/metrics.go: -------------------------------------------------------------------------------- 1 | package filcold 2 | 3 | import ( 4 | "go.opentelemetry.io/otel/attribute" 5 | "go.opentelemetry.io/otel/metric" 6 | "go.opentelemetry.io/otel/metric/global" 7 | ) 8 | 9 | var ( 10 | metricTagPreprocessingWaiting = attribute.Key("status").String("waiting") 11 | metricTagPreprocessingInProgress = attribute.Key("status").String("inprogress") 12 | ) 13 | 14 | func (fc *FilCold) initMetrics() { 15 | meter := global.Meter("powergate") 16 | fc.metricPreprocessingTotal = metric.Must(meter).NewInt64UpDownCounter("powergate.preprocessing.queue.total") 17 | } 18 | -------------------------------------------------------------------------------- /ffs/integrationtest/general/cov.pprof: -------------------------------------------------------------------------------- 1 | mode: atomic 2 | -------------------------------------------------------------------------------- /ffs/scheduler/internal/ristore/cistore.go: -------------------------------------------------------------------------------- 1 | package ristore 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/ipfs/go-datastore" 9 | "github.com/textileio/powergate/v2/ffs" 10 | ) 11 | 12 | var ( 13 | // ErrNotFound indicates there's not information for the retrieval. 14 | ErrNotFound = errors.New("retrieval info not found") 15 | ) 16 | 17 | // Store stores retrieval information. 18 | type Store struct { 19 | ds datastore.Datastore 20 | } 21 | 22 | // New returns a new retrieval information store. 23 | func New(ds datastore.Datastore) *Store { 24 | return &Store{ 25 | ds: ds, 26 | } 27 | } 28 | 29 | // Get gets information about an executed retrieval. 30 | func (s *Store) Get(rid ffs.RetrievalID) (ffs.RetrievalInfo, error) { 31 | var ri ffs.RetrievalInfo 32 | buf, err := s.ds.Get(makeKey(rid)) 33 | if err == datastore.ErrNotFound { 34 | return ri, ErrNotFound 35 | } 36 | if err != nil { 37 | return ri, fmt.Errorf("getting retrieval info from datastore: %s", err) 38 | } 39 | if err := json.Unmarshal(buf, &ri); err != nil { 40 | return ri, fmt.Errorf("unmarshaling retrieval info from datastore: %s", err) 41 | } 42 | return ri, nil 43 | } 44 | 45 | // Put saves new information about a retrieval. 46 | func (s *Store) Put(ri ffs.RetrievalInfo) error { 47 | if ri.ID == ffs.EmptyRetrievalID { 48 | return fmt.Errorf("retrieval id can't be empty") 49 | } 50 | buf, err := json.Marshal(ri) 51 | if err != nil { 52 | return fmt.Errorf("marshaling retrieval info for datastore: %s", err) 53 | } 54 | if err := s.ds.Put(makeKey(ri.ID), buf); err != nil { 55 | return fmt.Errorf("putting retrieval info in datastore: %s", err) 56 | } 57 | return nil 58 | } 59 | 60 | func makeKey(rid ffs.RetrievalID) datastore.Key { 61 | return datastore.NewKey(rid.String()) 62 | } 63 | -------------------------------------------------------------------------------- /ffs/scheduler/internal/rjstore/rjstore_test.go: -------------------------------------------------------------------------------- 1 | package rjstore 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | "github.com/textileio/powergate/v2/ffs" 8 | "github.com/textileio/powergate/v2/tests" 9 | ) 10 | 11 | func TestEnqueue(t *testing.T) { 12 | t.Parallel() 13 | s := create(t) 14 | j := createJob() 15 | err := s.Enqueue(j) 16 | require.NoError(t, err) 17 | jQueued, err := s.Get(j.ID) 18 | require.NoError(t, err) 19 | j.Status = ffs.Queued 20 | require.Equal(t, j, jQueued) 21 | } 22 | 23 | func TestDequeue(t *testing.T) { 24 | t.Parallel() 25 | t.Run("Success", func(t *testing.T) { 26 | t.Parallel() 27 | s := create(t) 28 | j := createJob() 29 | err := s.Enqueue(j) 30 | require.NoError(t, err) 31 | j2, err := s.Dequeue() 32 | require.NoError(t, err) 33 | j.Status = ffs.Executing 34 | require.NotNil(t, j2) 35 | require.Equal(t, j, *j2) 36 | }) 37 | t.Run("Empty", func(t *testing.T) { 38 | t.Parallel() 39 | s := create(t) 40 | j, err := s.Dequeue() 41 | require.NoError(t, err) 42 | require.Nil(t, j) 43 | }) 44 | } 45 | 46 | func createJob() ffs.RetrievalJob { 47 | return ffs.RetrievalJob{ 48 | ID: ffs.NewJobID(), 49 | APIID: "ApiIDTest", 50 | RetrievalID: ffs.NewRetrievalID(), 51 | } 52 | } 53 | 54 | func create(t *testing.T) *Store { 55 | ds := tests.NewTxMapDatastore() 56 | store, err := New(ds) 57 | require.NoError(t, err) 58 | return store 59 | } 60 | -------------------------------------------------------------------------------- /ffs/scheduler/internal/sjstore/metrics.go: -------------------------------------------------------------------------------- 1 | package sjstore 2 | 3 | import ( 4 | "go.opentelemetry.io/otel/attribute" 5 | "go.opentelemetry.io/otel/metric" 6 | "go.opentelemetry.io/otel/metric/global" 7 | ) 8 | 9 | var ( 10 | attrStatusQueued = attribute.Key("jobstatus").String("queued") 11 | attrStatusExecuting = attribute.Key("jobstatus").String("executing") 12 | attrStatusSuccess = attribute.Key("jobstatus").String("success") 13 | attrStatusCanceled = attribute.Key("jobstatus").String("canceled") 14 | attrStatusFailed = attribute.Key("jobstatus").String("failed") 15 | ) 16 | 17 | func (s *Store) initMetrics() { 18 | meter := global.Meter("powergate") 19 | s.metricJobCounter = metric.Must(meter).NewInt64UpDownCounter("powergate.storage.job.total") 20 | } 21 | -------------------------------------------------------------------------------- /filchain/filchain.go: -------------------------------------------------------------------------------- 1 | package filchain 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/textileio/powergate/v2/lotus" 8 | ) 9 | 10 | // FilChain is an abstraction of the Filecoin network. 11 | type FilChain struct { 12 | clientBuilder lotus.ClientBuilder 13 | } 14 | 15 | // New creates a new deal module. 16 | func New(clientBuilder lotus.ClientBuilder) *FilChain { 17 | return &FilChain{ 18 | clientBuilder: clientBuilder, 19 | } 20 | } 21 | 22 | // GetHeight returns the current height of the chain for the targeted Lotus node. 23 | func (lc *FilChain) GetHeight(ctx context.Context) (uint64, error) { 24 | client, cls, err := lc.clientBuilder(ctx) 25 | if err != nil { 26 | return 0, fmt.Errorf("creating lotus client: %s", err) 27 | } 28 | defer cls() 29 | h, err := client.ChainHead(ctx) 30 | if err != nil { 31 | return 0, fmt.Errorf("get head from lotus node: %s", err) 32 | } 33 | return uint64(h.Height()), nil 34 | } 35 | -------------------------------------------------------------------------------- /gateway/Makefile: -------------------------------------------------------------------------------- 1 | ASSET_DIRS = $(shell find ./public/ -type d) 2 | ASSET_FILES = $(shell find ./public/ -type f -name '*') 3 | 4 | assets.go: ./public/ $(ASSET_DIRS) $(ASSET_FILES) 5 | go-assets-builder . -p gateway -o assets.go -------------------------------------------------------------------------------- /gateway/public/html/404.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header" "404 Not Found"}} 2 |
3 |
4 | 5 |
6 |
7 |

Nothing to see here!

8 |
9 |
10 | {{template "footer"}} 11 | -------------------------------------------------------------------------------- /gateway/public/html/asks.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header" "Asks Index"}} 2 | {{template "menu" .}} 3 |
4 | {{template "table" .}} 5 |
6 | {{template "footer"}} -------------------------------------------------------------------------------- /gateway/public/html/error.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header" "Oops!"}} 2 |
3 |
4 | 5 |
6 |
7 |

{{.Code}} Error: {{.Error}}

8 |
9 |
10 | {{template "footer"}} 11 | -------------------------------------------------------------------------------- /gateway/public/html/faults.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header" "Fault Index"}} 2 | {{template "menu" .}} 3 |
4 | {{template "table" .}} 5 |
6 | {{template "footer"}} 7 | -------------------------------------------------------------------------------- /gateway/public/html/miners.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header" "Miners Index"}} 2 | {{template "menu" .}} 3 |
4 | {{template "table" .MetaData}} 5 |
6 |
7 | {{template "table" .ChainData}} 8 |
9 | {{template "footer"}} -------------------------------------------------------------------------------- /gateway/public/html/reputation.gohtml: -------------------------------------------------------------------------------- 1 | {{template "header" "Reputation"}} 2 | {{template "menu" .}} 3 |
4 | {{template "table" .}} 5 |
6 | {{template "footer"}} -------------------------------------------------------------------------------- /gateway/public/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/gateway/public/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /gateway/public/img/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/gateway/public/img/android-chrome-512x512.png -------------------------------------------------------------------------------- /gateway/public/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/gateway/public/img/apple-touch-icon.png -------------------------------------------------------------------------------- /gateway/public/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/gateway/public/img/favicon-16x16.png -------------------------------------------------------------------------------- /gateway/public/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/gateway/public/img/favicon-32x32.png -------------------------------------------------------------------------------- /gateway/public/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/gateway/public/img/favicon.ico -------------------------------------------------------------------------------- /gateway/public/img/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /index/ask/internal/store/store.go: -------------------------------------------------------------------------------- 1 | package store 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/ipfs/go-datastore" 8 | "github.com/textileio/powergate/v2/index/ask" 9 | ) 10 | 11 | var ( 12 | dsKey = datastore.NewKey("index") 13 | ) 14 | 15 | // Store persists ask index into a datastore. 16 | type Store struct { 17 | ds datastore.Datastore 18 | } 19 | 20 | // New returns a new store for ask index. 21 | func New(ds datastore.Datastore) *Store { 22 | return &Store{ 23 | ds: ds, 24 | } 25 | } 26 | 27 | // Save persist the index into the datastore. 28 | func (s *Store) Save(idx ask.Index) error { 29 | buf, err := json.Marshal(idx) 30 | if err != nil { 31 | return fmt.Errorf("marshaling new index: %s", err) 32 | } 33 | if err = s.ds.Put(dsKey, buf); err != nil { 34 | return fmt.Errorf("saving to datastore: %s", err) 35 | } 36 | return nil 37 | } 38 | 39 | // Get returns the last saved ask index. If no ask index was persisted, 40 | // it returns an valid empty index. 41 | func (s *Store) Get() (ask.Index, error) { 42 | buf, err := s.ds.Get(dsKey) 43 | if err != nil { 44 | if err == datastore.ErrNotFound { 45 | return ask.Index{Storage: make(map[string]ask.StorageAsk)}, nil 46 | } 47 | return ask.Index{}, err 48 | } 49 | idx := ask.Index{} 50 | if err = json.Unmarshal(buf, &idx); err != nil { 51 | return ask.Index{}, err 52 | } 53 | return idx, nil 54 | } 55 | -------------------------------------------------------------------------------- /index/ask/runner/metrics.go: -------------------------------------------------------------------------------- 1 | package runner 2 | 3 | import ( 4 | "context" 5 | 6 | "go.opentelemetry.io/otel/metric" 7 | "go.opentelemetry.io/otel/metric/global" 8 | "go.opentelemetry.io/otel/unit" 9 | ) 10 | 11 | // Init register all views. 12 | func (ai *Runner) initMetrics() { 13 | meter := global.Meter("powergate") 14 | 15 | _ = metric.Must(meter).NewFloat64ValueObserver("powergate.index.ask.progress", ai.progressValueObserver, metric.WithDescription("Ask index refresh progress"), metric.WithUnit(unit.Dimensionless)) 16 | ai.refreshDuration = metric.Must(meter).NewInt64ValueRecorder("powergate.index.ask.refresh.duration", metric.WithDescription("Refresh duration"), metric.WithUnit(unit.Milliseconds)) 17 | } 18 | 19 | func (ai *Runner) progressValueObserver(ctx context.Context, result metric.Float64ObserverResult) { 20 | ai.metricLock.Lock() 21 | defer ai.metricLock.Unlock() 22 | 23 | result.Observe(ai.progress) 24 | } 25 | -------------------------------------------------------------------------------- /index/ask/types.go: -------------------------------------------------------------------------------- 1 | package ask 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // Module provides information about storage asks. 8 | type Module interface { 9 | Get() Index 10 | Query(q Query) ([]StorageAsk, error) 11 | Listen() <-chan struct{} 12 | Unregister(c chan struct{}) 13 | } 14 | 15 | // Index contains Ask information from markets. 16 | type Index struct { 17 | LastUpdated time.Time 18 | StorageMedianPrice uint64 19 | Storage map[string]StorageAsk 20 | } 21 | 22 | // StorageAsk has information about an active ask from a storage miner. 23 | type StorageAsk struct { 24 | Miner string 25 | Price uint64 26 | VerifiedPrice uint64 27 | MinPieceSize uint64 28 | MaxPieceSize uint64 29 | Timestamp int64 30 | Expiry int64 31 | } 32 | 33 | // Query specifies filtering and paging data to retrieve active Asks. 34 | type Query struct { 35 | MaxPrice uint64 36 | PieceSize uint64 37 | Limit int 38 | Offset int 39 | } 40 | -------------------------------------------------------------------------------- /index/faults/module/faults_test.go: -------------------------------------------------------------------------------- 1 | package module 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | "time" 7 | 8 | logging "github.com/ipfs/go-log/v2" 9 | "github.com/stretchr/testify/require" 10 | "github.com/textileio/powergate/v2/tests" 11 | "github.com/textileio/powergate/v2/util" 12 | ) 13 | 14 | func TestMain(m *testing.M) { 15 | util.AvgBlockTime = time.Millisecond * 100 16 | logging.SetAllLoggers(logging.LevelError) 17 | os.Exit(m.Run()) 18 | } 19 | 20 | func TestFreshIndex(t *testing.T) { 21 | // Skipped until #235 lands. 22 | t.SkipNow() 23 | client, _, _ := tests.CreateLocalDevnet(t, 1, 300) 24 | time.Sleep(time.Millisecond * 500) // Allow the network to some tipsets 25 | 26 | sh, err := New(tests.NewTxMapDatastore(), client, false) 27 | require.NoError(t, err) 28 | 29 | // Wait for some rounds of faults updating 30 | for i := 0; i < 10; i++ { 31 | select { 32 | case <-time.After(time.Second): 33 | t.Fatal("timeout waiting for miner index full refresh") 34 | case <-sh.Listen(): 35 | } 36 | } 37 | index := sh.Get() 38 | if index.TipSetKey == "" { 39 | t.Fatalf("miner info state is invalid: %s %d", index.TipSetKey, len(index.Miners)) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /index/faults/types.go: -------------------------------------------------------------------------------- 1 | package faults 2 | 3 | // IndexSnapshot contains faults histoy information up-to a TipSetKey. 4 | type IndexSnapshot struct { 5 | TipSetKey string 6 | Miners map[string]Faults 7 | } 8 | 9 | // Faults contains epochs where a fault was detected for a miner. 10 | type Faults struct { 11 | Epochs []int64 12 | } 13 | 14 | // Module provides faults information about the Filecoin network. 15 | type Module interface { 16 | Get() IndexSnapshot 17 | Listen() <-chan struct{} 18 | Unregister(c chan struct{}) 19 | } 20 | -------------------------------------------------------------------------------- /index/miner/lotusidx/metrics.go: -------------------------------------------------------------------------------- 1 | package lotusidx 2 | 3 | import ( 4 | "context" 5 | 6 | "go.opentelemetry.io/otel/attribute" 7 | "go.opentelemetry.io/otel/metric" 8 | "go.opentelemetry.io/otel/metric/global" 9 | "go.opentelemetry.io/otel/unit" 10 | ) 11 | 12 | var ( 13 | onchainSubindex = attribute.Key("subindex").String("onchain") 14 | metaSubindex = attribute.Key("subindex").String("meta") 15 | ) 16 | 17 | func (mi *Index) initMetrics() { 18 | meter := global.Meter("powergate") 19 | 20 | _ = metric.Must(meter).NewFloat64ValueObserver("powergate.index.miner.progress", mi.progressValueObserver, metric.WithDescription("Miner index refresh progress"), metric.WithUnit(unit.Dimensionless)) 21 | mi.meterRefreshDuration = metric.Must(meter).NewInt64ValueRecorder("powergate.index.miner.refresh.duration", metric.WithDescription("Refresh duration"), metric.WithUnit(unit.Milliseconds)) 22 | } 23 | 24 | func (mi *Index) progressValueObserver(ctx context.Context, result metric.Float64ObserverResult) { 25 | mi.metricLock.Lock() 26 | defer mi.metricLock.Unlock() 27 | result.Observe(mi.onchainProgress, onchainSubindex) 28 | result.Observe(mi.metaProgress, metaSubindex) 29 | } 30 | -------------------------------------------------------------------------------- /index/miner/types.go: -------------------------------------------------------------------------------- 1 | package miner 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // IndexSnapshot contains on-chain and off-chain information about miners. 8 | type IndexSnapshot struct { 9 | Meta MetaIndex 10 | OnChain ChainIndex 11 | } 12 | 13 | // ChainIndex contains on-chain information about miners. 14 | type ChainIndex struct { 15 | LastUpdated int64 16 | Miners map[string]OnChainMinerData 17 | } 18 | 19 | // OnChainMinerData contains on-chain data about a miner. 20 | type OnChainMinerData struct { 21 | Power uint64 22 | RelativePower float64 23 | SectorSize uint64 24 | SectorsLive uint64 25 | SectorsActive uint64 26 | SectorsFaulty uint64 27 | } 28 | 29 | // MetaIndex contains off-chain information about miners. 30 | type MetaIndex struct { 31 | Info map[string]Meta 32 | } 33 | 34 | // Meta contains off-chain information of a miner. 35 | type Meta struct { 36 | LastUpdated time.Time 37 | UserAgent string 38 | Location Location 39 | } 40 | 41 | // Location contains geeoinformation. 42 | type Location struct { 43 | Country string 44 | Longitude float64 45 | Latitude float64 46 | } 47 | 48 | // Module provides information about miners in the 49 | // Filecoin network. 50 | type Module interface { 51 | Get() IndexSnapshot 52 | Listen() <-chan struct{} 53 | Unregister(c chan struct{}) 54 | } 55 | -------------------------------------------------------------------------------- /iplocation/iplocation.go: -------------------------------------------------------------------------------- 1 | package iplocation 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/multiformats/go-multiaddr" 7 | ) 8 | 9 | var ( 10 | // ErrCantResolve indicates that geoinformation couldn't be resolved for a host. 11 | ErrCantResolve = errors.New("can't resolve multiaddr location information") 12 | ) 13 | 14 | // Location contains geoinformation. 15 | type Location struct { 16 | Country string 17 | Latitude float64 18 | Longitude float64 19 | } 20 | 21 | // LocationResolver resolver gets location information from a set of multiaddresses of 22 | // a single host. 23 | type LocationResolver interface { 24 | Resolve(mas []multiaddr.Multiaddr) (Location, error) 25 | } 26 | -------------------------------------------------------------------------------- /iplocation/maxmind/GeoLite2-City.mmdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/iplocation/maxmind/GeoLite2-City.mmdb -------------------------------------------------------------------------------- /iplocation/maxmind/maxmind_test.go: -------------------------------------------------------------------------------- 1 | package maxmind 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiformats/go-multiaddr" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestResolve(t *testing.T) { 11 | mm := setup(t) 12 | 13 | tests := []struct { 14 | Name string 15 | Maddr multiaddr.Multiaddr 16 | CountryISO string 17 | Error bool 18 | }{ 19 | { 20 | Name: "China IP4", 21 | Maddr: multiaddr.StringCast("/ip4/59.110.242.123/tcp/1234"), 22 | CountryISO: "CN", 23 | }, 24 | { 25 | Name: "Uruguay IP4", 26 | Maddr: multiaddr.StringCast("/ip4/186.52.85.100/tcp/1234"), 27 | CountryISO: "UY", 28 | }, 29 | { 30 | Name: "DNS", 31 | Maddr: multiaddr.StringCast("/dns4/google.com/tcp/80"), 32 | CountryISO: "US", 33 | }, 34 | { 35 | Name: "USA IP6", 36 | Maddr: multiaddr.StringCast("/ip6/2001:4b0:85a3:0000:0000:8a2e:0370:7334/tcp/1234"), 37 | CountryISO: "US", 38 | }, 39 | { 40 | Name: "Unresolvable IP4", 41 | Maddr: multiaddr.StringCast("/ip4/127.0.233.233/tcp/1234"), 42 | Error: true, 43 | }, 44 | } 45 | for _, tc := range tests { 46 | l, err := mm.Resolve([]multiaddr.Multiaddr{tc.Maddr}) 47 | require.Equal(t, tc.Error, err != nil) 48 | if tc.Error { 49 | continue 50 | } 51 | require.Equal(t, tc.CountryISO, l.Country) 52 | require.NotZero(t, l.Latitude) 53 | require.NotZero(t, l.Longitude) 54 | } 55 | } 56 | 57 | func setup(t *testing.T) *MaxMind { 58 | mm, err := New("GeoLite2-City.mmdb") 59 | require.NoError(t, err) 60 | t.Cleanup(func() { _ = mm.Close() }) 61 | return mm 62 | } 63 | -------------------------------------------------------------------------------- /lotus/client.go: -------------------------------------------------------------------------------- 1 | package lotus 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/filecoin-project/go-jsonrpc" 10 | "github.com/filecoin-project/lotus/api" 11 | logging "github.com/ipfs/go-log/v2" 12 | ma "github.com/multiformats/go-multiaddr" 13 | 14 | "github.com/textileio/powergate/v2/util" 15 | ) 16 | 17 | var ( 18 | log = logging.Logger("lotus-client") 19 | ) 20 | 21 | // ClientBuilder creates a new Lotus client. 22 | type ClientBuilder func(ctx context.Context) (*api.FullNodeStruct, func(), error) 23 | 24 | // NewBuilder creates a new ClientBuilder. 25 | func NewBuilder(maddr ma.Multiaddr, authToken string, connRetries int) (ClientBuilder, error) { 26 | addr, err := util.TCPAddrFromMultiAddr(maddr) 27 | if err != nil { 28 | return nil, err 29 | } 30 | headers := http.Header{ 31 | "Authorization": []string{"Bearer " + authToken}, 32 | } 33 | 34 | return func(ctx context.Context) (*api.FullNodeStruct, func(), error) { 35 | var api api.FullNodeStruct 36 | var closer jsonrpc.ClientCloser 37 | var err error 38 | for i := 0; i < connRetries; i++ { 39 | if ctx.Err() != nil { 40 | return nil, nil, fmt.Errorf("canceled by context") 41 | } 42 | closer, err = jsonrpc.NewMergeClient(context.Background(), "ws://"+addr+"/rpc/v0", "Filecoin", 43 | []interface{}{ 44 | &api.Internal, 45 | &api.CommonStruct.Internal, 46 | }, headers) 47 | if err == nil { 48 | break 49 | } 50 | log.Warnf("failed to connect to Lotus client %s, retrying...", err) 51 | time.Sleep(time.Second * 10) 52 | } 53 | if err != nil { 54 | return nil, nil, fmt.Errorf("couldn't connect to Lotus API: %s", err) 55 | } 56 | 57 | return &api, closer, nil 58 | }, nil 59 | } 60 | -------------------------------------------------------------------------------- /migration/migration1_joblogger_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ipfs/go-cid" 7 | "github.com/stretchr/testify/require" 8 | "github.com/textileio/powergate/v2/ffs" 9 | "github.com/textileio/powergate/v2/tests" 10 | "github.com/textileio/powergate/v2/util" 11 | ) 12 | 13 | func TestV1_JobLogger(t *testing.T) { 14 | t.Parallel() 15 | 16 | ds := tests.NewTxMapDatastore() 17 | 18 | pre(t, ds, "testdata/v1_JobLogger.pre") 19 | 20 | c1, _ := util.CidFromString("QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE") 21 | c2, _ := util.CidFromString("QmZTMaDfCMWqhUXYDnKup8ctCTyPxnriYW7G4JR8KXoX5M") 22 | cidOwners := map[cid.Cid][]ffs.APIID{ 23 | c1: {ffs.APIID("ID1"), ffs.APIID("ID2")}, 24 | c2: {ffs.APIID("ID3")}, 25 | } 26 | txn, _ := ds.NewTransaction(false) 27 | err := migrateJobLogger(txn, cidOwners) 28 | require.NoError(t, err) 29 | require.NoError(t, txn.Commit()) 30 | 31 | post(t, ds, "testdata/v1_JobLogger.post") 32 | } 33 | -------------------------------------------------------------------------------- /migration/migration1_pinstore_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ipfs/go-cid" 7 | "github.com/stretchr/testify/require" 8 | "github.com/textileio/powergate/v2/ffs" 9 | "github.com/textileio/powergate/v2/tests" 10 | "github.com/textileio/powergate/v2/util" 11 | ) 12 | 13 | func TestV1_Pinstore(t *testing.T) { 14 | t.Parallel() 15 | 16 | ds := tests.NewTxMapDatastore() 17 | 18 | pre(t, ds, "testdata/v1_Pinstore.pre") 19 | 20 | c1, _ := util.CidFromString("QmY7gN6AfKSoR7DNEjcUyXRYS85giD1YXN62cWVzS5zfus") 21 | c2, _ := util.CidFromString("QmX5J6NujFycQyoMvHXjTNmtvqDnn8TN6wAVQJ4Ap2GMnq") 22 | cidOwners := map[cid.Cid][]ffs.APIID{ 23 | c1: {ffs.APIID("ad2f3b0c-e356-43d4-a483-fba79479d7e4"), ffs.APIID("fb79f525-a3c4-47f0-94e5-e344c5b1dec5")}, 24 | c2: {ffs.APIID("2bef4790-a47a-4a48-90da-a89f93ab6310")}, 25 | } 26 | txn, _ := ds.NewTransaction(false) 27 | err := pinstoreFilling(txn, cidOwners) 28 | require.NoError(t, err) 29 | require.NoError(t, txn.Commit()) 30 | 31 | post(t, ds, "testdata/v1_Pinstore.post") 32 | } 33 | -------------------------------------------------------------------------------- /migration/migration1_starteddeals.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/ipfs/go-datastore" 7 | "github.com/ipfs/go-datastore/query" 8 | "github.com/textileio/powergate/v2/util" 9 | ) 10 | 11 | func migrateStartedDeals(ds datastoreReaderWriter) error { 12 | executingJobs, err := v0GetExecutingJobs(ds) 13 | if err != nil { 14 | return fmt.Errorf("getting executing jobs: %s", err) 15 | } 16 | q := query.Query{Prefix: "/ffs/scheduler/sjstore/starteddeals"} 17 | res, err := ds.Query(q) 18 | if err != nil { 19 | return fmt.Errorf("querying started deals in sjstore: %s", err) 20 | } 21 | defer func() { _ = res.Close() }() 22 | 23 | for r := range res.Next() { 24 | if r.Error != nil { 25 | return fmt.Errorf("iterating result: %s", r.Error) 26 | } 27 | 28 | originalKey := datastore.NewKey(r.Key) 29 | cidStr := originalKey.Namespaces()[4] // /ffs/scheduler/sjstore/starteddeals/ 30 | cid, err := util.CidFromString(cidStr) 31 | if err != nil { 32 | return fmt.Errorf("discovered invalid cid: %s", err) 33 | } 34 | 35 | owner, ok := executingJobs[cid] 36 | if ok { 37 | // Step 1/2: 38 | // Add corresponding iid in started deals key namespace. 39 | newKey := datastore.NewKey("/ffs/scheduler/sjstore/starteddeals_v2").ChildString(owner.String()).ChildString(cidStr) 40 | if err := ds.Put(newKey, r.Value); err != nil { 41 | return fmt.Errorf("copying started deal to new key: %s", err) 42 | } 43 | } 44 | 45 | // Step 2/2: 46 | // Delete old datastore key. 47 | if err := ds.Delete(originalKey); err != nil { 48 | return fmt.Errorf("deleting old key: %s", err) 49 | } 50 | } 51 | 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /migration/migration1_starteddeals_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | "github.com/textileio/powergate/v2/ffs" 8 | "github.com/textileio/powergate/v2/tests" 9 | "github.com/textileio/powergate/v2/util" 10 | ) 11 | 12 | func TestV1_StartedDeals(t *testing.T) { 13 | t.Parallel() 14 | 15 | ds := tests.NewTxMapDatastore() 16 | 17 | pre(t, ds, "testdata/v1_StartedDeals.pre") 18 | 19 | txn, _ := ds.NewTransaction(false) 20 | err := migrateStartedDeals(txn) 21 | require.NoError(t, err) 22 | require.NoError(t, txn.Commit()) 23 | 24 | post(t, ds, "testdata/v1_StartedDeals.post") 25 | } 26 | 27 | func TestV0_ExecutingJobs(t *testing.T) { 28 | t.Parallel() 29 | 30 | ds := tests.NewTxMapDatastore() 31 | 32 | pre(t, ds, "testdata/v1_StartedDeals.pre") 33 | 34 | txn, _ := ds.NewTransaction(false) 35 | execJobsOwners, err := v0GetExecutingJobs(txn) 36 | require.NoError(t, err) 37 | 38 | require.Len(t, execJobsOwners, 2) 39 | 40 | c1, _ := util.CidFromString("QmbcKgdxWfZzePsrc6rWq2yk12GE1MnW8JJiubHAJovKb5") 41 | iid1 := ffs.APIID("a9aeaecc-4c94-4bb6-bd14-13927d8cede0") 42 | require.Equal(t, iid1, execJobsOwners[c1]) 43 | 44 | c2, _ := util.CidFromString("QmaPndBy99qcz7rCAooak8SY34Rk9oXWpEBp4dUyhbmq1q") 45 | iid2 := ffs.APIID("ad2f3b0c-e356-43d4-a483-fba79479d7e4") 46 | require.Equal(t, iid2, execJobsOwners[c2]) 47 | } 48 | -------------------------------------------------------------------------------- /migration/migration1_storageinfo_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ipfs/go-cid" 7 | "github.com/stretchr/testify/require" 8 | "github.com/textileio/powergate/v2/ffs" 9 | "github.com/textileio/powergate/v2/tests" 10 | "github.com/textileio/powergate/v2/util" 11 | ) 12 | 13 | func TestV1_StorageInfo(t *testing.T) { 14 | t.Parallel() 15 | 16 | ds := tests.NewTxMapDatastore() 17 | 18 | pre(t, ds, "testdata/v1_StorageInfo.pre") 19 | 20 | c1, _ := util.CidFromString("QmbtfAvVRVgEa9RH6vYpKg1HWbBQjxiZ6vNG1AAvt3vyfR") 21 | c2, _ := util.CidFromString("QmZTMaDfCMWqhUXYDnKup8ctCTyPxnriYW7G4JR8KXoX5M") 22 | cidOwners := map[cid.Cid][]ffs.APIID{ 23 | c1: {ffs.APIID("ID1"), ffs.APIID("ID2")}, 24 | c2: {ffs.APIID("ID2"), ffs.APIID("ID3")}, 25 | } 26 | txn, _ := ds.NewTransaction(false) 27 | err := migrateStorageInfo(txn, cidOwners) 28 | require.NoError(t, err) 29 | require.NoError(t, txn.Commit()) 30 | 31 | post(t, ds, "testdata/v1_StorageInfo.post") 32 | } 33 | -------------------------------------------------------------------------------- /migration/migration2_storageinfo_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | "github.com/textileio/powergate/v2/tests" 8 | ) 9 | 10 | func TestV2_StorageInfo(t *testing.T) { 11 | t.Parallel() 12 | 13 | ds := tests.NewTxMapDatastore() 14 | 15 | pre(t, ds, "testdata/v2_StorageInfo.pre") 16 | 17 | propDealID, err := v2GenProposalCidToDealID(ds) 18 | require.NoError(t, err) 19 | 20 | txn, _ := ds.NewTransaction(false) 21 | err = v2MigrationDealIDFilling(txn, propDealID) 22 | require.NoError(t, err) 23 | require.NoError(t, txn.Commit()) 24 | 25 | post(t, ds, "testdata/v2_StorageInfo.post") 26 | } 27 | -------------------------------------------------------------------------------- /migration/migration3_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | "github.com/textileio/powergate/v2/tests" 8 | ) 9 | 10 | func TestV3(t *testing.T) { 11 | t.Parallel() 12 | 13 | ds := tests.NewTxMapDatastore() 14 | 15 | pre(t, ds, "testdata/v3_StorageJobs.pre") 16 | txn, _ := ds.NewTransaction(false) 17 | 18 | err := V3StorageJobsIndexMigration.Run(txn) 19 | require.NoError(t, err) 20 | require.NoError(t, txn.Commit()) 21 | 22 | post(t, ds, "testdata/v3_StorageJobs.post") 23 | } 24 | -------------------------------------------------------------------------------- /migration/migration4_test.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | "github.com/textileio/powergate/v2/tests" 8 | ) 9 | 10 | func TestV4(t *testing.T) { 11 | t.Parallel() 12 | 13 | ds := tests.NewTxMapDatastore() 14 | 15 | pre(t, ds, "testdata/v4_Records.pre") 16 | 17 | err := V4RecordsMigration.Run(ds) 18 | require.NoError(t, err) 19 | 20 | post(t, ds, "testdata/v4_Records.post") 21 | } 22 | -------------------------------------------------------------------------------- /migration/migration5.go: -------------------------------------------------------------------------------- 1 | package migration 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/ipfs/go-datastore" 7 | "github.com/ipfs/go-datastore/query" 8 | ) 9 | 10 | // V5DeleteOldMinerIndex contains the logic to upgrade a datastore from 11 | // version 4 to version 5. 12 | var V5DeleteOldMinerIndex = Migration{ 13 | UseTxn: false, 14 | Run: func(ds datastoreReaderWriter) error { 15 | q := query.Query{Prefix: "/index/miner/chainstore"} 16 | res, err := ds.Query(q) 17 | if err != nil { 18 | return fmt.Errorf("querying records: %s", err) 19 | } 20 | defer func() { _ = res.Close() }() 21 | 22 | var count int 23 | for v := range res.Next() { 24 | if err := ds.Delete(datastore.NewKey(v.Key)); err != nil { 25 | return fmt.Errorf("deleting miner chainstore key: %s", err) 26 | } 27 | count++ 28 | } 29 | log.Infof("deleted %d chainstore keys", count) 30 | 31 | return nil 32 | }, 33 | } 34 | -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv0/000000.vlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv0/000000.vlog -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv0/000002.sst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv0/000002.sst -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv0/KEYREGISTRY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv0/KEYREGISTRY -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv0/MANIFEST: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv0/MANIFEST -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv1/000000.vlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv1/000000.vlog -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv1/000002.sst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv1/000002.sst -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv1/KEYREGISTRY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv1/KEYREGISTRY -------------------------------------------------------------------------------- /migration/testdata/badgerdumpv1/MANIFEST: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textileio/powergate/fd1d09312a136d31f28bc62ddfad177d00e5d5e9/migration/testdata/badgerdumpv1/MANIFEST -------------------------------------------------------------------------------- /migration/testdata/v1_JobLogger.post: -------------------------------------------------------------------------------- 1 | /ffs/joblogger_v2/ID1/QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE/1602952162298722885,{"Cid":{"/":"QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE"},"RetrievalID":"","Timestamp":1602952162298722885,"Jid":"ad6da2a0-5465-4275-a330-2537062765c8","Msg":"Deal 763168 with miner f022142 is active on-chain"} 2 | /ffs/joblogger_v2/ID2/QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE/1602952162298722885,{"Cid":{"/":"QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE"},"RetrievalID":"","Timestamp":1602952162298722885,"Jid":"ad6da2a0-5465-4275-a330-2537062765c8","Msg":"Deal 763168 with miner f022142 is active on-chain"} 3 | /ffs/joblogger_v2/ID3/QmZTMaDfCMWqhUXYDnKup8ctCTyPxnriYW7G4JR8KXoX5M/1603115031102317344,{"Cid":{"/":"QmZTMaDfCMWqhUXYDnKup8ctCTyPxnriYW7G4JR8KXoX5M"},"RetrievalID":"","Timestamp":1603115031102317344,"Jid":"35a6f8fc-cad5-41f4-a410-e5c3d882f0e0","Msg":"Proposing deal to miner f022142 with 200000000 attoFIL per epoch..."} 4 | -------------------------------------------------------------------------------- /migration/testdata/v1_JobLogger.pre: -------------------------------------------------------------------------------- 1 | /ffs/joblogger/QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE/1602952162298722885,{"Cid":{"/":"QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE"},"RetrievalID":"","Timestamp":1602952162298722885,"Jid":"ad6da2a0-5465-4275-a330-2537062765c8","Msg":"Deal 763168 with miner f022142 is active on-chain"} 2 | /ffs/joblogger/QmZTMaDfCMWqhUXYDnKup8ctCTyPxnriYW7G4JR8KXoX5M/1603115031102317344,{"Cid":{"/":"QmZTMaDfCMWqhUXYDnKup8ctCTyPxnriYW7G4JR8KXoX5M"},"RetrievalID":"","Timestamp":1603115031102317344,"Jid":"35a6f8fc-cad5-41f4-a410-e5c3d882f0e0","Msg":"Proposing deal to miner f022142 with 200000000 attoFIL per epoch..."} 3 | -------------------------------------------------------------------------------- /migration/testdata/v4_Records.pre: -------------------------------------------------------------------------------- 1 | /deals/retrieval/a5d4782fcc16d55985f2d581b2800b0c,{"Addr":"Addr1","DealInfo":{"RootCid":{"/":"QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D"},"Size":3000,"MinPrice":329,"PaymentInterval":0,"PaymentIntervalIncrease":0,"Miner":"f01002","MinerPeerID":""},"Time":1234,"DataTransferStart":1003,"DataTransferEnd":1004,"ErrMsg":"err msg 2","UpdatedAt":502} 2 | /deals/storage-final/bafyreihz5xu6gu6dfkhapkitz6hi47ahx25ym42oujgpguz65yewu4ka5u,{"RootCid":{"/":"QmPewMLNZEgnLxaenjo9Q5qwQwW3zHZ7Ac973UmeJ6VWHE"},"Addr":"f3qgbldlglseh6xvjmbwze2hyuwpwtoo2ap2vogfszo24td32jywnxowgyuzg4ts5kiln4fmewob77mmmcdgga","DealInfo":{"ProposalCid":{"/":"bafyreihz5xu6gu6dfkhapkitz6hi47ahx25ym42oujgpguz65yewu4ka5u"},"StateID":7,"StateName":"StorageDealActive","Miner":"f022142","PieceCID":{"/":"baga6ea4seaqjcl6lxe3d2u6or4kxeim4xoacuqj5yevyphcy7y7qcpai3mplepi"},"Size":66584576,"PricePerEpoch":3125000000,"StartEpoch":160288,"Duration":519892,"DealID":763168,"ActivationEpoch":154843,"Message":""},"Time":1602952149,"Pending":false} 3 | /deals/storage-pending/bafyreibayywhgjkahhqyrk7qplilzkaw3pzr4e232pqgpi2ngc32zl53ce,{"RootCid":{"/":"bafybeia6fqgswzj7cf3pfqgzdnf3lwmroxsqgkl7mhvyfdom7gosqyqrla"},"Addr":"f3rab4mhsr7f2gdg6ozgj44mtny6bhcy3rvlftc5xyki6t4hvhdkaji3ahfaid6fh2o3wff4yfrzag4lge2r2q","DealInfo":{"ProposalCid":{"/":"bafyreibayywhgjkahhqyrk7qplilzkaw3pzr4e232pqgpi2ngc32zl53ce"},"StateID":0,"StateName":"","Miner":"f089558","PieceCID":null,"Size":0,"PricePerEpoch":4000000000,"StartEpoch":0,"Duration":518400,"DealID":0,"ActivationEpoch":0,"Message":""},"Time":1607842400,"Pending":true} 4 | -------------------------------------------------------------------------------- /reputation/internal/source/source.go: -------------------------------------------------------------------------------- 1 | package source 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | ma "github.com/multiformats/go-multiaddr" 8 | ) 9 | 10 | // Source is an external source of reputation information. 11 | type Source struct { 12 | ID string 13 | Weight float64 14 | Scores map[string]int 15 | Maddr ma.Multiaddr 16 | LastFetched *time.Time 17 | } 18 | 19 | // Refresh pulls fresh information from source. 20 | func (s *Source) Refresh(ctx context.Context) error { 21 | // ToDo: pull from Maddr fresh reputation information 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /scripts/gen-js-protos.sh: -------------------------------------------------------------------------------- 1 | LIB_VERSION=$1 2 | PROTOS_PATH=$2 3 | OUT_PATH=$3 4 | 5 | LIB_PREFIX="@textile" 6 | LIB_POSTFIX="grpc-powergate-client" 7 | LIB_NAME="$LIB_PREFIX/$LIB_POSTFIX" 8 | LIB_SRC_DIR="dist" 9 | 10 | PROTOC_GEN_TS_PATH="$OUT_PATH/node_modules/.bin/protoc-gen-ts" 11 | PTOTOC_GEN_OUT_DIR="$OUT_PATH/$LIB_SRC_DIR" 12 | 13 | if [ -d "$OUT_PATH" ] 14 | then 15 | rm -rf $OUT_PATH 16 | fi 17 | 18 | mkdir -p $PTOTOC_GEN_OUT_DIR 19 | 20 | printf '{"name":"%s", "version":"%s", "files":["%s"]}' $LIB_NAME $LIB_VERSION $LIB_SRC_DIR > $OUT_PATH/package.json 21 | 22 | (cd $OUT_PATH && npm install --save-dev ts-protoc-gen) 23 | (cd $OUT_PATH && npm install google-protobuf@^3.12.2 @improbable-eng/grpc-web @types/google-protobuf@^3.7.2) 24 | 25 | ABS_OUT_PATH="$( cd $OUT_PATH >/dev/null 2>&1 ; pwd -P )" 26 | ABS_PROTOS_PATH="$( cd $PROTOS_PATH >/dev/null 2>&1 ; pwd -P )" 27 | 28 | PROTOS=$(find $ABS_PROTOS_PATH -path $ABS_OUT_PATH -prune -o -iname "*.proto" -print) 29 | 30 | protoc \ 31 | --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \ 32 | --js_out="import_style=commonjs,binary:${PTOTOC_GEN_OUT_DIR}" \ 33 | --ts_out="service=grpc-web:${PTOTOC_GEN_OUT_DIR}" \ 34 | -I $ABS_PROTOS_PATH \ 35 | ${PROTOS} 36 | 37 | -------------------------------------------------------------------------------- /scripts/gen-py-protos.sh: -------------------------------------------------------------------------------- 1 | LIB_VERSION=$1 2 | PROTOS_PATH=$2 3 | OUT_PATH=$3 4 | SRC_PATH=$OUT_PATH/src 5 | 6 | if [ -d "$OUT_PATH" ] 7 | then 8 | rm -rf $OUT_PATH 9 | fi 10 | 11 | mkdir -p $SRC_PATH 12 | 13 | cat << EOF > $OUT_PATH/setup.py 14 | import setuptools 15 | 16 | setuptools.setup( 17 | name="grpc_powergate_client", 18 | version="${LIB_VERSION}", 19 | author="Textile", 20 | author_email="contact@textile.io", 21 | url="https://github.com/textileio/powergate", 22 | packages=setuptools.find_packages(where="src"), 23 | package_dir={'': 'src'}, 24 | install_requires=[ 25 | 'protobuf', 26 | 'grpcio', 27 | ], 28 | ) 29 | EOF 30 | 31 | ABS_OUT_PATH="$( cd $OUT_PATH >/dev/null 2>&1 ; pwd -P )" 32 | ABS_PROTOS_PATH="$( cd $PROTOS_PATH >/dev/null 2>&1 ; pwd -P )" 33 | 34 | PROTOS=$(find $ABS_PROTOS_PATH -path $ABS_OUT_PATH -prune -o -iname "*.proto" -print) 35 | 36 | python3 -m pip install grpcio-tools 37 | python3 -m grpc_tools.protoc -I$ABS_PROTOS_PATH --python_out=$SRC_PATH --grpc_python_out=$SRC_PATH $PROTOS 38 | 39 | find $SRC_PATH -type d -exec touch {}/__init__.py \; 40 | 41 | python3 -m pip install --user --upgrade setuptools wheel 42 | cd $OUT_PATH && python3 setup.py sdist bdist_wheel 43 | 44 | -------------------------------------------------------------------------------- /signaler/signaler.go: -------------------------------------------------------------------------------- 1 | package signaler 2 | 3 | import ( 4 | "sync" 5 | 6 | logging "github.com/ipfs/go-log/v2" 7 | ) 8 | 9 | var ( 10 | log = logging.Logger("broadcaster") 11 | ) 12 | 13 | // Signaler allows subscribing to a singnaling hub. 14 | type Signaler struct { 15 | lock sync.Mutex 16 | listeners []chan struct{} 17 | } 18 | 19 | // New returns a new Signaler. 20 | func New() *Signaler { 21 | return &Signaler{} 22 | } 23 | 24 | // Listen returns a new channel signaler. 25 | func (s *Signaler) Listen() <-chan struct{} { 26 | c := make(chan struct{}, 1) 27 | s.lock.Lock() 28 | s.listeners = append(s.listeners, c) 29 | s.lock.Unlock() 30 | return c 31 | } 32 | 33 | // Unregister unregisters a channel signaler from the hub. 34 | func (s *Signaler) Unregister(c chan struct{}) { 35 | s.lock.Lock() 36 | defer s.lock.Unlock() 37 | for i := range s.listeners { 38 | if s.listeners[i] == c { 39 | if len(s.listeners) == 1 { 40 | s.listeners = nil 41 | return 42 | } 43 | s.listeners[i] = s.listeners[len(s.listeners)-1] 44 | s.listeners = s.listeners[:len(s.listeners)-1] 45 | close(s.listeners[i]) 46 | return 47 | } 48 | } 49 | } 50 | 51 | // Signal triggers a new notification to all listeners. 52 | func (s *Signaler) Signal() { 53 | s.lock.Lock() 54 | defer s.lock.Unlock() 55 | for _, c := range s.listeners { 56 | select { 57 | case c <- struct{}{}: 58 | default: 59 | log.Warn("dropping signal on blocked listener") 60 | } 61 | } 62 | } 63 | 64 | // Close closes the Signaler. Any channel that wasn't explicitly unregistered, 65 | // is closed. 66 | func (s *Signaler) Close() { 67 | s.lock.Lock() 68 | defer s.lock.Unlock() 69 | for _, c := range s.listeners { 70 | close(c) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/auth.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "path/filepath" 8 | "testing" 9 | 10 | ma "github.com/multiformats/go-multiaddr" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | const ( 15 | lotusHost = "127.0.0.1" 16 | lotusPort = 1234 17 | ) 18 | 19 | // GetLotusToken returns the lotus token from a Lotus repo path. 20 | func GetLotusToken(lotusFolderPath string) (string, error) { 21 | tokenFullPath := filepath.Join(lotusFolderPath, "token") 22 | if _, err := os.Stat(tokenFullPath); err != nil { 23 | if os.IsNotExist(err) { 24 | return createAdminToken() 25 | } 26 | return "", err 27 | } 28 | cmd := exec.Command("cat", tokenFullPath) 29 | out, err := cmd.Output() 30 | if err != nil { 31 | return "", err 32 | } 33 | return string(out), nil 34 | } 35 | 36 | func createAdminToken() (string, error) { 37 | cmd := exec.Command("lotus", "auth", "create-token", "--perm", "admin") 38 | out, err := cmd.Output() 39 | if err != nil { 40 | return "", err 41 | } 42 | return string(out), err 43 | } 44 | 45 | // ClientConfigMA returns the prepared multiaddress and Lotus token, 46 | // to connect to a Lotus node. 47 | func ClientConfigMA(t *testing.T) (ma.Multiaddr, string) { 48 | addr := fmt.Sprintf("/ip4/%v/tcp/%v", lotusHost, lotusPort) 49 | multi, err := ma.NewMultiaddr(addr) 50 | require.NoError(t, err) 51 | authToken, ok := os.LookupEnv("TEXTILE_LOTUS_TOKEN") 52 | if !ok { 53 | home, err := os.UserHomeDir() 54 | require.NoError(t, err) 55 | path := filepath.Join(home, ".lotus") 56 | authToken, err = GetLotusToken(path) 57 | require.NoError(t, err) 58 | } 59 | 60 | return multi, authToken 61 | } 62 | -------------------------------------------------------------------------------- /tests/docker.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/ory/dockertest/v3" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | // LaunchIPFSDocker runs a fresh go-ipfs docker image and returns the resource for 11 | // container metadata. 12 | func LaunchIPFSDocker(t require.TestingT) (*dockertest.Resource, func()) { 13 | pool, err := dockertest.NewPool("") 14 | require.NoError(t, err) 15 | 16 | ipfsDocker, err := pool.Run("ipfs/go-ipfs", "v0.7.0", []string{"IPFS_PROFILE=test"}) 17 | require.NoError(t, err) 18 | 19 | err = ipfsDocker.Expire(180) 20 | require.NoError(t, err) 21 | 22 | time.Sleep(time.Second * 3) 23 | return ipfsDocker, func() { 24 | err = pool.Purge(ipfsDocker) 25 | require.NoError(t, err) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/flaky.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "runtime" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | // FlakyT provides retry mechanisms to test. 12 | type FlakyT struct { 13 | t *testing.T 14 | failed bool 15 | cls []func() 16 | } 17 | 18 | // NewFlakyT creates a new FlakyT. 19 | func NewFlakyT(t *testing.T) *FlakyT { 20 | return &FlakyT{ 21 | t: t, 22 | } 23 | } 24 | 25 | var _ require.TestingT = (*FlakyT)(nil) 26 | 27 | // Errorf registers an error message. 28 | func (ft *FlakyT) Errorf(format string, args ...interface{}) { 29 | ft.t.Logf(format, args...) 30 | } 31 | 32 | // FailNow indicates to fail the test. 33 | func (ft *FlakyT) FailNow() { 34 | ft.failed = true 35 | runtime.Goexit() 36 | } 37 | 38 | // Cleanup registers a cleanup function. 39 | func (ft *FlakyT) Cleanup(cls func()) { 40 | ft.cls = append([]func(){cls}, ft.cls...) 41 | } 42 | 43 | var numRetries = 5 44 | 45 | // RunFlaky runs a flaky test with retries. 46 | func RunFlaky(t *testing.T, f func(ft *FlakyT)) { 47 | for i := 0; i < numRetries; i++ { 48 | var wg sync.WaitGroup 49 | wg.Add(1) 50 | ft := NewFlakyT(t) 51 | go func() { 52 | defer wg.Done() 53 | f(ft) 54 | }() 55 | wg.Wait() 56 | for _, f := range ft.cls { 57 | f() 58 | } 59 | if !ft.failed { 60 | return 61 | } 62 | ft.t.Logf("test %s attempt %d/%d failed, retrying...", t.Name(), i+1, numRetries) 63 | } 64 | t.Fatalf("test failed after %d retries", numRetries) 65 | } 66 | -------------------------------------------------------------------------------- /tests/mocks/mocks.go: -------------------------------------------------------------------------------- 1 | package mocks 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/libp2p/go-libp2p-core/peer" 7 | "github.com/multiformats/go-multiaddr" 8 | minerModule "github.com/textileio/powergate/v2/index/miner/lotusidx" 9 | "github.com/textileio/powergate/v2/iplocation" 10 | ) 11 | 12 | var _ minerModule.P2PHost = (*P2pHostMock)(nil) 13 | 14 | // P2pHostMock provides a mock P2PHost. 15 | type P2pHostMock struct{} 16 | 17 | // Addrs implements Addrs. 18 | func (hm *P2pHostMock) Addrs(id peer.ID) []multiaddr.Multiaddr { 19 | return nil 20 | } 21 | 22 | // GetAgentVersion implements GetAgentVersion. 23 | func (hm *P2pHostMock) GetAgentVersion(id peer.ID) string { 24 | return "fakeAgentVersion" 25 | } 26 | 27 | // Ping implements Ping. 28 | func (hm *P2pHostMock) Ping(ctx context.Context, pid peer.ID) bool { 29 | return true 30 | } 31 | 32 | var _ iplocation.LocationResolver = (*LrMock)(nil) 33 | 34 | // LrMock provides a mock LocationResolver. 35 | type LrMock struct{} 36 | 37 | // Resolve implements Resolve. 38 | func (lr *LrMock) Resolve(mas []multiaddr.Multiaddr) (iplocation.Location, error) { 39 | return iplocation.Location{ 40 | Country: "USA", 41 | Latitude: 0.1, 42 | Longitude: 0.1, 43 | }, nil 44 | } 45 | -------------------------------------------------------------------------------- /util/util_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ipfs/go-cid" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | const cidString = "QmSqL792vF4fGjStbYHRgazsEahAQKZmx68jrnvFi9hXMp" 11 | 12 | func TestCidToString(t *testing.T) { 13 | c, err := cid.Decode(cidString) 14 | require.NoError(t, err) 15 | s := CidToString(c) 16 | require.Equal(t, cidString, s) 17 | c = cid.Undef 18 | s = CidToString(c) 19 | require.Equal(t, CidUndef, s) 20 | } 21 | 22 | func TestCidFromString(t *testing.T) { 23 | orig, err := cid.Decode(cidString) 24 | require.NoError(t, err) 25 | c, err := CidFromString(cidString) 26 | require.NoError(t, err) 27 | require.Equal(t, orig, c) 28 | c, err = CidFromString(CidUndef) 29 | require.NoError(t, err) 30 | require.Equal(t, cid.Undef, c) 31 | c, err = CidFromString(DefaultCidUndef) 32 | require.NoError(t, err) 33 | require.Equal(t, cid.Undef, c) 34 | _, err = CidFromString("xyz") 35 | require.Error(t, err) 36 | } 37 | -------------------------------------------------------------------------------- /wallet/lotuswallet/metrics.go: -------------------------------------------------------------------------------- 1 | package lotuswallet 2 | 3 | import ( 4 | "go.opentelemetry.io/otel/attribute" 5 | "go.opentelemetry.io/otel/metric" 6 | "go.opentelemetry.io/otel/metric/global" 7 | ) 8 | 9 | var ( 10 | tagAutofund = attribute.Key("autofunding") 11 | ) 12 | 13 | func (m *Module) initMetrics() { 14 | meter := global.Meter("powergate") 15 | 16 | m.metricCreated = metric.Must(meter).NewInt64Counter("powergate.wallet.created") 17 | m.metricTransfer = metric.Must(meter).NewInt64ValueRecorder("powergate.wallet.transfer", metric.WithDescription("Transfers in nanoFIL")) 18 | } 19 | -------------------------------------------------------------------------------- /wallet/type.go: -------------------------------------------------------------------------------- 1 | package wallet 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "math/big" 7 | 8 | "github.com/ipfs/go-cid" 9 | ) 10 | 11 | var ( 12 | // ErrNoVerifiedClient indicates that the provided 13 | // wallet-address isn't a verified client. 14 | ErrNoVerifiedClient = errors.New("the wallet-address isn't a verified client") 15 | ) 16 | 17 | // VerifiedClientInfo contains information for a wallet address 18 | // that is a verified-client. 19 | type VerifiedClientInfo struct { 20 | RemainingDatacapBytes *big.Int 21 | } 22 | 23 | // Module provides wallet management access to a Filecoin client. 24 | type Module interface { 25 | // NewAddress returns a new wallet address of the specified type. 26 | NewAddress(ctx context.Context, typ string) (string, error) 27 | // List lists all known wallet addresses. 28 | List(ctx context.Context) ([]string, error) 29 | // GetVerifiedClientInfo returns details about a wallet-address that's 30 | // a verified client. If the wallet address isn't a verified client, 31 | // it will return ErrNoVerifiedClient. 32 | GetVerifiedClientInfo(ctx context.Context, addr string) (VerifiedClientInfo, error) 33 | // Balance returns the balance of a wallet-address. 34 | Balance(ctx context.Context, addr string) (*big.Int, error) 35 | // SendFil sends `amount` attoFIL from `from` to `to` and returns the 36 | // message Cid. 37 | SendFil(ctx context.Context, from string, to string, amount *big.Int) (cid.Cid, error) 38 | // FundFromFaucet funds addr from the master address (if configured). 39 | FundFromFaucet(ctx context.Context, addr string) error 40 | } 41 | --------------------------------------------------------------------------------