database_query.go 3.0 KB

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