message.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package processor
  2. import (
  3. "context"
  4. "encoding/hex"
  5. "github.com/prometheus/client_golang/prometheus"
  6. "github.com/prometheus/client_golang/prometheus/promauto"
  7. "github.com/ethereum/go-ethereum/crypto"
  8. "go.uber.org/zap"
  9. "github.com/certusone/wormhole/node/pkg/common"
  10. "github.com/certusone/wormhole/node/pkg/reporter"
  11. "github.com/certusone/wormhole/node/pkg/supervisor"
  12. "github.com/certusone/wormhole/node/pkg/vaa"
  13. )
  14. var (
  15. // SECURITY: source_chain/target_chain are untrusted uint8 values. An attacker could cause a maximum of 255**2 label
  16. // pairs to be created, which is acceptable.
  17. messagesObservedTotal = promauto.NewCounterVec(
  18. prometheus.CounterOpts{
  19. Name: "wormhole_message_observations_total",
  20. Help: "Total number of messages observed",
  21. },
  22. []string{"emitter_chain"})
  23. messagesSignedTotal = promauto.NewCounterVec(
  24. prometheus.CounterOpts{
  25. Name: "wormhole_message_observations_signed_total",
  26. Help: "Total number of message observations that were successfully signed",
  27. },
  28. []string{"emitter_chain"})
  29. )
  30. // handleMessage processes a message received from a chain and instantiates our deterministic copy of the VAA. An
  31. // event may be received multiple times and must be handled in an idempotent fashion.
  32. func (p *Processor) handleMessage(ctx context.Context, k *common.MessagePublication) {
  33. supervisor.Logger(ctx).Info("message publication confirmed",
  34. zap.Stringer("emitter_chain", k.EmitterChain),
  35. zap.Stringer("emitter_address", k.EmitterAddress),
  36. zap.Uint32("nonce", k.Nonce),
  37. zap.Stringer("txhash", k.TxHash),
  38. zap.Time("timestamp", k.Timestamp),
  39. )
  40. messagesObservedTotal.With(prometheus.Labels{
  41. "emitter_chain": k.EmitterChain.String(),
  42. }).Add(1)
  43. // All nodes will create the exact same VAA and sign its digest.
  44. // Consensus is established on this digest.
  45. v := &vaa.VAA{
  46. Version: vaa.SupportedVAAVersion,
  47. GuardianSetIndex: p.gs.Index,
  48. Signatures: nil,
  49. Timestamp: k.Timestamp,
  50. Nonce: k.Nonce,
  51. EmitterChain: k.EmitterChain,
  52. EmitterAddress: k.EmitterAddress,
  53. Payload: k.Payload,
  54. Sequence: k.Sequence,
  55. ConsistencyLevel: k.ConsistencyLevel,
  56. }
  57. // Generate digest of the unsigned VAA.
  58. digest, err := v.SigningMsg()
  59. if err != nil {
  60. panic(err)
  61. }
  62. // Sign the digest using our node's guardian key.
  63. s, err := crypto.Sign(digest.Bytes(), p.gk)
  64. if err != nil {
  65. panic(err)
  66. }
  67. p.logger.Info("observed and signed confirmed message publication",
  68. zap.Stringer("source_chain", k.EmitterChain),
  69. zap.Stringer("txhash", k.TxHash),
  70. zap.String("digest", hex.EncodeToString(digest.Bytes())),
  71. zap.String("signature", hex.EncodeToString(s)))
  72. messagesSignedTotal.With(prometheus.Labels{
  73. "emitter_chain": k.EmitterChain.String()}).Add(1)
  74. p.attestationEvents.ReportMessagePublication(&reporter.MessagePublication{VAA: *v, InitiatingTxID: k.TxHash})
  75. p.broadcastSignature(v, s)
  76. }