lockup.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package processor
  2. import (
  3. "context"
  4. "encoding/hex"
  5. "github.com/mr-tron/base58"
  6. "github.com/prometheus/client_golang/prometheus"
  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/supervisor"
  11. "github.com/certusone/wormhole/node/pkg/vaa"
  12. )
  13. var (
  14. // SECURITY: source_chain/target_chain are untrusted uint8 values. An attacker could cause a maximum of 255**2 label
  15. // pairs to be created, which is acceptable.
  16. lockupsObservedTotal = prometheus.NewCounterVec(
  17. prometheus.CounterOpts{
  18. Name: "wormhole_lockups_observed_total",
  19. Help: "Total number of lockups received on-chain",
  20. },
  21. []string{"source_chain", "target_chain"})
  22. lockupsSignedTotal = prometheus.NewCounterVec(
  23. prometheus.CounterOpts{
  24. Name: "wormhole_lockups_signed_total",
  25. Help: "Total number of lockups that were successfully signed",
  26. },
  27. []string{"source_chain", "target_chain"})
  28. )
  29. func init() {
  30. prometheus.MustRegister(lockupsObservedTotal)
  31. prometheus.MustRegister(lockupsSignedTotal)
  32. }
  33. // handleLockup processes a lockup received from a chain and instantiates our deterministic copy of the VAA. A lockup
  34. // event may be received multiple times until it has been successfully completed.
  35. func (p *Processor) handleLockup(ctx context.Context, k *common.ChainLock) {
  36. supervisor.Logger(ctx).Info("lockup confirmed",
  37. zap.Stringer("source_chain", k.SourceChain),
  38. zap.Stringer("target_chain", k.TargetChain),
  39. zap.Stringer("source_addr", k.SourceAddress),
  40. zap.Stringer("target_addr", k.TargetAddress),
  41. zap.Stringer("token_chain", k.TokenChain),
  42. zap.Stringer("token_addr", k.TokenAddress),
  43. zap.Stringer("amount", k.Amount),
  44. zap.Stringer("txhash", k.TxHash),
  45. zap.Time("timestamp", k.Timestamp),
  46. )
  47. lockupsObservedTotal.With(prometheus.Labels{
  48. "source_chain": k.SourceChain.String(),
  49. "target_chain": k.TargetChain.String()}).Add(1)
  50. // All nodes will create the exact same VAA and sign its digest.
  51. // Consensus is established on this digest.
  52. v := &vaa.VAA{
  53. Version: vaa.SupportedVAAVersion,
  54. GuardianSetIndex: p.gs.Index,
  55. Signatures: nil,
  56. Timestamp: k.Timestamp,
  57. Payload: &vaa.BodyTransfer{
  58. Nonce: k.Nonce,
  59. SourceChain: k.SourceChain,
  60. TargetChain: k.TargetChain,
  61. SourceAddress: k.SourceAddress,
  62. TargetAddress: k.TargetAddress,
  63. Asset: &vaa.AssetMeta{
  64. Chain: k.TokenChain,
  65. Address: k.TokenAddress,
  66. Decimals: k.TokenDecimals,
  67. },
  68. Amount: k.Amount,
  69. },
  70. }
  71. // Generate digest of the unsigned VAA.
  72. digest, err := v.SigningMsg()
  73. if err != nil {
  74. panic(err)
  75. }
  76. // Sign the digest using our node's guardian key.
  77. s, err := crypto.Sign(digest.Bytes(), p.gk)
  78. if err != nil {
  79. panic(err)
  80. }
  81. p.logger.Info("observed and signed confirmed lockup",
  82. zap.Stringer("source_chain", k.SourceChain),
  83. zap.Stringer("target_chain", k.TargetChain),
  84. zap.Stringer("txhash", k.TxHash),
  85. zap.String("txhash_b58", base58.Encode(k.TxHash.Bytes())),
  86. zap.String("digest", hex.EncodeToString(digest.Bytes())),
  87. zap.String("signature", hex.EncodeToString(s)))
  88. lockupsSignedTotal.With(prometheus.Labels{
  89. "source_chain": k.SourceChain.String(),
  90. "target_chain": k.TargetChain.String()}).Add(1)
  91. p.broadcastSignature(v, s, k.TxHash.Bytes())
  92. }