wormhole/event_database/database_query.go

126 lines
3.1 KiB
Go

package main
import (
"bytes"
"context"
"encoding/hex"
"fmt"
"log"
"time"
"cloud.google.com/go/bigtable"
"google.golang.org/api/option"
)
type Signature struct {
// Index of the validator
Index uint8
// Signature data
Signature [65]byte
}
func printRow(row bigtable.Row) {
if _, ok := row[columnFamilies[0]]; ok {
printItems(row[columnFamilies[0]])
}
if _, ok := row[columnFamilies[1]]; ok {
printItems(row[columnFamilies[1]])
}
if _, ok := row[columnFamilies[2]]; ok {
printSignatures(row[columnFamilies[2]])
}
if _, ok := row[columnFamilies[3]]; ok {
printItems(row[columnFamilies[3]])
}
}
func printItems(familyCols []bigtable.ReadItem) {
for _, item := range familyCols {
log.Printf("\t%s = %s\n", item.Column, string(item.Value))
}
}
func printSignatures(familyCols []bigtable.ReadItem) {
for _, item := range familyCols {
if item.Column == "VAAState:Signatures" {
reader := bytes.NewReader(item.Value[:])
lenSignatures, er := reader.ReadByte()
if er != nil {
log.Print(fmt.Errorf("failed to read signature length"))
return
}
signatures := make([]*Signature, lenSignatures)
for i := 0; i < int(lenSignatures); i++ {
index, err := reader.ReadByte()
if err != nil {
log.Print(fmt.Errorf("failed to read validator index [%d]", i))
return
}
signature := [65]byte{}
if n, err := reader.Read(signature[:]); err != nil || n != 65 {
log.Print(fmt.Errorf("failed to read signature [%d]: %w", i, err))
return
}
signatures[i] = &Signature{
Index: index,
Signature: signature,
}
}
for index, sig := range signatures {
log.Printf("\tSignatures: list index: %v, item index: %v, signature = %s\n", index, sig.Index, hex.EncodeToString(sig.Signature[:]))
}
} else {
log.Printf("\t%s = %s\n", item.Column, string(item.Value))
}
}
}
// Query will lookup BigTable row(s) and log their data.
func Query(project string, instance string, keyFilePath string, rowKey string, previousMinutes int) {
ctx := context.Background()
client, err := bigtable.NewClient(ctx, project, instance, option.WithCredentialsFile(keyFilePath))
if err != nil {
log.Fatalf("Could not create data operations client: %v", err)
}
tbl := client.Open(tableName)
if rowKey != "" {
log.Printf("Querying by row key: %s ", rowKey)
row, err := tbl.ReadRow(ctx, rowKey)
if err != nil {
log.Fatalf("Could not read row with key %s: %v", rowKey, err)
}
printRow(row)
}
if previousMinutes != 0 {
xMinutesAgo := time.Now().Add(-time.Duration(previousMinutes) * time.Minute)
log.Printf("Reading rows from: %v ", xMinutesAgo)
err = tbl.ReadRows(ctx, bigtable.PrefixRange(""), func(row bigtable.Row) bool {
if _, ok := row[columnFamilies[0]]; ok {
// log the rowKey
cell := row[columnFamilies[0]][0]
log.Printf("rowKey: %s", cell.Row)
}
printRow(row)
return true
}, bigtable.RowFilter(bigtable.TimestampRangeFilter(xMinutesAgo, time.Now())))
if err != nil {
log.Fatalf("failed to read recent rows: %v", err)
}
}
if err = client.Close(); err != nil {
log.Fatalf("Could not close data operations client: %v", err)
}
}