shared.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package p
  2. import (
  3. "context"
  4. "log"
  5. "net/http"
  6. "os"
  7. "sync"
  8. "cloud.google.com/go/bigtable"
  9. "github.com/certusone/wormhole/node/pkg/vaa"
  10. )
  11. // shared code for the various functions, primarily response formatting.
  12. // client is a global Bigtable client, to avoid initializing a new client for
  13. // every request.
  14. var client *bigtable.Client
  15. var clientOnce sync.Once
  16. var tbl *bigtable.Table
  17. // init runs during cloud function initialization. So, this will only run during an
  18. // an instance's cold start.
  19. // https://cloud.google.com/functions/docs/bestpractices/networking#accessing_google_apis
  20. func init() {
  21. clientOnce.Do(func() {
  22. // Declare a separate err variable to avoid shadowing client.
  23. var err error
  24. project := os.Getenv("GCP_PROJECT")
  25. instance := os.Getenv("BIGTABLE_INSTANCE")
  26. client, err = bigtable.NewClient(context.Background(), project, instance)
  27. if err != nil {
  28. // http.Error(w, "Error initializing client", http.StatusInternalServerError)
  29. log.Printf("bigtable.NewClient error: %v", err)
  30. return
  31. }
  32. })
  33. tbl = client.Open("v2Events")
  34. }
  35. var columnFamilies = []string{"MessagePublication", "Signatures", "VAAState", "QuorumState"}
  36. type (
  37. Summary struct {
  38. EmitterChain string
  39. EmitterAddress string
  40. Sequence string
  41. InitiatingTxID string
  42. Payload []byte
  43. SignedVAABytes []byte
  44. QuorumTime string
  45. }
  46. // Details is a Summary, with the VAA decoded as SignedVAA
  47. Details struct {
  48. SignedVAA *vaa.VAA
  49. EmitterChain string
  50. EmitterAddress string
  51. Sequence string
  52. InitiatingTxID string
  53. Payload []byte
  54. SignedVAABytes []byte
  55. QuorumTime string
  56. }
  57. )
  58. func makeSummary(row bigtable.Row) *Summary {
  59. summary := &Summary{}
  60. if _, ok := row[columnFamilies[0]]; ok {
  61. for _, item := range row[columnFamilies[0]] {
  62. switch item.Column {
  63. case "MessagePublication:InitiatingTxID":
  64. summary.InitiatingTxID = string(item.Value)
  65. case "MessagePublication:Payload":
  66. summary.Payload = item.Value
  67. case "MessagePublication:EmitterChain":
  68. summary.EmitterChain = string(item.Value)
  69. case "MessagePublication:EmitterAddress":
  70. summary.EmitterAddress = string(item.Value)
  71. case "MessagePublication:Sequence":
  72. summary.Sequence = string(item.Value)
  73. }
  74. }
  75. }
  76. if _, ok := row[columnFamilies[3]]; ok {
  77. item := row[columnFamilies[3]][0]
  78. summary.SignedVAABytes = item.Value
  79. summary.QuorumTime = item.Timestamp.Time().String()
  80. }
  81. return summary
  82. }
  83. func makeDetails(row bigtable.Row) *Details {
  84. sum := makeSummary(row)
  85. deets := &Details{
  86. EmitterChain: sum.EmitterChain,
  87. EmitterAddress: sum.EmitterAddress,
  88. Sequence: sum.Sequence,
  89. InitiatingTxID: sum.InitiatingTxID,
  90. Payload: sum.Payload,
  91. SignedVAABytes: sum.SignedVAABytes,
  92. QuorumTime: sum.QuorumTime,
  93. }
  94. if _, ok := row[columnFamilies[3]]; ok {
  95. item := row[columnFamilies[3]][0]
  96. deets.SignedVAA, _ = vaa.Unmarshal(item.Value)
  97. }
  98. return deets
  99. }
  100. var mux = newMux()
  101. // Entry is the cloud function entry point
  102. func Entry(w http.ResponseWriter, r *http.Request) {
  103. mux.ServeHTTP(w, r)
  104. }
  105. func newMux() *http.ServeMux {
  106. mux := http.NewServeMux()
  107. mux.HandleFunc("/totals", Totals)
  108. mux.HandleFunc("/recent", Recent)
  109. mux.HandleFunc("/transaction", Transaction)
  110. mux.HandleFunc("/readrow", ReadRow)
  111. mux.HandleFunc("/readyz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
  112. return mux
  113. }