|
|
@@ -3,6 +3,7 @@ package guardiand
|
|
|
import (
|
|
|
"context"
|
|
|
"encoding/base64"
|
|
|
+ "encoding/hex"
|
|
|
"fmt"
|
|
|
"github.com/certusone/wormhole/node/pkg/db"
|
|
|
"github.com/certusone/wormhole/node/pkg/notify/discord"
|
|
|
@@ -521,7 +522,7 @@ func runNode(cmd *cobra.Command, args []string) {
|
|
|
// Inbound signed VAAs
|
|
|
signedInC := make(chan *gossipv1.SignedVAAWithQuorum, 50)
|
|
|
|
|
|
- // Inbound observation requests
|
|
|
+ // Inbound observation requests from the p2p service (for all chains)
|
|
|
obsvReqC := make(chan *gossipv1.ObservationRequest, 50)
|
|
|
|
|
|
// Outbound observation requests
|
|
|
@@ -533,6 +534,38 @@ func runNode(cmd *cobra.Command, args []string) {
|
|
|
// Guardian set state managed by processor
|
|
|
gst := common.NewGuardianSetState()
|
|
|
|
|
|
+ // Per-chain observation requests
|
|
|
+ chainObsvReqC := make(map[vaa.ChainID]chan *gossipv1.ObservationRequest)
|
|
|
+
|
|
|
+ // Observation request channel for each chain supporting observation requests.
|
|
|
+ chainObsvReqC[vaa.ChainIDSolana] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ chainObsvReqC[vaa.ChainIDEthereum] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ chainObsvReqC[vaa.ChainIDBSC] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ chainObsvReqC[vaa.ChainIDPolygon] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ chainObsvReqC[vaa.ChainIDAvalanche] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ chainObsvReqC[vaa.ChainIDOasis] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ if *testnetMode {
|
|
|
+ chainObsvReqC[vaa.ChainIDEthereumRopsten] = make(chan *gossipv1.ObservationRequest)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Multiplex observation requests to the appropriate chain
|
|
|
+ go func() {
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case <-rootCtx.Done():
|
|
|
+ return
|
|
|
+ case req := <-obsvReqC:
|
|
|
+ if channel, ok := chainObsvReqC[vaa.ChainID(req.ChainId)]; ok {
|
|
|
+ channel <- req
|
|
|
+ } else {
|
|
|
+ logger.Error("unknown chain ID for reobservation request",
|
|
|
+ zap.Uint32("chain_id", req.ChainId),
|
|
|
+ zap.String("tx_hash", hex.EncodeToString(req.TxHash)))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
var notifier *discord.DiscordNotifier
|
|
|
if *discordToken != "" {
|
|
|
notifier, err = discord.NewDiscordNotifier(*discordToken, *discordChannel, logger)
|
|
|
@@ -624,38 +657,36 @@ func runNode(cmd *cobra.Command, args []string) {
|
|
|
}
|
|
|
|
|
|
if err := supervisor.Run(ctx, "ethwatch",
|
|
|
- ethereum.NewEthWatcher(*ethRPC, ethContractAddr, "eth", common.ReadinessEthSyncing, vaa.ChainIDEthereum, lockC, setC, 1).Run); err != nil {
|
|
|
+ ethereum.NewEthWatcher(*ethRPC, ethContractAddr, "eth", common.ReadinessEthSyncing, vaa.ChainIDEthereum, lockC, setC, 1, chainObsvReqC[vaa.ChainIDEthereum]).Run); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
if err := supervisor.Run(ctx, "bscwatch",
|
|
|
- ethereum.NewEthWatcher(*bscRPC, bscContractAddr, "bsc", common.ReadinessBSCSyncing, vaa.ChainIDBSC, lockC, nil, 1).Run); err != nil {
|
|
|
+ ethereum.NewEthWatcher(*bscRPC, bscContractAddr, "bsc", common.ReadinessBSCSyncing, vaa.ChainIDBSC, lockC, nil, 1, chainObsvReqC[vaa.ChainIDBSC]).Run); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
if err := supervisor.Run(ctx, "polygonwatch",
|
|
|
- ethereum.NewEthWatcher(
|
|
|
- *polygonRPC, polygonContractAddr, "polygon", common.ReadinessPolygonSyncing, vaa.ChainIDPolygon, lockC, nil,
|
|
|
- // Special case: Polygon can fork like PoW Ethereum, and it's not clear what the safe number of blocks is
|
|
|
- //
|
|
|
- // Hardcode the minimum number of confirmations to 512 regardless of what the smart contract specifies to protect
|
|
|
- // developers from accidentally specifying an unsafe number of confirmations. We can remove this restriction as soon
|
|
|
- // as specific public guidance exists for Polygon developers.
|
|
|
- 512).Run); err != nil {
|
|
|
+ ethereum.NewEthWatcher(*polygonRPC, polygonContractAddr, "polygon", common.ReadinessPolygonSyncing, vaa.ChainIDPolygon, lockC, nil, 512, chainObsvReqC[vaa.ChainIDPolygon]).Run); err != nil {
|
|
|
+ // Special case: Polygon can fork like PoW Ethereum, and it's not clear what the safe number of blocks is
|
|
|
+ //
|
|
|
+ // Hardcode the minimum number of confirmations to 512 regardless of what the smart contract specifies to protect
|
|
|
+ // developers from accidentally specifying an unsafe number of confirmations. We can remove this restriction as soon
|
|
|
+ // as specific public guidance exists for Polygon developers.
|
|
|
return err
|
|
|
}
|
|
|
if err := supervisor.Run(ctx, "avalanchewatch",
|
|
|
- ethereum.NewEthWatcher(*avalancheRPC, avalancheContractAddr, "avalanche", common.ReadinessAvalancheSyncing, vaa.ChainIDAvalanche, lockC, nil, 1).Run); err != nil {
|
|
|
+ ethereum.NewEthWatcher(*avalancheRPC, avalancheContractAddr, "avalanche", common.ReadinessAvalancheSyncing, vaa.ChainIDAvalanche, lockC, nil, 1, chainObsvReqC[vaa.ChainIDAvalanche]).Run); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if err := supervisor.Run(ctx, "oasiswatch",
|
|
|
- ethereum.NewEthWatcher(*oasisRPC, oasisContractAddr, "oasis", common.ReadinessOasisSyncing, vaa.ChainIDOasis, lockC, nil, 1).Run); err != nil {
|
|
|
+ ethereum.NewEthWatcher(*oasisRPC, oasisContractAddr, "oasis", common.ReadinessOasisSyncing, vaa.ChainIDOasis, lockC, nil, 1, chainObsvReqC[vaa.ChainIDOasis]).Run); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
if *testnetMode {
|
|
|
if err := supervisor.Run(ctx, "ethropstenwatch",
|
|
|
- ethereum.NewEthWatcher(*ethRopstenRPC, ethRopstenContractAddr, "ethropsten", common.ReadinessEthRopstenSyncing, vaa.ChainIDEthereumRopsten, lockC, setC, 1).Run); err != nil {
|
|
|
+ ethereum.NewEthWatcher(*ethRopstenRPC, ethRopstenContractAddr, "ethropsten", common.ReadinessEthRopstenSyncing, vaa.ChainIDEthereumRopsten, lockC, setC, 1, chainObsvReqC[vaa.ChainIDEthereumRopsten]).Run); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
|
@@ -680,7 +711,7 @@ func runNode(cmd *cobra.Command, args []string) {
|
|
|
}
|
|
|
|
|
|
if err := supervisor.Run(ctx, "solwatch-finalized",
|
|
|
- solana.NewSolanaWatcher(*solanaWsRPC, *solanaRPC, solAddress, lockC, obsvReqC, rpc.CommitmentFinalized).Run); err != nil {
|
|
|
+ solana.NewSolanaWatcher(*solanaWsRPC, *solanaRPC, solAddress, lockC, chainObsvReqC[vaa.ChainIDSolana], rpc.CommitmentFinalized).Run); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|