From bb90c8d6907e9965dbb28dcb28a9330925975435 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Mon, 30 Oct 2023 09:49:28 -0500 Subject: [PATCH 1/6] add subcommand: skywire-cli reward calc --- cmd/skywire-cli/commands/reward/root.go | 170 +++++++++++++++++++++++- 1 file changed, 168 insertions(+), 2 deletions(-) diff --git a/cmd/skywire-cli/commands/reward/root.go b/cmd/skywire-cli/commands/reward/root.go index 91eb1e72e3..3d7172cfc7 100644 --- a/cmd/skywire-cli/commands/reward/root.go +++ b/cmd/skywire-cli/commands/reward/root.go @@ -3,13 +3,17 @@ package clireward import ( "fmt" + "log" "os" + "sort" + "strconv" "strings" + "time" coincipher "github.com/skycoin/skycoin/src/cipher" "github.com/spf13/cobra" "github.com/spf13/pflag" - + "github.com/bitfield/script" clirpc "github.com/skycoin/skywire/cmd/skywire-cli/commands/rpc" "github.com/skycoin/skywire/cmd/skywire-cli/internal" "github.com/skycoin/skywire/pkg/visor/visorconfig" @@ -29,7 +33,6 @@ var ( ) func init() { - rewardCmd.Flags().SortFlags = false if defaultRewardAddress == "" { //default is genesis address for skycoin blockchain ; for testing @@ -196,3 +199,166 @@ func readRewardFile(cmdFlags *pflag.FlagSet) { output := fmt.Sprintf("Reward address file:\n %s\nreward address:\n %s\n", output, dat) internal.PrintOutput(cmdFlags, output, output) } + + + + +const yearlyTotalRewards int = 408000 + +var ( + yearlyTotal int + surveyPath string + wdate = time.Now().AddDate(0, 0, -1).Format("2006-01-02") + utfile string + disallowArchitectures string +) + +type nodeinfo struct { + SkyAddr string `json:"skycoin_address"` + PK string `json:"public_key"` + Arch string `json:"go_arch"` + IPAddr string `json:"ip_address"` + Share float64 `json:"reward_share"` + Reward float64 `json:"reward_amount"` +} + +type ipCount struct { + IP string + Count int +} + +type rewardData struct { + SkyAddr string + Reward float64 +} + + +func init() { + RootCmd.AddCommand(rewardCalcCmd) + rewardCalcCmd.Flags().SortFlags = false + rewardCalcCmd.Flags().StringVarP(&wdate, "date", "d", wdate, "date for which to calculate reward") + rewardCalcCmd.Flags().StringVarP(&disallowArchitectures, "noarch", "n", "amd64", "disallowed architectures, comma separated") + rewardCalcCmd.Flags().IntVarP(&yearlyTotal, "year", "y", yearlyTotalRewards, "yearly total rewards") + rewardCalcCmd.Flags().StringVarP(&utfile, "utfile", "u", "ut.txt", "uptime tracker data file") + rewardCalcCmd.Flags().StringVarP(&surveyPath, "path", "p", "./log_collecting", "path to the surveys ") +} + +var rewardCalcCmd = &cobra.Command{ + Use: "calc", + Short: "calculate rewards from uptime data & collected surveys", + Long: ` +Collect surveys: skywire-cli log +Fetch uptimes: skywire-cli ut > ut.txt`, + Run: func(cmd *cobra.Command, args []string) { + _, err := os.Stat(surveyPath) + if os.IsNotExist(err) { + log.Fatal("the path to the surveys does not exist\n", err, "\nfetch the surveys with:\n$ skywire-cli log") + } + _, err = os.Stat(utfile) + if os.IsNotExist(err) { + log.Fatal("uptime tracker data file not found\n", err, "\nfetch the uptime tracker data with:\n$ skywire-cli ut > ut.txt") + } + + archMap := make(map[string]struct{}) + for _, disallowedarch := range strings.Split(disallowArchitectures, ",") { + if disallowedarch != "" { + archMap[disallowedarch] = struct{}{} + } + } + res, _ := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() + var nodesInfos []nodeinfo + for _, pk := range res { + nodeInfo := fmt.Sprintf("%s/%s/node-info.json", surveyPath, pk) + ip, _ := script.File(nodeInfo).JQ(`."ip.skycoin.com".ip_address`).Replace(" ", "").Replace(`"`, "").String() + ip = strings.TrimRight(ip, "\n") + sky, _ := script.File(nodeInfo).JQ(".skycoin_address").Replace(" ", "").Replace(`"`, "").String() + sky = strings.TrimRight(sky, "\n") + arch, _ := script.File(nodeInfo).JQ(".go_arch").Replace(" ", "").Replace(`"`, "").String() + arch = strings.TrimRight(arch, "\n") + if _, disallowed := archMap[arch]; !disallowed && ip != "" && strings.Count(ip, ".") == 3 && sky != "" { + ni := nodeinfo{ + IPAddr: ip, + SkyAddr: sky, + PK: pk, + Arch: arch, + } + nodesInfos = append(nodesInfos, ni) + } + } + daysThisMonth := float64(time.Date(time.Now().Year(), time.Now().Month()+1, 0, 0, 0, 0, 0, time.UTC).Day()) + daysThisYear := float64(int(time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 999999999, time.UTC).Sub(time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.UTC)).Hours())/24) + monthReward := (float64(yearlyTotal) / daysThisYear) * daysThisMonth + dayReward := monthReward / daysThisMonth + wdate = strings.ReplaceAll(wdate, " ", "0") + fmt.Printf("date: %s\n", wdate) + fmt.Printf("days this month: %.4f\n", daysThisMonth) + fmt.Printf("days in the year: %.4f\n", daysThisYear) + fmt.Printf("this month's rewards: %.4f\n", monthReward) + fmt.Printf("reward total: %.4f\n", dayReward) + + uniqueIP, _ := script.Echo(func() string { + var inputStr strings.Builder + for _, ni := range nodesInfos { + inputStr.WriteString(fmt.Sprintf("%s\n", ni.IPAddr)) + } + return inputStr.String() + }()).Freq().String() + var ipCounts []ipCount + lines := strings.Split(uniqueIP, "\n") + for _, line := range lines { + if line != "" { + fields := strings.Fields(line) + if len(fields) == 2 { + count, _ := strconv.Atoi(fields[0]) + ipCounts = append(ipCounts, ipCount{ + IP: fields[1], + Count: count, + }) + } + } + } + totalValidShares := 0 + for _, ipCount := range ipCounts { + if ipCount.Count <= 8 { + totalValidShares += ipCount.Count + } else { + totalValidShares += 8 + } + } + fmt.Printf("Total valid shares: %d\n", totalValidShares) + + for i, ni := range nodesInfos { + for _, ipCount := range ipCounts { + if ni.IPAddr == ipCount.IP { + if ipCount.Count <= 8 { + nodesInfos[i].Share = 1.0 + } else { + nodesInfos[i].Share = 8.0 / float64(ipCount.Count) + } + break + } + } + nodesInfos[i].Reward = nodesInfos[i].Share / float64(totalValidShares) * dayReward + } + + fmt.Println("IP, Skycoin Address, Skywire Public Key, Architecture, Reward Shares, Reward $SKY amout") + for _, ni := range nodesInfos { + fmt.Printf("%s, %s, %s, %s, %4f, %4f\n", ni.IPAddr, ni.SkyAddr, ni.PK, ni.Arch, ni.Share, ni.Reward) + } + rewardSumBySkyAddr := make(map[string]float64) + for _, ni := range nodesInfos { + rewardSumBySkyAddr[ni.SkyAddr] += ni.Reward + } + var sortedSkyAddrs []rewardData + for skyAddr, rewardSum := range rewardSumBySkyAddr { + sortedSkyAddrs = append(sortedSkyAddrs, rewardData{SkyAddr: skyAddr, Reward: rewardSum}) + } + sort.Slice(sortedSkyAddrs, func(i, j int) bool { + return sortedSkyAddrs[i].Reward > sortedSkyAddrs[j].Reward + }) + fmt.Println("Skycoin Address, Reward Amount") + for _, skyAddrReward := range sortedSkyAddrs { + fmt.Printf("%s, %.4f\n", skyAddrReward.SkyAddr, skyAddrReward.Reward) + } + }, +} From 020d9b75e479f029c0ef53832db01f7318c1d382 Mon Sep 17 00:00:00 2001 From: Moses Narrow <36607567+0pcom@users.noreply.github.com> Date: Mon, 6 Nov 2023 06:18:22 -0600 Subject: [PATCH 2/6] fix make check errors --- cmd/skywire-cli/commands/reward/root.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/skywire-cli/commands/reward/root.go b/cmd/skywire-cli/commands/reward/root.go index 3d7172cfc7..25d77280d5 100644 --- a/cmd/skywire-cli/commands/reward/root.go +++ b/cmd/skywire-cli/commands/reward/root.go @@ -265,15 +265,18 @@ Fetch uptimes: skywire-cli ut > ut.txt`, archMap[disallowedarch] = struct{}{} } } - res, _ := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() + res, err := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() + if err != nil { + internal.PrintFatalError(cmdFlags, fmt.Errorf("Error reading uptime tracker data file. err=%v", err)) + } var nodesInfos []nodeinfo for _, pk := range res { nodeInfo := fmt.Sprintf("%s/%s/node-info.json", surveyPath, pk) - ip, _ := script.File(nodeInfo).JQ(`."ip.skycoin.com".ip_address`).Replace(" ", "").Replace(`"`, "").String() + ip, _ := script.File(nodeInfo).JQ(`."ip.skycoin.com".ip_address`).Replace(" ", "").Replace(`"`, "").String() //nolint ip = strings.TrimRight(ip, "\n") - sky, _ := script.File(nodeInfo).JQ(".skycoin_address").Replace(" ", "").Replace(`"`, "").String() + sky, _ := script.File(nodeInfo).JQ(".skycoin_address").Replace(" ", "").Replace(`"`, "").String() //nolint sky = strings.TrimRight(sky, "\n") - arch, _ := script.File(nodeInfo).JQ(".go_arch").Replace(" ", "").Replace(`"`, "").String() + arch, _ := script.File(nodeInfo).JQ(".go_arch").Replace(" ", "").Replace(`"`, "").String() //nolint arch = strings.TrimRight(arch, "\n") if _, disallowed := archMap[arch]; !disallowed && ip != "" && strings.Count(ip, ".") == 3 && sky != "" { ni := nodeinfo{ From 778fdf5388abd537f68387d9d030a77fbd72bfb6 Mon Sep 17 00:00:00 2001 From: Moses Narrow <36607567+0pcom@users.noreply.github.com> Date: Mon, 6 Nov 2023 06:26:36 -0600 Subject: [PATCH 3/6] fix make check errors --- cmd/skywire-cli/commands/reward/root.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cmd/skywire-cli/commands/reward/root.go b/cmd/skywire-cli/commands/reward/root.go index 25d77280d5..92a32e6a9c 100644 --- a/cmd/skywire-cli/commands/reward/root.go +++ b/cmd/skywire-cli/commands/reward/root.go @@ -265,10 +265,7 @@ Fetch uptimes: skywire-cli ut > ut.txt`, archMap[disallowedarch] = struct{}{} } } - res, err := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() - if err != nil { - internal.PrintFatalError(cmdFlags, fmt.Errorf("Error reading uptime tracker data file. err=%v", err)) - } + res, _ := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() //nolint var nodesInfos []nodeinfo for _, pk := range res { nodeInfo := fmt.Sprintf("%s/%s/node-info.json", surveyPath, pk) From c0be87c9c2f54f79240a719b4611d534ebfb024c Mon Sep 17 00:00:00 2001 From: Moses Narrow <36607567+0pcom@users.noreply.github.com> Date: Mon, 6 Nov 2023 06:36:53 -0600 Subject: [PATCH 4/6] fix make check errors --- cmd/skywire-cli/commands/reward/root.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/skywire-cli/commands/reward/root.go b/cmd/skywire-cli/commands/reward/root.go index 92a32e6a9c..b4adbed758 100644 --- a/cmd/skywire-cli/commands/reward/root.go +++ b/cmd/skywire-cli/commands/reward/root.go @@ -302,14 +302,14 @@ Fetch uptimes: skywire-cli ut > ut.txt`, inputStr.WriteString(fmt.Sprintf("%s\n", ni.IPAddr)) } return inputStr.String() - }()).Freq().String() + }()).Freq().String() //nolint var ipCounts []ipCount lines := strings.Split(uniqueIP, "\n") for _, line := range lines { if line != "" { fields := strings.Fields(line) if len(fields) == 2 { - count, _ := strconv.Atoi(fields[0]) + count, _ := strconv.Atoi(fields[0]) //nolint ipCounts = append(ipCounts, ipCount{ IP: fields[1], Count: count, From 12187bd073a2db073a4bad848e5dd9b9c2c37b61 Mon Sep 17 00:00:00 2001 From: Moses Narrow <36607567+0pcom@users.noreply.github.com> Date: Mon, 6 Nov 2023 06:48:46 -0600 Subject: [PATCH 5/6] fix make check errors --- cmd/skywire-cli/commands/reward/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/skywire-cli/commands/reward/root.go b/cmd/skywire-cli/commands/reward/root.go index b4adbed758..b4875b9e29 100644 --- a/cmd/skywire-cli/commands/reward/root.go +++ b/cmd/skywire-cli/commands/reward/root.go @@ -296,7 +296,7 @@ Fetch uptimes: skywire-cli ut > ut.txt`, fmt.Printf("this month's rewards: %.4f\n", monthReward) fmt.Printf("reward total: %.4f\n", dayReward) - uniqueIP, _ := script.Echo(func() string { + uniqueIP, _ := script.Echo(func() string { //nolint var inputStr strings.Builder for _, ni := range nodesInfos { inputStr.WriteString(fmt.Sprintf("%s\n", ni.IPAddr)) From 8cbc964e835face5efe6650a43498e2bb6240b74 Mon Sep 17 00:00:00 2001 From: Moses Narrow <36607567+0pcom@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:43:25 -0600 Subject: [PATCH 6/6] fix make check errors --- cmd/skywire-cli/commands/reward/root.go | 249 ++++++++++++------------ 1 file changed, 123 insertions(+), 126 deletions(-) diff --git a/cmd/skywire-cli/commands/reward/root.go b/cmd/skywire-cli/commands/reward/root.go index b4875b9e29..374cc405c4 100644 --- a/cmd/skywire-cli/commands/reward/root.go +++ b/cmd/skywire-cli/commands/reward/root.go @@ -10,10 +10,11 @@ import ( "strings" "time" + "github.com/bitfield/script" coincipher "github.com/skycoin/skycoin/src/cipher" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/bitfield/script" + clirpc "github.com/skycoin/skywire/cmd/skywire-cli/commands/rpc" "github.com/skycoin/skywire/cmd/skywire-cli/internal" "github.com/skycoin/skywire/pkg/visor/visorconfig" @@ -200,26 +201,23 @@ func readRewardFile(cmdFlags *pflag.FlagSet) { internal.PrintOutput(cmdFlags, output, output) } - - - const yearlyTotalRewards int = 408000 var ( - yearlyTotal int - surveyPath string - wdate = time.Now().AddDate(0, 0, -1).Format("2006-01-02") - utfile string - disallowArchitectures string + yearlyTotal int + surveyPath string + wdate = time.Now().AddDate(0, 0, -1).Format("2006-01-02") + utfile string + disallowArchitectures string ) type nodeinfo struct { SkyAddr string `json:"skycoin_address"` PK string `json:"public_key"` - Arch string `json:"go_arch"` - IPAddr string `json:"ip_address"` - Share float64 `json:"reward_share"` - Reward float64 `json:"reward_amount"` + Arch string `json:"go_arch"` + IPAddr string `json:"ip_address"` + Share float64 `json:"reward_share"` + Reward float64 `json:"reward_amount"` } type ipCount struct { @@ -228,137 +226,136 @@ type ipCount struct { } type rewardData struct { - SkyAddr string - Reward float64 + SkyAddr string + Reward float64 } - func init() { RootCmd.AddCommand(rewardCalcCmd) rewardCalcCmd.Flags().SortFlags = false - rewardCalcCmd.Flags().StringVarP(&wdate, "date", "d", wdate, "date for which to calculate reward") - rewardCalcCmd.Flags().StringVarP(&disallowArchitectures, "noarch", "n", "amd64", "disallowed architectures, comma separated") - rewardCalcCmd.Flags().IntVarP(&yearlyTotal, "year", "y", yearlyTotalRewards, "yearly total rewards") - rewardCalcCmd.Flags().StringVarP(&utfile, "utfile", "u", "ut.txt", "uptime tracker data file") + rewardCalcCmd.Flags().StringVarP(&wdate, "date", "d", wdate, "date for which to calculate reward") + rewardCalcCmd.Flags().StringVarP(&disallowArchitectures, "noarch", "n", "amd64", "disallowed architectures, comma separated") + rewardCalcCmd.Flags().IntVarP(&yearlyTotal, "year", "y", yearlyTotalRewards, "yearly total rewards") + rewardCalcCmd.Flags().StringVarP(&utfile, "utfile", "u", "ut.txt", "uptime tracker data file") rewardCalcCmd.Flags().StringVarP(&surveyPath, "path", "p", "./log_collecting", "path to the surveys ") } var rewardCalcCmd = &cobra.Command{ Use: "calc", Short: "calculate rewards from uptime data & collected surveys", - Long: ` + Long: ` Collect surveys: skywire-cli log Fetch uptimes: skywire-cli ut > ut.txt`, Run: func(cmd *cobra.Command, args []string) { _, err := os.Stat(surveyPath) - if os.IsNotExist(err) { - log.Fatal("the path to the surveys does not exist\n", err, "\nfetch the surveys with:\n$ skywire-cli log") - } + if os.IsNotExist(err) { + log.Fatal("the path to the surveys does not exist\n", err, "\nfetch the surveys with:\n$ skywire-cli log") + } _, err = os.Stat(utfile) - if os.IsNotExist(err) { - log.Fatal("uptime tracker data file not found\n", err, "\nfetch the uptime tracker data with:\n$ skywire-cli ut > ut.txt") - } + if os.IsNotExist(err) { + log.Fatal("uptime tracker data file not found\n", err, "\nfetch the uptime tracker data with:\n$ skywire-cli ut > ut.txt") + } - archMap := make(map[string]struct{}) - for _, disallowedarch := range strings.Split(disallowArchitectures, ",") { - if disallowedarch != "" { - archMap[disallowedarch] = struct{}{} - } - } - res, _ := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() //nolint - var nodesInfos []nodeinfo - for _, pk := range res { - nodeInfo := fmt.Sprintf("%s/%s/node-info.json", surveyPath, pk) - ip, _ := script.File(nodeInfo).JQ(`."ip.skycoin.com".ip_address`).Replace(" ", "").Replace(`"`, "").String() //nolint - ip = strings.TrimRight(ip, "\n") - sky, _ := script.File(nodeInfo).JQ(".skycoin_address").Replace(" ", "").Replace(`"`, "").String() //nolint - sky = strings.TrimRight(sky, "\n") - arch, _ := script.File(nodeInfo).JQ(".go_arch").Replace(" ", "").Replace(`"`, "").String() //nolint - arch = strings.TrimRight(arch, "\n") - if _, disallowed := archMap[arch]; !disallowed && ip != "" && strings.Count(ip, ".") == 3 && sky != "" { - ni := nodeinfo{ - IPAddr: ip, - SkyAddr: sky, - PK: pk, - Arch: arch, - } - nodesInfos = append(nodesInfos, ni) - } - } - daysThisMonth := float64(time.Date(time.Now().Year(), time.Now().Month()+1, 0, 0, 0, 0, 0, time.UTC).Day()) - daysThisYear := float64(int(time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 999999999, time.UTC).Sub(time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.UTC)).Hours())/24) - monthReward := (float64(yearlyTotal) / daysThisYear) * daysThisMonth - dayReward := monthReward / daysThisMonth - wdate = strings.ReplaceAll(wdate, " ", "0") - fmt.Printf("date: %s\n", wdate) - fmt.Printf("days this month: %.4f\n", daysThisMonth) - fmt.Printf("days in the year: %.4f\n", daysThisYear) - fmt.Printf("this month's rewards: %.4f\n", monthReward) - fmt.Printf("reward total: %.4f\n", dayReward) + archMap := make(map[string]struct{}) + for _, disallowedarch := range strings.Split(disallowArchitectures, ",") { + if disallowedarch != "" { + archMap[disallowedarch] = struct{}{} + } + } + res, _ := script.File(utfile).Match(strings.TrimRight(wdate, "\n")).Column(1).Slice() //nolint + var nodesInfos []nodeinfo + for _, pk := range res { + nodeInfo := fmt.Sprintf("%s/%s/node-info.json", surveyPath, pk) + ip, _ := script.File(nodeInfo).JQ(`."ip.skycoin.com".ip_address`).Replace(" ", "").Replace(`"`, "").String() //nolint + ip = strings.TrimRight(ip, "\n") + sky, _ := script.File(nodeInfo).JQ(".skycoin_address").Replace(" ", "").Replace(`"`, "").String() //nolint + sky = strings.TrimRight(sky, "\n") + arch, _ := script.File(nodeInfo).JQ(".go_arch").Replace(" ", "").Replace(`"`, "").String() //nolint + arch = strings.TrimRight(arch, "\n") + if _, disallowed := archMap[arch]; !disallowed && ip != "" && strings.Count(ip, ".") == 3 && sky != "" { + ni := nodeinfo{ + IPAddr: ip, + SkyAddr: sky, + PK: pk, + Arch: arch, + } + nodesInfos = append(nodesInfos, ni) + } + } + daysThisMonth := float64(time.Date(time.Now().Year(), time.Now().Month()+1, 0, 0, 0, 0, 0, time.UTC).Day()) + daysThisYear := float64(int(time.Date(time.Now().Year(), 12, 31, 23, 59, 59, 999999999, time.UTC).Sub(time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.UTC)).Hours()) / 24) + monthReward := (float64(yearlyTotal) / daysThisYear) * daysThisMonth + dayReward := monthReward / daysThisMonth + wdate = strings.ReplaceAll(wdate, " ", "0") + fmt.Printf("date: %s\n", wdate) + fmt.Printf("days this month: %.4f\n", daysThisMonth) + fmt.Printf("days in the year: %.4f\n", daysThisYear) + fmt.Printf("this month's rewards: %.4f\n", monthReward) + fmt.Printf("reward total: %.4f\n", dayReward) - uniqueIP, _ := script.Echo(func() string { //nolint - var inputStr strings.Builder - for _, ni := range nodesInfos { - inputStr.WriteString(fmt.Sprintf("%s\n", ni.IPAddr)) - } - return inputStr.String() - }()).Freq().String() //nolint - var ipCounts []ipCount - lines := strings.Split(uniqueIP, "\n") - for _, line := range lines { - if line != "" { - fields := strings.Fields(line) - if len(fields) == 2 { - count, _ := strconv.Atoi(fields[0]) //nolint - ipCounts = append(ipCounts, ipCount{ - IP: fields[1], - Count: count, - }) - } - } - } - totalValidShares := 0 - for _, ipCount := range ipCounts { - if ipCount.Count <= 8 { - totalValidShares += ipCount.Count - } else { - totalValidShares += 8 - } - } - fmt.Printf("Total valid shares: %d\n", totalValidShares) + uniqueIP, _ := script.Echo(func() string { //nolint + var inputStr strings.Builder + for _, ni := range nodesInfos { + inputStr.WriteString(fmt.Sprintf("%s\n", ni.IPAddr)) + } + return inputStr.String() + }()).Freq().String() //nolint + var ipCounts []ipCount + lines := strings.Split(uniqueIP, "\n") + for _, line := range lines { + if line != "" { + fields := strings.Fields(line) + if len(fields) == 2 { + count, _ := strconv.Atoi(fields[0]) //nolint + ipCounts = append(ipCounts, ipCount{ + IP: fields[1], + Count: count, + }) + } + } + } + totalValidShares := 0 + for _, ipCount := range ipCounts { + if ipCount.Count <= 8 { + totalValidShares += ipCount.Count + } else { + totalValidShares += 8 + } + } + fmt.Printf("Total valid shares: %d\n", totalValidShares) - for i, ni := range nodesInfos { - for _, ipCount := range ipCounts { - if ni.IPAddr == ipCount.IP { - if ipCount.Count <= 8 { - nodesInfos[i].Share = 1.0 - } else { - nodesInfos[i].Share = 8.0 / float64(ipCount.Count) - } - break - } - } - nodesInfos[i].Reward = nodesInfos[i].Share / float64(totalValidShares) * dayReward - } + for i, ni := range nodesInfos { + for _, ipCount := range ipCounts { + if ni.IPAddr == ipCount.IP { + if ipCount.Count <= 8 { + nodesInfos[i].Share = 1.0 + } else { + nodesInfos[i].Share = 8.0 / float64(ipCount.Count) + } + break + } + } + nodesInfos[i].Reward = nodesInfos[i].Share / float64(totalValidShares) * dayReward + } - fmt.Println("IP, Skycoin Address, Skywire Public Key, Architecture, Reward Shares, Reward $SKY amout") - for _, ni := range nodesInfos { - fmt.Printf("%s, %s, %s, %s, %4f, %4f\n", ni.IPAddr, ni.SkyAddr, ni.PK, ni.Arch, ni.Share, ni.Reward) - } - rewardSumBySkyAddr := make(map[string]float64) - for _, ni := range nodesInfos { - rewardSumBySkyAddr[ni.SkyAddr] += ni.Reward - } - var sortedSkyAddrs []rewardData - for skyAddr, rewardSum := range rewardSumBySkyAddr { - sortedSkyAddrs = append(sortedSkyAddrs, rewardData{SkyAddr: skyAddr, Reward: rewardSum}) - } - sort.Slice(sortedSkyAddrs, func(i, j int) bool { - return sortedSkyAddrs[i].Reward > sortedSkyAddrs[j].Reward - }) - fmt.Println("Skycoin Address, Reward Amount") - for _, skyAddrReward := range sortedSkyAddrs { - fmt.Printf("%s, %.4f\n", skyAddrReward.SkyAddr, skyAddrReward.Reward) - } - }, + fmt.Println("IP, Skycoin Address, Skywire Public Key, Architecture, Reward Shares, Reward $SKY amout") + for _, ni := range nodesInfos { + fmt.Printf("%s, %s, %s, %s, %4f, %4f\n", ni.IPAddr, ni.SkyAddr, ni.PK, ni.Arch, ni.Share, ni.Reward) + } + rewardSumBySkyAddr := make(map[string]float64) + for _, ni := range nodesInfos { + rewardSumBySkyAddr[ni.SkyAddr] += ni.Reward + } + var sortedSkyAddrs []rewardData + for skyAddr, rewardSum := range rewardSumBySkyAddr { + sortedSkyAddrs = append(sortedSkyAddrs, rewardData{SkyAddr: skyAddr, Reward: rewardSum}) + } + sort.Slice(sortedSkyAddrs, func(i, j int) bool { + return sortedSkyAddrs[i].Reward > sortedSkyAddrs[j].Reward + }) + fmt.Println("Skycoin Address, Reward Amount") + for _, skyAddrReward := range sortedSkyAddrs { + fmt.Printf("%s, %.4f\n", skyAddrReward.SkyAddr, skyAddrReward.Reward) + } + }, }