diff --git a/bridge/cmd/guardiand/bridge.go b/bridge/cmd/guardiand/bridge.go index 3376fcb30..b2b65503d 100644 --- a/bridge/cmd/guardiand/bridge.go +++ b/bridge/cmd/guardiand/bridge.go @@ -80,6 +80,8 @@ var ( publicRPC *string publicREST *string + disableHeartbeatVerify *bool + bigTablePersistenceEnabled *bool bigTableGCPProject *string bigTableInstanceName *string @@ -126,6 +128,9 @@ func init() { publicRPC = BridgeCmd.Flags().String("publicRPC", "", "Listen address for public gRPC interface") publicREST = BridgeCmd.Flags().String("publicREST", "", "Listen address for public REST interface") + disableHeartbeatVerify = BridgeCmd.Flags().Bool("disableHeartbeatVerify", false, + "Disable heartbeat signature verification (useful during network startup)") + bigTablePersistenceEnabled = BridgeCmd.Flags().Bool("bigTablePersistenceEnabled", false, "Turn on forwarding events to BigTable") bigTableGCPProject = BridgeCmd.Flags().String("bigTableGCPProject", "", "Google Cloud project ID for storing events") bigTableInstanceName = BridgeCmd.Flags().String("bigTableInstanceName", "", "BigTable instance name for storing events") @@ -440,7 +445,7 @@ func runBridge(cmd *cobra.Command, args []string) { // Run supervisor. supervisor.New(rootCtx, logger, func(ctx context.Context) error { if err := supervisor.Run(ctx, "p2p", p2p.Run( - obsvC, sendC, rawHeartbeatListeners, priv, gk, gst, *p2pPort, *p2pNetworkID, *p2pBootstrap, *nodeName, rootCtxCancel)); err != nil { + obsvC, sendC, rawHeartbeatListeners, priv, gk, gst, *p2pPort, *p2pNetworkID, *p2pBootstrap, *nodeName, *disableHeartbeatVerify, rootCtxCancel)); err != nil { return err } diff --git a/bridge/pkg/p2p/p2p.go b/bridge/pkg/p2p/p2p.go index dc4f94f97..d7cc81809 100644 --- a/bridge/pkg/p2p/p2p.go +++ b/bridge/pkg/p2p/p2p.go @@ -59,7 +59,7 @@ func heartbeatDigest(b []byte) common.Hash { return ethcrypto.Keccak256Hash(append(heartbeatMessagePrefix, b...)) } -func Run(obsvC chan *gossipv1.SignedObservation, sendC chan []byte, rawHeartbeatListeners *publicrpc.RawHeartbeatConns, priv crypto.PrivKey, gk *ecdsa.PrivateKey, gst *bridge_common.GuardianSetState, port uint, networkID string, bootstrapPeers string, nodeName string, rootCtxCancel context.CancelFunc) func(ctx context.Context) error { +func Run(obsvC chan *gossipv1.SignedObservation, sendC chan []byte, rawHeartbeatListeners *publicrpc.RawHeartbeatConns, priv crypto.PrivKey, gk *ecdsa.PrivateKey, gst *bridge_common.GuardianSetState, port uint, networkID string, bootstrapPeers string, nodeName string, disableHeartbeatVerify bool, rootCtxCancel context.CancelFunc) func(ctx context.Context) error { return func(ctx context.Context) (re error) { logger := supervisor.Logger(ctx) @@ -301,7 +301,7 @@ func Run(obsvC chan *gossipv1.SignedObservation, sendC chan []byte, rawHeartbeat zap.String("from", envelope.GetFrom().String())) break } - if heartbeat, err := processSignedHeartbeat(s, gs, gst); err != nil { + if heartbeat, err := processSignedHeartbeat(s, gs, gst, disableHeartbeatVerify); err != nil { p2pMessagesReceived.WithLabelValues("invalid_heartbeat").Inc() logger.Warn("invalid signed heartbeat received", zap.Error(err), @@ -330,15 +330,18 @@ func Run(obsvC chan *gossipv1.SignedObservation, sendC chan []byte, rawHeartbeat } } -func processSignedHeartbeat(s *gossipv1.SignedHeartbeat, gs *bridge_common.GuardianSet, gst *bridge_common.GuardianSetState) (*gossipv1.Heartbeat, error) { +func processSignedHeartbeat(s *gossipv1.SignedHeartbeat, gs *bridge_common.GuardianSet, gst *bridge_common.GuardianSetState, disableVerify bool) (*gossipv1.Heartbeat, error) { envelopeAddr := common.BytesToAddress(s.GuardianAddr) idx, ok := gs.KeyIndex(envelopeAddr) + var pk common.Address if !ok { - return nil, fmt.Errorf("invalid message: %s not in guardian set", envelopeAddr) + if !disableVerify { + return nil, fmt.Errorf("invalid message: %s not in guardian set", envelopeAddr) + } + } else { + pk = gs.Keys[idx] } - pk := gs.Keys[idx] - digest := heartbeatDigest(s.Heartbeat) pubKey, err := ethcrypto.Ecrecover(digest.Bytes(), s.Signature) @@ -347,7 +350,7 @@ func processSignedHeartbeat(s *gossipv1.SignedHeartbeat, gs *bridge_common.Guard } signerAddr := common.BytesToAddress(ethcrypto.Keccak256(pubKey[1:])[12:]) - if pk != signerAddr { + if pk != signerAddr && !disableVerify { return nil, fmt.Errorf("invalid signer: %v", signerAddr) }