An Yggdrasil address miner in Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
2.7 KiB

  1. package main
  2. /*
  3. This program is largely based on cmd/genkeys from yggdrasil-go, located at
  4. https://github.com/yggdrasil-network/yggdrasil-go
  5. See cmd/genkeys/main.go@78b5f88e4bb734d0dd6a138ff08d34ca39dcaea3
  6. */
  7. import (
  8. "encoding/hex"
  9. "flag"
  10. "log"
  11. "net"
  12. "os"
  13. "regexp"
  14. "runtime"
  15. "github.com/yggdrasil-network/yggdrasil-go/src/address"
  16. "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
  17. )
  18. var version = "v0.1.3"
  19. func main() {
  20. rxflag := flag.String("regex", "::", "regex to match addresses against")
  21. threads := flag.Int("threads", runtime.GOMAXPROCS(0), "how many threads to use for mining")
  22. iterationsPerOutput := flag.Uint("iter", 100000, "per how many iterations to output status")
  23. displayVersion := flag.Bool("version", false, "display version")
  24. origCode := flag.Bool("original", false, "use original Yggdrasil code")
  25. highAddressMode := flag.Bool("highaddr", false, "high address mining mode, excludes regex")
  26. flag.Parse()
  27. if *displayVersion {
  28. println("syg_go", version)
  29. return
  30. }
  31. if *origCode {
  32. log.Println("using unmodified Yggdrasil code")
  33. addrForNodeID = address.AddrForNodeID
  34. } else {
  35. log.Println("using syg_go vendored code")
  36. addrForNodeID = AddrForNodeID
  37. }
  38. regex, err := regexp.Compile(*rxflag)
  39. if err != nil {
  40. log.Printf("%v\n", err)
  41. os.Exit(1)
  42. }
  43. newKeys := make(chan keySet, *threads)
  44. var currentBest []byte
  45. if !*highAddressMode {
  46. log.Printf("starting mining for %v with %v threads\n", regex, *threads)
  47. } else {
  48. log.Printf("starting mining higher addresses with %v threads\n", *threads)
  49. }
  50. for i := 0; i < *threads; i++ {
  51. go doBoxKeys(newKeys)
  52. }
  53. counter := uint64(0)
  54. i := uint64(*iterationsPerOutput)
  55. if !*highAddressMode {
  56. for {
  57. newKey := <-newKeys
  58. if regex.MatchString(newKey.ip) {
  59. newKey.print()
  60. }
  61. counter++
  62. if counter%i == 0 {
  63. log.Printf("reached %v iterations\n", counter)
  64. }
  65. }
  66. } else {
  67. for {
  68. newKey := <-newKeys
  69. if isBetter(currentBest[:], newKey.id) || len(currentBest) == 0 {
  70. currentBest = newKey.id
  71. newKey.print()
  72. }
  73. counter++
  74. if counter%i == 0 {
  75. log.Printf("reached %v iterations\n", counter)
  76. }
  77. }
  78. }
  79. }
  80. type keySet struct {
  81. priv []byte
  82. pub []byte
  83. id []byte
  84. ip string
  85. }
  86. func (k *keySet) print() {
  87. log.Printf("priv: %s | pub: %s | nodeid: %s | ip: %s\n",
  88. hex.EncodeToString(k.priv[:]),
  89. hex.EncodeToString(k.pub[:]),
  90. hex.EncodeToString(k.id[:]),
  91. k.ip)
  92. }
  93. func doBoxKeys(out chan<- keySet) {
  94. for {
  95. pub, priv := crypto.NewBoxKeys()
  96. id := crypto.GetNodeID(pub)
  97. ip := net.IP(addrForNodeID(id)[:]).String()
  98. out <- keySet{priv[:], pub[:], id[:], ip}
  99. }
  100. }
  101. func isBetter(oldID, newID []byte) bool {
  102. for i := range oldID {
  103. if newID[i] > oldID[i] {
  104. return true
  105. }
  106. if newID[i] < oldID[i] {
  107. return false
  108. }
  109. }
  110. return false
  111. }