package processor import ( "encoding/hex" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "time" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "google.golang.org/protobuf/proto" gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" "github.com/certusone/wormhole/node/pkg/vaa" ) var ( observationsBroadcastTotal = promauto.NewCounter( prometheus.CounterOpts{ Name: "wormhole_observations_broadcast_total", Help: "Total number of signed observations queued for broadcast", }) ) func (p *Processor) broadcastSignature(v *vaa.VAA, signature []byte) { digest, err := v.SigningMsg() if err != nil { panic(err) } obsv := gossipv1.SignedObservation{ Addr: crypto.PubkeyToAddress(p.gk.PublicKey).Bytes(), Hash: digest.Bytes(), Signature: signature, } w := gossipv1.GossipMessage{Message: &gossipv1.GossipMessage_SignedObservation{SignedObservation: &obsv}} msg, err := proto.Marshal(&w) if err != nil { panic(err) } p.sendC <- msg // Store our VAA in case we're going to submit it to Solana hash := hex.EncodeToString(digest.Bytes()) if p.state.vaaSignatures[hash] == nil { p.state.vaaSignatures[hash] = &vaaState{ firstObserved: time.Now(), signatures: map[ethcommon.Address][]byte{}, source: "loopback", } } p.state.vaaSignatures[hash].ourVAA = v p.state.vaaSignatures[hash].ourMsg = msg p.state.vaaSignatures[hash].gs = p.gs // guaranteed to match ourVAA - there's no concurrent access to p.gs // Fast path for our own signature go func() { p.obsvC <- &obsv }() observationsBroadcastTotal.Inc() }