From a13158cf06d1d14f5a48f80fe2ee4d7fd8bb86f5 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Fri, 2 Aug 2024 14:36:55 -0500 Subject: [PATCH 01/12] Add datalayer command --- cmd/datalayer/datalayer.go | 17 +++++++++++++++++ main.go | 1 + 2 files changed, 18 insertions(+) create mode 100644 cmd/datalayer/datalayer.go diff --git a/cmd/datalayer/datalayer.go b/cmd/datalayer/datalayer.go new file mode 100644 index 0000000..4a86bb7 --- /dev/null +++ b/cmd/datalayer/datalayer.go @@ -0,0 +1,17 @@ +package datalayer + +import ( + "github.com/spf13/cobra" + + "github.com/chia-network/chia-tools/cmd" +) + +// datalayerCmd represents the config command +var datalayerCmd = &cobra.Command{ + Use: "data", + Short: "Utilities for working with chia data layer", +} + +func init() { + cmd.RootCmd.AddCommand(datalayerCmd) +} diff --git a/main.go b/main.go index e6c561d..0090492 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "github.com/chia-network/chia-tools/cmd" _ "github.com/chia-network/chia-tools/cmd/certs" _ "github.com/chia-network/chia-tools/cmd/config" + _ "github.com/chia-network/chia-tools/cmd/datalayer" ) func main() { From 49fa2ed508b8364a38529ec8f4796f67e953b986 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Fri, 2 Aug 2024 14:52:36 -0500 Subject: [PATCH 02/12] Add unsub-all command --- cmd/datalayer/unsuball.go | 53 +++++++++++++++++++++++++++++++++++++++ go.mod | 6 ++++- go.sum | 14 +++++++++-- 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 cmd/datalayer/unsuball.go diff --git a/cmd/datalayer/unsuball.go b/cmd/datalayer/unsuball.go new file mode 100644 index 0000000..ed6ee6f --- /dev/null +++ b/cmd/datalayer/unsuball.go @@ -0,0 +1,53 @@ +package datalayer + +import ( + "slices" + + "github.com/chia-network/go-chia-libs/pkg/rpc" + "github.com/chia-network/go-modules/pkg/slogs" + "github.com/spf13/cobra" +) + +// unsubAllCmd Unsubscribes from all non-owned datalayer stores +var unsubAllCmd = &cobra.Command{ + Use: "unsub-all", + Short: "Unsubscribes from all datalayer stores except for owned stores", + Run: func(cmd *cobra.Command, args []string) { + client, err := rpc.NewClient(rpc.ConnectionModeHTTP, rpc.WithAutoConfig()) + if err != nil { + slogs.Logr.Fatal("error creating chia RPC client", "error", err) + } + + ownedStores, _, err := client.DataLayerService.GetOwnedStores(&rpc.DatalayerGetOwnedStoresOptions{}) + if err != nil { + slogs.Logr.Fatal("error getting list of owned data stores", "error", err) + } + + subscriptions, _, err := client.DataLayerService.GetSubscriptions(&rpc.DatalayerGetSubscriptionsOptions{}) + if err != nil { + slogs.Logr.Fatal("error getting list of datalayer subscriptions", "error", err) + } + + for _, subscription := range subscriptions.StoreIDs { + if slices.Contains(ownedStores.StoreIDs, subscription) { + slogs.Logr.Info("Owned store found, skipping", "store", subscription) + continue + } + slogs.Logr.Info("Unsubscribing from subscription", "store", subscription) + resp, _, err := client.DataLayerService.Unsubscribe(&rpc.DatalayerUnsubscribeOptions{ + ID: subscription, + RetainData: true, + }) + if err != nil { + slogs.Logr.Fatal("error unsubscribing from store", "store", subscription, "error", err) + } + if !resp.Success { + slogs.Logr.Fatal("unknown error when unsubscribing from store", "store", subscription) + } + } + }, +} + +func init() { + datalayerCmd.AddCommand(unsubAllCmd) +} diff --git a/go.mod b/go.mod index 53e2cd1..dc22468 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/chia-network/chia-tools go 1.22.4 require ( - github.com/chia-network/go-chia-libs v0.8.5 + github.com/chia-network/go-chia-libs v0.8.6-0.20240802191521-ac5fb4a152f1 github.com/chia-network/go-modules v0.0.5 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 @@ -12,10 +12,14 @@ require ( require ( github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index 0f5a762..107a6ce 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/chia-network/go-chia-libs v0.8.5 h1:IZKpQQH6VcbafDA/DlDlFkjerr3KzDn5vWD4C5nmzHA= -github.com/chia-network/go-chia-libs v0.8.5/go.mod h1:npTqaFSjTdMxE7hc0LOmWJmWGqcs+IERarK5fDxXk/I= +github.com/chia-network/go-chia-libs v0.8.6-0.20240802191521-ac5fb4a152f1 h1:zmeRuQcnMEjBKEbQcOgEr3JyAGxZubOrXy8gKOek60w= +github.com/chia-network/go-chia-libs v0.8.6-0.20240802191521-ac5fb4a152f1/go.mod h1:npTqaFSjTdMxE7hc0LOmWJmWGqcs+IERarK5fDxXk/I= github.com/chia-network/go-modules v0.0.5 h1:5luTVlP6RgBXodnFcWFBk2sLdJn+6vQ4wObim683C7c= github.com/chia-network/go-modules v0.0.5/go.mod h1:5AiYBxQSvf2aFSOizTqFXXSeb9AucZWrWmRCVwUMO3A= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -11,8 +11,15 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -25,6 +32,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -73,6 +82,7 @@ golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From fa3dabd659c321b103268b53bf617839dbf9cbd6 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Fri, 2 Aug 2024 15:21:45 -0500 Subject: [PATCH 03/12] Add delete-mirrors command --- cmd/datalayer/deletemirrors.go | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 cmd/datalayer/deletemirrors.go diff --git a/cmd/datalayer/deletemirrors.go b/cmd/datalayer/deletemirrors.go new file mode 100644 index 0000000..7b9abe4 --- /dev/null +++ b/cmd/datalayer/deletemirrors.go @@ -0,0 +1,74 @@ +package datalayer + +import ( + "github.com/chia-network/go-chia-libs/pkg/rpc" + "github.com/chia-network/go-chia-libs/pkg/types" + "github.com/chia-network/go-modules/pkg/slogs" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// deleteMirrorsCmd Deletes all owned mirrors for all datalayer subscriptions +var deleteMirrorsCmd = &cobra.Command{ + Use: "delete-mirrors", + Short: "Deletes all owned mirrors for all datalayer subscriptions", + Run: func(cmd *cobra.Command, args []string) { + client, err := rpc.NewClient(rpc.ConnectionModeHTTP, rpc.WithAutoConfig()) + if err != nil { + slogs.Logr.Fatal("error creating chia RPC client", "error", err) + } + + // Figure out what fee we are using + feeXCH := viper.GetFloat64("delete-mirror-fee") + feeMojos := uint64(feeXCH * 1000000000000) + slogs.Logr.Debug("fee for all transactions", "xch", feeXCH, "mojos", feeMojos) + + subscriptions, _, err := client.DataLayerService.GetSubscriptions(&rpc.DatalayerGetSubscriptionsOptions{}) + if err != nil { + slogs.Logr.Fatal("error getting list of datalayer subscriptions", "error", err) + } + + for _, subscription := range subscriptions.StoreIDs { + slogs.Logr.Info("checking subscription", "store", subscription) + + mirrors, _, err := client.DataLayerService.GetMirrors(&rpc.DatalayerGetMirrorsOptions{ + ID: subscription, + }) + if err != nil { + slogs.Logr.Fatal("error fetching mirrors for subscription", "store", subscription, "error", err) + } + var ownedMirrors []types.Bytes32 + + for _, mirror := range mirrors.Mirrors { + if mirror.Ours { + ownedMirrors = append(ownedMirrors, mirror.CoinID) + } + } + + if len(ownedMirrors) == 0 { + slogs.Logr.Info("no owned mirrors for this datastore", "store", subscription) + continue + } + + for _, coinID := range ownedMirrors { + resp, _, err := client.DataLayerService.DeleteMirror(&rpc.DatalayerDeleteMirrorOptions{ + CoinID: coinID.String(), + Fee: feeMojos, + }) + if err != nil { + slogs.Logr.Fatal("error deleting mirror for store", "store", subscription, "mirror", coinID, "error", err) + } + if !resp.Success { + slogs.Logr.Fatal("unknown error when deleting mirror for store", "store", subscription, "mirror", coinID) + } + } + } + }, +} + +func init() { + deleteMirrorsCmd.PersistentFlags().Float64P("fee", "m", 0, "Fee to use when deleting the mirrors. The fee is used per mirror. Units are XCH") + cobra.CheckErr(viper.BindPFlag("delete-mirror-fee", deleteMirrorsCmd.PersistentFlags().Lookup("fee"))) + + datalayerCmd.AddCommand(deleteMirrorsCmd) +} From f0878a7221ea821acc107d98c4b4a130c111d0f7 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Mon, 5 Aug 2024 11:59:13 -0500 Subject: [PATCH 04/12] Add fix mirrors command --- cmd/datalayer/fixmirrors.go | 125 ++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 cmd/datalayer/fixmirrors.go diff --git a/cmd/datalayer/fixmirrors.go b/cmd/datalayer/fixmirrors.go new file mode 100644 index 0000000..1aed485 --- /dev/null +++ b/cmd/datalayer/fixmirrors.go @@ -0,0 +1,125 @@ +package datalayer + +import ( + "strings" + "time" + + "github.com/chia-network/go-chia-libs/pkg/rpc" + "github.com/chia-network/go-modules/pkg/slogs" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// fixMirrorsCmd Replaces one mirror url with another for all mirrors with the url +var fixMirrorsCmd = &cobra.Command{ + Use: "fix-mirrors", + Short: "For all owned mirrors, replaces one url with a new url", + Example: "chia-tools data fix-mirrors -b 127.0.0.1 -n https://my-dl-domain.com -a 300 -m 0.00000001", + Run: func(cmd *cobra.Command, args []string) { + client, err := rpc.NewClient(rpc.ConnectionModeHTTP, rpc.WithAutoConfig()) + if err != nil { + slogs.Logr.Fatal("error creating chia RPC client", "error", err) + } + + // Figure out what fee we are using + feeXCH := viper.GetFloat64("fix-mirror-fee") + feeMojos := uint64(feeXCH * 1000000000000) + slogs.Logr.Debug("fee for all transactions", "xch", feeXCH, "mojos", feeMojos) + + subscriptions, _, err := client.DataLayerService.GetSubscriptions(&rpc.DatalayerGetSubscriptionsOptions{}) + if err != nil { + slogs.Logr.Fatal("error getting list of datalayer subscriptions", "error", err) + } + + for _, sub := range subscriptions.StoreIDs { + foundAnyMirror := false + + mirrors, _, err := client.DataLayerService.GetMirrors(&rpc.DatalayerGetMirrorsOptions{ + ID: sub, + }) + if err != nil { + slogs.Logr.Fatal("error getting mirrors for subscription", "store", sub, "error", err) + } + for _, mirror := range mirrors.Mirrors { + if !mirror.Ours { + continue + } + for _, url := range mirror.URLs { + if strings.EqualFold(url, viper.GetString("fix-mirror-bad-url")) { + foundAnyMirror = true + waitForAvailableBalance(client, feeMojos) + slogs.Logr.Info("deleting mirror", "store", sub, "mirror", mirror.CoinID.String()) + _, _, err := client.DataLayerService.DeleteMirror(&rpc.DatalayerDeleteMirrorOptions{ + CoinID: mirror.CoinID.String(), + Fee: viper.GetUint64("fix-mirror-fee"), + }) + if err != nil { + slogs.Logr.Fatal("error deleting mirror", "store", sub, "mirror", mirror.CoinID.String(), "error", err) + } + break + } + } + } + + // Outside the mirror loop, in case there's a weird edge case where we have multiple mirrors on the same bad + // url, we consolidate down to just one + if foundAnyMirror { + mirrorAmount := viper.GetUint64("fix-mirror-amount") + waitForAvailableBalance(client, mirrorAmount+feeMojos) + slogs.Logr.Info("adding replacement mirror", "store", sub) + _, _, err = client.DataLayerService.AddMirror(&rpc.DatalayerAddMirrorOptions{ + ID: sub, + URLs: []string{viper.GetString("fix-mirror-new-url")}, + Amount: mirrorAmount, + Fee: feeMojos, + }) + if err != nil { + slogs.Logr.Fatal("error adding new mirror", "store", sub, "error", err) + } + } + } + }, +} + +// waitForAvailableBalance blocks execution until the wallet has at least one coin and the specified amount available to spend +func waitForAvailableBalance(client *rpc.Client, amount uint64) { + for { + balance, _, err := client.WalletService.GetWalletBalance(&rpc.GetWalletBalanceOptions{WalletID: 1}) + if err != nil { + slogs.Logr.Error("error checking wallet balance. Retrying in 5 seconds", "error", err) + time.Sleep(5 * time.Second) + continue + } + + if balance.Balance.IsAbsent() { + slogs.Logr.Error("unknown error checking wallet balance. Retrying in 5 seconds") + time.Sleep(5 * time.Second) + continue + } + + // Makes the assumption that wallet balance is not over uint64max mojos + // It is extremely unlikely to have that balance in one wallet + if !balance.Balance.MustGet().SpendableBalance.FitsInUint64() || balance.Balance.MustGet().SpendableBalance.Uint64() < amount { + slogs.Logr.Warn("wallet does not have enough funds to continue. Waiting...", "need", amount, "spendable", balance.Balance.MustGet().SpendableBalance.Uint64()) + time.Sleep(5 * time.Second) + continue + } + + // Have enough, so return + return + } +} + +func init() { + fixMirrorsCmd.PersistentFlags().Float64P("fee", "m", 0, "Fee to use when deleting and launching the mirrors. The fee is used per mirror. Units are XCH") + fixMirrorsCmd.PersistentFlags().StringP("new-url", "n", "", "New mirror URL (required)") + fixMirrorsCmd.PersistentFlags().StringP("bad-url", "b", "", "Old mirror URL to replace (required)") + fixMirrorsCmd.PersistentFlags().Uint64P("amount", "a", 100, "Mirror coin amount in mojos") + + cobra.CheckErr(viper.BindPFlag("fix-mirror-fee", fixMirrorsCmd.PersistentFlags().Lookup("fee"))) + cobra.CheckErr(viper.BindPFlag("fix-mirror-new-url", fixMirrorsCmd.PersistentFlags().Lookup("new-url"))) + cobra.CheckErr(viper.BindPFlag("fix-mirror-bad-url", fixMirrorsCmd.PersistentFlags().Lookup("bad-url"))) + cobra.CheckErr(viper.BindPFlag("fix-mirror-amount", fixMirrorsCmd.PersistentFlags().Lookup("amount"))) + + datalayerCmd.AddCommand(fixMirrorsCmd) +} From 7a9f13ed3a9709e58daa122fcddaa104835a8a1e Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Mon, 5 Aug 2024 16:34:04 -0500 Subject: [PATCH 05/12] Use run number for non-tagged debs --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a1c9b8f..25f0ff4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,7 +71,7 @@ jobs: --output-type deb \ --name chia-tools \ --architecture ${{ matrix.GOARCH }} \ - --version "${{ env.RELEASE_TAG || github.sha }}" \ + --version "${{ env.RELEASE_TAG || github.run_number }}" \ --url "https://github.com/Chia-Network/chia-tools" \ --maintainer "Chia Network Inc " \ --description "Collection of CLI tools for working with Chia Blockchain" \ From d464284b6edd05be7db74da00cf379dbb2580d69 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Tue, 6 Aug 2024 13:56:53 -0500 Subject: [PATCH 06/12] Add message for deleting mirror in delete command --- cmd/datalayer/deletemirrors.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/datalayer/deletemirrors.go b/cmd/datalayer/deletemirrors.go index 7b9abe4..d7c88f5 100644 --- a/cmd/datalayer/deletemirrors.go +++ b/cmd/datalayer/deletemirrors.go @@ -51,6 +51,7 @@ var deleteMirrorsCmd = &cobra.Command{ } for _, coinID := range ownedMirrors { + slogs.Logr.Info("deleting mirror", "store", subscription, "mirror", coinID.String()) resp, _, err := client.DataLayerService.DeleteMirror(&rpc.DatalayerDeleteMirrorOptions{ CoinID: coinID.String(), Fee: feeMojos, From 14491f781b9958c574ed37de605c1a589e5cc4c2 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Tue, 6 Aug 2024 21:20:04 -0500 Subject: [PATCH 07/12] Update go chia libs to tagged release --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dc22468..de691dc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/chia-network/chia-tools go 1.22.4 require ( - github.com/chia-network/go-chia-libs v0.8.6-0.20240802191521-ac5fb4a152f1 + github.com/chia-network/go-chia-libs v0.8.6 github.com/chia-network/go-modules v0.0.5 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 diff --git a/go.sum b/go.sum index 107a6ce..493eb5d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/chia-network/go-chia-libs v0.8.6-0.20240802191521-ac5fb4a152f1 h1:zmeRuQcnMEjBKEbQcOgEr3JyAGxZubOrXy8gKOek60w= -github.com/chia-network/go-chia-libs v0.8.6-0.20240802191521-ac5fb4a152f1/go.mod h1:npTqaFSjTdMxE7hc0LOmWJmWGqcs+IERarK5fDxXk/I= +github.com/chia-network/go-chia-libs v0.8.6 h1:7EzDO/TiQD3L981a28ArbsKb621vOVsml5kkpFitoFk= +github.com/chia-network/go-chia-libs v0.8.6/go.mod h1:npTqaFSjTdMxE7hc0LOmWJmWGqcs+IERarK5fDxXk/I= github.com/chia-network/go-modules v0.0.5 h1:5luTVlP6RgBXodnFcWFBk2sLdJn+6vQ4wObim683C7c= github.com/chia-network/go-modules v0.0.5/go.mod h1:5AiYBxQSvf2aFSOizTqFXXSeb9AucZWrWmRCVwUMO3A= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= From a957e2ddcf0e5213e53a69cab62c8ab2dc15bb80 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Tue, 6 Aug 2024 21:24:09 -0500 Subject: [PATCH 08/12] Add example for config generate --- cmd/config/generate.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/config/generate.go b/cmd/config/generate.go index b4f4df9..b5ceb5e 100644 --- a/cmd/config/generate.go +++ b/cmd/config/generate.go @@ -14,6 +14,7 @@ import ( var generateCmd = &cobra.Command{ Use: "generate", Short: "Generate a new chia configuration file", + Example: "chia-tools config generate --set full_node.port=58444 --set full_node.target_peer_count=10 --output ~/.chia/mainnet/config/config.yaml", Run: func(cmd *cobra.Command, args []string) { cfg, err := config.LoadDefaultConfig() if err != nil { From 11c1e47cf4041468b914a31b0583a6cb6ab5e3d9 Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Wed, 7 Aug 2024 06:36:13 -0500 Subject: [PATCH 09/12] Add flags for --all or --id to delete mirrors --- cmd/config/generate.go | 4 +- cmd/datalayer/deletemirrors.go | 98 +++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/cmd/config/generate.go b/cmd/config/generate.go index b5ceb5e..2320598 100644 --- a/cmd/config/generate.go +++ b/cmd/config/generate.go @@ -12,8 +12,8 @@ import ( // generateCmd generates a new chia config var generateCmd = &cobra.Command{ - Use: "generate", - Short: "Generate a new chia configuration file", + Use: "generate", + Short: "Generate a new chia configuration file", Example: "chia-tools config generate --set full_node.port=58444 --set full_node.target_peer_count=10 --output ~/.chia/mainnet/config/config.yaml", Run: func(cmd *cobra.Command, args []string) { cfg, err := config.LoadDefaultConfig() diff --git a/cmd/datalayer/deletemirrors.go b/cmd/datalayer/deletemirrors.go index d7c88f5..db911a9 100644 --- a/cmd/datalayer/deletemirrors.go +++ b/cmd/datalayer/deletemirrors.go @@ -1,6 +1,8 @@ package datalayer import ( + "fmt" + "github.com/chia-network/go-chia-libs/pkg/rpc" "github.com/chia-network/go-chia-libs/pkg/types" "github.com/chia-network/go-modules/pkg/slogs" @@ -12,6 +14,14 @@ import ( var deleteMirrorsCmd = &cobra.Command{ Use: "delete-mirrors", Short: "Deletes all owned mirrors for all datalayer subscriptions", + PreRunE: func(cmd *cobra.Command, args []string) error { + all := viper.GetBool("delete-mirror-all") + subID := viper.GetString("delete-mirror-id") + if !all && subID == "" { + return fmt.Errorf("must provide a subscription ID with --id flag or use --all option") + } + return nil + }, Run: func(cmd *cobra.Command, args []string) { client, err := rpc.NewClient(rpc.ConnectionModeHTTP, rpc.WithAutoConfig()) if err != nil { @@ -21,55 +31,71 @@ var deleteMirrorsCmd = &cobra.Command{ // Figure out what fee we are using feeXCH := viper.GetFloat64("delete-mirror-fee") feeMojos := uint64(feeXCH * 1000000000000) - slogs.Logr.Debug("fee for all transactions", "xch", feeXCH, "mojos", feeMojos) - - subscriptions, _, err := client.DataLayerService.GetSubscriptions(&rpc.DatalayerGetSubscriptionsOptions{}) - if err != nil { - slogs.Logr.Fatal("error getting list of datalayer subscriptions", "error", err) - } - - for _, subscription := range subscriptions.StoreIDs { - slogs.Logr.Info("checking subscription", "store", subscription) + slogs.Logr.Info("fee for all transactions", "xch", feeXCH, "mojos", feeMojos) - mirrors, _, err := client.DataLayerService.GetMirrors(&rpc.DatalayerGetMirrorsOptions{ - ID: subscription, - }) + all := viper.GetBool("delete-mirror-all") + subID := viper.GetString("delete-mirror-id") + if all { + slogs.Logr.Info("deleting all owned mirrors for all subscriptions") + subscriptions, _, err := client.DataLayerService.GetSubscriptions(&rpc.DatalayerGetSubscriptionsOptions{}) if err != nil { - slogs.Logr.Fatal("error fetching mirrors for subscription", "store", subscription, "error", err) + slogs.Logr.Fatal("error getting list of datalayer subscriptions", "error", err) } - var ownedMirrors []types.Bytes32 - for _, mirror := range mirrors.Mirrors { - if mirror.Ours { - ownedMirrors = append(ownedMirrors, mirror.CoinID) - } + for _, subscription := range subscriptions.StoreIDs { + deleteMirrorsForSubscription(client, subscription, feeMojos) } + } else { + deleteMirrorsForSubscription(client, subID, feeMojos) + } + }, +} - if len(ownedMirrors) == 0 { - slogs.Logr.Info("no owned mirrors for this datastore", "store", subscription) - continue - } +func deleteMirrorsForSubscription(client *rpc.Client, subscription string, feeMojos uint64) { + slogs.Logr.Info("checking subscription", "store", subscription) - for _, coinID := range ownedMirrors { - slogs.Logr.Info("deleting mirror", "store", subscription, "mirror", coinID.String()) - resp, _, err := client.DataLayerService.DeleteMirror(&rpc.DatalayerDeleteMirrorOptions{ - CoinID: coinID.String(), - Fee: feeMojos, - }) - if err != nil { - slogs.Logr.Fatal("error deleting mirror for store", "store", subscription, "mirror", coinID, "error", err) - } - if !resp.Success { - slogs.Logr.Fatal("unknown error when deleting mirror for store", "store", subscription, "mirror", coinID) - } - } + mirrors, _, err := client.DataLayerService.GetMirrors(&rpc.DatalayerGetMirrorsOptions{ + ID: subscription, + }) + if err != nil { + slogs.Logr.Fatal("error fetching mirrors for subscription", "store", subscription, "error", err) + } + var ownedMirrors []types.Bytes32 + + for _, mirror := range mirrors.Mirrors { + if mirror.Ours { + ownedMirrors = append(ownedMirrors, mirror.CoinID) } - }, + } + + if len(ownedMirrors) == 0 { + slogs.Logr.Info("no owned mirrors for this datastore", "store", subscription) + return + } + + for _, coinID := range ownedMirrors { + slogs.Logr.Info("deleting mirror", "store", subscription, "mirror", coinID.String()) + resp, _, err := client.DataLayerService.DeleteMirror(&rpc.DatalayerDeleteMirrorOptions{ + CoinID: coinID.String(), + Fee: feeMojos, + }) + if err != nil { + slogs.Logr.Fatal("error deleting mirror for store", "store", subscription, "mirror", coinID, "error", err) + } + if !resp.Success { + slogs.Logr.Fatal("unknown error when deleting mirror for store", "store", subscription, "mirror", coinID) + } + } } func init() { deleteMirrorsCmd.PersistentFlags().Float64P("fee", "m", 0, "Fee to use when deleting the mirrors. The fee is used per mirror. Units are XCH") + deleteMirrorsCmd.PersistentFlags().Bool("all", false, "Delete all owned mirrors for all subscriptions") + deleteMirrorsCmd.PersistentFlags().String("id", "", "The subscription ID to delete mirrors for") + cobra.CheckErr(viper.BindPFlag("delete-mirror-fee", deleteMirrorsCmd.PersistentFlags().Lookup("fee"))) + cobra.CheckErr(viper.BindPFlag("delete-mirror-all", deleteMirrorsCmd.PersistentFlags().Lookup("all"))) + cobra.CheckErr(viper.BindPFlag("delete-mirror-id", deleteMirrorsCmd.PersistentFlags().Lookup("id"))) datalayerCmd.AddCommand(deleteMirrorsCmd) } From f13e215a781161f9efe12f2cd2dc7f863ffa956e Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Wed, 7 Aug 2024 06:38:50 -0500 Subject: [PATCH 10/12] Add input checking on fix mirrors --- cmd/datalayer/fixmirrors.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cmd/datalayer/fixmirrors.go b/cmd/datalayer/fixmirrors.go index 1aed485..7501b20 100644 --- a/cmd/datalayer/fixmirrors.go +++ b/cmd/datalayer/fixmirrors.go @@ -1,6 +1,7 @@ package datalayer import ( + "fmt" "strings" "time" @@ -15,6 +16,16 @@ var fixMirrorsCmd = &cobra.Command{ Use: "fix-mirrors", Short: "For all owned mirrors, replaces one url with a new url", Example: "chia-tools data fix-mirrors -b 127.0.0.1 -n https://my-dl-domain.com -a 300 -m 0.00000001", + PreRunE: func(cmd *cobra.Command, args []string) error { + newURL := viper.GetString("fix-mirror-new-url") + oldURL := viper.GetString("fix-mirror-bad-url") + + if newURL == "" || oldURL == "" { + return fmt.Errorf("must provide both --new-url and --old-url flags") + } + + return nil + }, Run: func(cmd *cobra.Command, args []string) { client, err := rpc.NewClient(rpc.ConnectionModeHTTP, rpc.WithAutoConfig()) if err != nil { @@ -24,7 +35,7 @@ var fixMirrorsCmd = &cobra.Command{ // Figure out what fee we are using feeXCH := viper.GetFloat64("fix-mirror-fee") feeMojos := uint64(feeXCH * 1000000000000) - slogs.Logr.Debug("fee for all transactions", "xch", feeXCH, "mojos", feeMojos) + slogs.Logr.Info("fee for all transactions", "xch", feeXCH, "mojos", feeMojos) subscriptions, _, err := client.DataLayerService.GetSubscriptions(&rpc.DatalayerGetSubscriptionsOptions{}) if err != nil { From c13c84659e2db50a3f42df58230ee5086423a93d Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Wed, 7 Aug 2024 06:40:02 -0500 Subject: [PATCH 11/12] Add examples for delete-mirrors --- cmd/datalayer/deletemirrors.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/datalayer/deletemirrors.go b/cmd/datalayer/deletemirrors.go index db911a9..5573c7c 100644 --- a/cmd/datalayer/deletemirrors.go +++ b/cmd/datalayer/deletemirrors.go @@ -14,6 +14,7 @@ import ( var deleteMirrorsCmd = &cobra.Command{ Use: "delete-mirrors", Short: "Deletes all owned mirrors for all datalayer subscriptions", + Example: "chia-tools data delete-mirrors --all\nchia-tools data delete-mirrors --id abcd1234", PreRunE: func(cmd *cobra.Command, args []string) error { all := viper.GetBool("delete-mirror-all") subID := viper.GetString("delete-mirror-id") From bf245a76b7901b430a284a72ec86ede4911d23ab Mon Sep 17 00:00:00 2001 From: Chris Marslender Date: Wed, 7 Aug 2024 06:41:17 -0500 Subject: [PATCH 12/12] Add example for certs generate --- cmd/certs/generate.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/certs/generate.go b/cmd/certs/generate.go index 10ce21c..b6060a1 100644 --- a/cmd/certs/generate.go +++ b/cmd/certs/generate.go @@ -11,6 +11,7 @@ import ( var generateCmd = &cobra.Command{ Use: "generate", Short: "Generates a full set of certificates for chia-blockchain", + Example: "chia-tools certs generate --output ~/.chia/mainnet/config/ssl", Run: func(cmd *cobra.Command, args []string) { err := tls.GenerateAllCerts(viper.GetString("cert-output")) if err != nil {