database_query.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package main
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/hex"
  6. "fmt"
  7. "log"
  8. "time"
  9. "cloud.google.com/go/bigtable"
  10. "google.golang.org/api/option"
  11. )
  12. type Signature struct {
  13. // Index of the validator
  14. Index uint8
  15. // Signature data
  16. Signature [65]byte
  17. }
  18. func printRow(row bigtable.Row) {
  19. if _, ok := row[columnFamilies[0]]; ok {
  20. printItems(row[columnFamilies[0]])
  21. }
  22. if _, ok := row[columnFamilies[1]]; ok {
  23. printItems(row[columnFamilies[1]])
  24. }
  25. if _, ok := row[columnFamilies[2]]; ok {
  26. printSignatures(row[columnFamilies[2]])
  27. }
  28. if _, ok := row[columnFamilies[3]]; ok {
  29. printItems(row[columnFamilies[3]])
  30. }
  31. }
  32. func printItems(familyCols []bigtable.ReadItem) {
  33. for _, item := range familyCols {
  34. log.Printf("\t%s = %s\n", item.Column, string(item.Value))
  35. }
  36. }
  37. func printSignatures(familyCols []bigtable.ReadItem) {
  38. for _, item := range familyCols {
  39. if item.Column == "VAAState:Signatures" {
  40. reader := bytes.NewReader(item.Value[:])
  41. lenSignatures, er := reader.ReadByte()
  42. if er != nil {
  43. log.Print(fmt.Errorf("failed to read signature length"))
  44. return
  45. }
  46. signatures := make([]*Signature, lenSignatures)
  47. for i := 0; i < int(lenSignatures); i++ {
  48. index, err := reader.ReadByte()
  49. if err != nil {
  50. log.Print(fmt.Errorf("failed to read validator index [%d]", i))
  51. return
  52. }
  53. signature := [65]byte{}
  54. if n, err := reader.Read(signature[:]); err != nil || n != 65 {
  55. log.Print(fmt.Errorf("failed to read signature [%d]: %w", i, err))
  56. return
  57. }
  58. signatures[i] = &Signature{
  59. Index: index,
  60. Signature: signature,
  61. }
  62. }
  63. for index, sig := range signatures {
  64. log.Printf("\tSignatures: list index: %v, item index: %v, signature = %s\n", index, sig.Index, hex.EncodeToString(sig.Signature[:]))
  65. }
  66. } else {
  67. log.Printf("\t%s = %s\n", item.Column, string(item.Value))
  68. }
  69. }
  70. }
  71. // Query will lookup BigTable row(s) and log their data.
  72. func Query(project string, instance string, keyFilePath string, rowKey string, previousMinutes int) {
  73. ctx := context.Background()
  74. client, err := bigtable.NewClient(ctx, project, instance, option.WithCredentialsFile(keyFilePath))
  75. if err != nil {
  76. log.Fatalf("Could not create data operations client: %v", err)
  77. }
  78. tbl := client.Open(tableName)
  79. if rowKey != "" {
  80. log.Printf("Querying by row key: %s ", rowKey)
  81. row, err := tbl.ReadRow(ctx, rowKey)
  82. if err != nil {
  83. log.Fatalf("Could not read row with key %s: %v", rowKey, err)
  84. }
  85. printRow(row)
  86. }
  87. if previousMinutes != 0 {
  88. xMinutesAgo := time.Now().Add(-time.Duration(previousMinutes) * time.Minute)
  89. log.Printf("Reading rows from: %v ", xMinutesAgo)
  90. err = tbl.ReadRows(ctx, bigtable.PrefixRange(""), func(row bigtable.Row) bool {
  91. if _, ok := row[columnFamilies[0]]; ok {
  92. // log the rowKey
  93. cell := row[columnFamilies[0]][0]
  94. log.Printf("rowKey: %s", cell.Row)
  95. }
  96. printRow(row)
  97. return true
  98. }, bigtable.RowFilter(bigtable.TimestampRangeFilter(xMinutesAgo, time.Now())))
  99. if err != nil {
  100. log.Fatalf("failed to read recent rows: %v", err)
  101. }
  102. }
  103. if err = client.Close(); err != nil {
  104. log.Fatalf("Could not close data operations client: %v", err)
  105. }
  106. }