2020-10-28 14:41:38 -07:00
package guardiand
2020-08-02 14:12:58 -07:00
import (
"context"
2022-01-09 12:56:59 -08:00
"encoding/base64"
2020-08-02 14:12:58 -07:00
"fmt"
2022-05-23 02:25:24 -07:00
"log"
2023-06-14 13:39:30 -07:00
"net"
2022-05-23 02:25:24 -07:00
_ "net/http/pprof" // #nosec G108 we are using a custom router (`router := mux.NewRouter()`) and thus not automatically expose pprof.
"os"
2022-11-28 05:48:27 -08:00
"os/signal"
2022-05-23 02:25:24 -07:00
"path"
2023-05-23 12:59:01 -07:00
"runtime"
2022-05-23 02:25:24 -07:00
"strings"
2022-11-28 05:48:27 -08:00
"syscall"
2023-06-14 13:39:30 -07:00
"time"
2022-05-23 02:25:24 -07:00
2023-05-24 14:23:42 -07:00
"github.com/certusone/wormhole/node/pkg/watchers"
"github.com/certusone/wormhole/node/pkg/watchers/ibc"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
2022-09-28 06:27:13 -07:00
"github.com/certusone/wormhole/node/pkg/watchers/cosmwasm"
"github.com/certusone/wormhole/node/pkg/watchers/algorand"
2022-10-13 18:22:54 -07:00
"github.com/certusone/wormhole/node/pkg/watchers/aptos"
2022-09-28 06:27:13 -07:00
"github.com/certusone/wormhole/node/pkg/watchers/evm"
"github.com/certusone/wormhole/node/pkg/watchers/near"
"github.com/certusone/wormhole/node/pkg/watchers/solana"
2022-11-18 06:14:22 -08:00
"github.com/certusone/wormhole/node/pkg/watchers/sui"
2023-01-16 04:33:01 -08:00
"github.com/certusone/wormhole/node/pkg/wormconn"
2022-09-28 04:15:57 -07:00
2021-12-02 16:02:32 -08:00
"github.com/certusone/wormhole/node/pkg/db"
2022-01-09 12:56:59 -08:00
"github.com/certusone/wormhole/node/pkg/telemetry"
"github.com/certusone/wormhole/node/pkg/version"
2021-12-02 16:02:32 -08:00
"github.com/gagliardetto/solana-go/rpc"
2022-01-06 08:58:56 -08:00
"go.uber.org/zap/zapcore"
2021-08-06 21:28:46 -07:00
2021-08-26 01:35:09 -07:00
"github.com/certusone/wormhole/node/pkg/common"
"github.com/certusone/wormhole/node/pkg/devnet"
2023-05-24 12:59:05 -07:00
"github.com/certusone/wormhole/node/pkg/node"
2021-08-26 01:35:09 -07:00
"github.com/certusone/wormhole/node/pkg/p2p"
"github.com/certusone/wormhole/node/pkg/supervisor"
2023-05-24 14:23:42 -07:00
libp2p_crypto "github.com/libp2p/go-libp2p/core/crypto"
2022-09-05 20:36:58 -07:00
"github.com/libp2p/go-libp2p/core/peer"
2021-12-02 16:02:32 -08:00
"github.com/spf13/cobra"
2022-08-18 01:52:36 -07:00
"github.com/wormhole-foundation/wormhole/sdk/vaa"
2021-12-02 16:02:32 -08:00
"go.uber.org/zap"
2021-08-26 01:35:09 -07:00
2020-08-02 14:12:58 -07:00
ipfslog "github.com/ipfs/go-log/v2"
2023-05-23 12:53:26 -07:00
googleapi_option "google.golang.org/api/option"
2020-08-02 14:12:58 -07:00
)
var (
2020-10-28 14:41:38 -07:00
p2pNetworkID * string
p2pPort * uint
p2pBootstrap * string
2020-08-16 08:05:58 -07:00
2020-10-28 14:41:38 -07:00
nodeKeyPath * string
2020-08-16 08:05:58 -07:00
2022-11-18 07:36:22 -08:00
adminSocketPath * string
publicGRPCSocketPath * string
2020-11-19 03:53:19 -08:00
2021-07-21 11:56:25 -07:00
dataDir * string
2021-01-24 08:20:04 -08:00
statusAddr * string
2021-08-30 07:19:00 -07:00
guardianKeyPath * string
solanaContract * string
2020-11-19 03:53:17 -08:00
2021-07-09 05:56:52 -07:00
ethRPC * string
ethContract * string
2020-08-16 08:05:58 -07:00
2021-07-28 06:32:49 -07:00
bscRPC * string
bscContract * string
2022-11-11 06:12:16 -08:00
polygonRPC * string
polygonContract * string
polygonRootChainRpc * string
polygonRootChainContractAddress * string
2021-10-18 08:53:13 -07:00
2022-03-15 07:41:10 -07:00
auroraRPC * string
auroraContract * string
2022-03-03 13:40:32 -08:00
fantomRPC * string
fantomContract * string
2022-02-02 09:50:10 -08:00
2021-12-09 13:40:55 -08:00
avalancheRPC * string
avalancheContract * string
2021-12-20 11:40:58 -08:00
oasisRPC * string
oasisContract * string
2022-03-03 13:40:32 -08:00
karuraRPC * string
karuraContract * string
acalaRPC * string
acalaContract * string
2022-04-04 15:11:03 -07:00
klaytnRPC * string
klaytnContract * string
2022-04-28 09:20:38 -07:00
celoRPC * string
celoContract * string
2022-05-10 08:23:07 -07:00
moonbeamRPC * string
moonbeamContract * string
2022-06-14 07:22:49 -07:00
neonRPC * string
neonContract * string
2020-11-16 04:28:07 -08:00
terraWS * string
terraLCD * string
terraContract * string
2022-06-16 12:17:43 -07:00
terra2WS * string
terra2LCD * string
terra2Contract * string
2022-07-06 07:19:57 -07:00
injectiveWS * string
injectiveLCD * string
injectiveContract * string
2022-10-05 06:05:31 -07:00
xplaWS * string
xplaLCD * string
xplaContract * string
2023-08-14 08:13:20 -07:00
gatewayWS * string
gatewayLCD * string
gatewayContract * string
2022-04-29 12:56:08 -07:00
algorandIndexerRPC * string
algorandIndexerToken * string
2022-05-10 04:41:59 -07:00
algorandAlgodRPC * string
algorandAlgodToken * string
2022-05-10 08:23:07 -07:00
algorandAppID * uint64
2021-12-22 08:22:04 -08:00
2022-08-05 10:49:16 -07:00
nearRPC * string
nearContract * string
2023-01-16 04:33:01 -08:00
wormchainURL * string
wormchainKeyPath * string
2023-01-17 05:30:50 -08:00
wormchainKeyPassPhrase * string
2023-01-16 04:33:01 -08:00
2023-04-17 07:54:36 -07:00
ibcWS * string
ibcLCD * string
ibcContract * string
2023-08-22 12:49:49 -07:00
accountantContract * string
accountantWS * string
accountantCheckEnabled * bool
accountantKeyPath * string
accountantKeyPassPhrase * string
2022-09-02 01:36:24 -07:00
2022-10-13 18:22:54 -07:00
aptosRPC * string
aptosAccount * string
aptosHandle * string
2023-04-17 10:56:52 -07:00
suiRPC * string
suiWS * string
suiMoveEventType * string
2022-11-18 06:14:22 -08:00
2022-09-26 06:56:39 -07:00
solanaRPC * string
2021-01-21 02:31:32 -08:00
2022-07-28 10:30:00 -07:00
pythnetContract * string
pythnetRPC * string
2023-01-18 08:24:55 -08:00
pythnetWS * string
2022-07-28 10:30:00 -07:00
2022-09-28 07:39:58 -07:00
arbitrumRPC * string
arbitrumContract * string
2023-06-12 10:41:29 -07:00
optimismRPC * string
optimismContract * string
2022-11-10 05:50:08 -08:00
2023-02-23 15:37:35 -08:00
baseRPC * string
baseContract * string
2023-04-03 07:24:17 -07:00
sepoliaRPC * string
sepoliaContract * string
2023-03-01 07:10:04 -08:00
logLevel * string
publicRpcLogDetailStr * string
publicRpcLogToTelemetry * bool
2020-08-17 09:20:15 -07:00
2023-03-03 07:14:39 -08:00
unsafeDevMode * bool
testnetMode * bool
nodeName * string
2021-05-12 22:57:08 -07:00
2021-08-20 16:52:07 -07:00
publicRPC * string
publicWeb * string
2021-07-07 02:39:48 -07:00
2021-08-20 15:44:37 -07:00
tlsHostname * string
tlsProdEnv * bool
2021-08-05 08:01:36 -07:00
disableHeartbeatVerify * bool
2022-01-09 12:56:59 -08:00
2023-07-12 12:51:01 -07:00
disableTelemetry * bool
// Google cloud logging parameters
2023-05-23 12:53:26 -07:00
telemetryKey * string
telemetryServiceAccountFile * string
telemetryProject * string
2021-08-05 08:01:36 -07:00
2023-07-12 12:51:01 -07:00
// Loki cloud logging parameters
telemetryLokiURL * string
2022-07-19 11:08:06 -07:00
chainGovernorEnabled * bool
2023-08-03 08:26:50 -07:00
2023-10-12 11:20:42 -07:00
ccqEnabled * bool
ccqAllowedRequesters * string
ccqP2pPort * uint
ccqP2pBootstrap * string
ccqAllowedPeers * string
2023-08-03 08:26:50 -07:00
gatewayRelayerContract * string
gatewayRelayerKeyPath * string
gatewayRelayerKeyPassPhrase * string
2020-08-02 14:12:58 -07:00
)
2020-10-28 14:41:38 -07:00
func init ( ) {
2021-08-30 07:19:00 -07:00
p2pNetworkID = NodeCmd . Flags ( ) . String ( "network" , "/wormhole/dev" , "P2P network identifier" )
2023-02-23 15:51:27 -08:00
p2pPort = NodeCmd . Flags ( ) . Uint ( "port" , p2p . DefaultPort , "P2P UDP listener port" )
2021-08-30 07:19:00 -07:00
p2pBootstrap = NodeCmd . Flags ( ) . String ( "bootstrap" , "" , "P2P bootstrap peers (comma-separated)" )
2020-10-28 14:41:38 -07:00
2021-08-30 07:19:00 -07:00
statusAddr = NodeCmd . Flags ( ) . String ( "statusAddr" , "[::]:6060" , "Listen address for status server (disabled if blank)" )
2021-01-24 08:20:04 -08:00
2021-08-30 07:19:00 -07:00
nodeKeyPath = NodeCmd . Flags ( ) . String ( "nodeKey" , "" , "Path to node key (will be generated if it doesn't exist)" )
2020-10-28 14:41:38 -07:00
2021-08-30 07:19:00 -07:00
adminSocketPath = NodeCmd . Flags ( ) . String ( "adminSocket" , "" , "Admin gRPC service UNIX domain socket path" )
2022-11-18 07:36:22 -08:00
publicGRPCSocketPath = NodeCmd . Flags ( ) . String ( "publicGRPCSocket" , "" , "Public gRPC service UNIX domain socket path" )
2020-11-19 03:53:19 -08:00
2021-08-30 07:19:00 -07:00
dataDir = NodeCmd . Flags ( ) . String ( "dataDir" , "" , "Data directory" )
2021-07-21 11:56:25 -07:00
2021-08-30 07:19:00 -07:00
guardianKeyPath = NodeCmd . Flags ( ) . String ( "guardianKey" , "" , "Path to guardian key (required)" )
solanaContract = NodeCmd . Flags ( ) . String ( "solanaContract" , "" , "Address of the Solana program (required)" )
2020-11-19 03:53:17 -08:00
2021-08-30 07:19:00 -07:00
ethRPC = NodeCmd . Flags ( ) . String ( "ethRPC" , "" , "Ethereum RPC URL" )
ethContract = NodeCmd . Flags ( ) . String ( "ethContract" , "" , "Ethereum contract address" )
2020-10-28 14:41:38 -07:00
2021-08-30 07:19:00 -07:00
bscRPC = NodeCmd . Flags ( ) . String ( "bscRPC" , "" , "Binance Smart Chain RPC URL" )
bscContract = NodeCmd . Flags ( ) . String ( "bscContract" , "" , "Binance Smart Chain contract address" )
2021-07-28 06:32:49 -07:00
2021-10-18 08:53:13 -07:00
polygonRPC = NodeCmd . Flags ( ) . String ( "polygonRPC" , "" , "Polygon RPC URL" )
polygonContract = NodeCmd . Flags ( ) . String ( "polygonContract" , "" , "Polygon contract address" )
2022-11-11 06:12:16 -08:00
polygonRootChainRpc = NodeCmd . Flags ( ) . String ( "polygonRootChainRpc" , "" , "Polygon root chain RPC" )
polygonRootChainContractAddress = NodeCmd . Flags ( ) . String ( "polygonRootChainContractAddress" , "" , "Polygon root chain contract address" )
2021-10-18 08:53:13 -07:00
2021-12-09 13:40:55 -08:00
avalancheRPC = NodeCmd . Flags ( ) . String ( "avalancheRPC" , "" , "Avalanche RPC URL" )
avalancheContract = NodeCmd . Flags ( ) . String ( "avalancheContract" , "" , "Avalanche contract address" )
2021-12-20 11:40:58 -08:00
oasisRPC = NodeCmd . Flags ( ) . String ( "oasisRPC" , "" , "Oasis RPC URL" )
oasisContract = NodeCmd . Flags ( ) . String ( "oasisContract" , "" , "Oasis contract address" )
2022-03-15 07:41:10 -07:00
auroraRPC = NodeCmd . Flags ( ) . String ( "auroraRPC" , "" , "Aurora Websocket RPC URL" )
auroraContract = NodeCmd . Flags ( ) . String ( "auroraContract" , "" , "Aurora contract address" )
2022-02-02 09:50:10 -08:00
fantomRPC = NodeCmd . Flags ( ) . String ( "fantomRPC" , "" , "Fantom Websocket RPC URL" )
fantomContract = NodeCmd . Flags ( ) . String ( "fantomContract" , "" , "Fantom contract address" )
2022-03-03 13:40:32 -08:00
karuraRPC = NodeCmd . Flags ( ) . String ( "karuraRPC" , "" , "Karura RPC URL" )
karuraContract = NodeCmd . Flags ( ) . String ( "karuraContract" , "" , "Karura contract address" )
acalaRPC = NodeCmd . Flags ( ) . String ( "acalaRPC" , "" , "Acala RPC URL" )
acalaContract = NodeCmd . Flags ( ) . String ( "acalaContract" , "" , "Acala contract address" )
2022-04-04 15:11:03 -07:00
klaytnRPC = NodeCmd . Flags ( ) . String ( "klaytnRPC" , "" , "Klaytn RPC URL" )
klaytnContract = NodeCmd . Flags ( ) . String ( "klaytnContract" , "" , "Klaytn contract address" )
2022-04-28 09:20:38 -07:00
celoRPC = NodeCmd . Flags ( ) . String ( "celoRPC" , "" , "Celo RPC URL" )
celoContract = NodeCmd . Flags ( ) . String ( "celoContract" , "" , "Celo contract address" )
2022-05-10 08:23:07 -07:00
moonbeamRPC = NodeCmd . Flags ( ) . String ( "moonbeamRPC" , "" , "Moonbeam RPC URL" )
moonbeamContract = NodeCmd . Flags ( ) . String ( "moonbeamContract" , "" , "Moonbeam contract address" )
2022-06-14 07:22:49 -07:00
neonRPC = NodeCmd . Flags ( ) . String ( "neonRPC" , "" , "Neon RPC URL" )
neonContract = NodeCmd . Flags ( ) . String ( "neonContract" , "" , "Neon contract address" )
2021-08-30 07:19:00 -07:00
terraWS = NodeCmd . Flags ( ) . String ( "terraWS" , "" , "Path to terrad root for websocket connection" )
terraLCD = NodeCmd . Flags ( ) . String ( "terraLCD" , "" , "Path to LCD service root for http calls" )
terraContract = NodeCmd . Flags ( ) . String ( "terraContract" , "" , "Wormhole contract address on Terra blockchain" )
2020-11-16 04:28:07 -08:00
2022-06-16 12:17:43 -07:00
terra2WS = NodeCmd . Flags ( ) . String ( "terra2WS" , "" , "Path to terrad root for websocket connection" )
terra2LCD = NodeCmd . Flags ( ) . String ( "terra2LCD" , "" , "Path to LCD service root for http calls" )
terra2Contract = NodeCmd . Flags ( ) . String ( "terra2Contract" , "" , "Wormhole contract address on Terra 2 blockchain" )
2022-07-06 07:19:57 -07:00
injectiveWS = NodeCmd . Flags ( ) . String ( "injectiveWS" , "" , "Path to root for Injective websocket connection" )
injectiveLCD = NodeCmd . Flags ( ) . String ( "injectiveLCD" , "" , "Path to LCD service root for Injective http calls" )
injectiveContract = NodeCmd . Flags ( ) . String ( "injectiveContract" , "" , "Wormhole contract address on Injective blockchain" )
2022-10-05 06:05:31 -07:00
xplaWS = NodeCmd . Flags ( ) . String ( "xplaWS" , "" , "Path to root for XPLA websocket connection" )
xplaLCD = NodeCmd . Flags ( ) . String ( "xplaLCD" , "" , "Path to LCD service root for XPLA http calls" )
xplaContract = NodeCmd . Flags ( ) . String ( "xplaContract" , "" , "Wormhole contract address on XPLA blockchain" )
2023-08-14 08:13:20 -07:00
gatewayWS = NodeCmd . Flags ( ) . String ( "gatewayWS" , "" , "Path to root for Gateway watcher websocket connection" )
gatewayLCD = NodeCmd . Flags ( ) . String ( "gatewayLCD" , "" , "Path to LCD service root for Gateway watcher http calls" )
gatewayContract = NodeCmd . Flags ( ) . String ( "gatewayContract" , "" , "Wormhole contract address on Gateway blockchain" )
2022-04-29 12:56:08 -07:00
algorandIndexerRPC = NodeCmd . Flags ( ) . String ( "algorandIndexerRPC" , "" , "Algorand Indexer RPC URL" )
algorandIndexerToken = NodeCmd . Flags ( ) . String ( "algorandIndexerToken" , "" , "Algorand Indexer access token" )
2022-05-10 04:41:59 -07:00
algorandAlgodRPC = NodeCmd . Flags ( ) . String ( "algorandAlgodRPC" , "" , "Algorand Algod RPC URL" )
algorandAlgodToken = NodeCmd . Flags ( ) . String ( "algorandAlgodToken" , "" , "Algorand Algod access token" )
2022-04-29 12:56:08 -07:00
algorandAppID = NodeCmd . Flags ( ) . Uint64 ( "algorandAppID" , 0 , "Algorand app id" )
2021-12-22 08:22:04 -08:00
2022-08-05 10:49:16 -07:00
nearRPC = NodeCmd . Flags ( ) . String ( "nearRPC" , "" , "near RPC URL" )
nearContract = NodeCmd . Flags ( ) . String ( "nearContract" , "" , "near contract" )
2023-01-16 04:33:01 -08:00
wormchainURL = NodeCmd . Flags ( ) . String ( "wormchainURL" , "" , "wormhole-chain gRPC URL" )
2023-08-22 12:49:49 -07:00
// TODO: These are deprecated. Get rid of them once the guardians have had a chance to migrate off of them.
2023-01-16 04:33:01 -08:00
wormchainKeyPath = NodeCmd . Flags ( ) . String ( "wormchainKeyPath" , "" , "path to wormhole-chain private key for signing transactions" )
wormchainKeyPassPhrase = NodeCmd . Flags ( ) . String ( "wormchainKeyPassPhrase" , "" , "pass phrase used to unarmor the wormchain key file" )
2023-04-17 07:54:36 -07:00
ibcWS = NodeCmd . Flags ( ) . String ( "ibcWS" , "" , "Websocket used to listen to the IBC receiver smart contract on wormchain" )
ibcLCD = NodeCmd . Flags ( ) . String ( "ibcLCD" , "" , "Path to LCD service root for http calls" )
ibcContract = NodeCmd . Flags ( ) . String ( "ibcContract" , "" , "Address of the IBC smart contract on wormchain" )
2023-01-17 05:30:50 -08:00
accountantWS = NodeCmd . Flags ( ) . String ( "accountantWS" , "" , "Websocket used to listen to the accountant smart contract on wormchain" )
accountantContract = NodeCmd . Flags ( ) . String ( "accountantContract" , "" , "Address of the accountant smart contract on wormchain" )
2023-08-22 12:49:49 -07:00
accountantKeyPath = NodeCmd . Flags ( ) . String ( "accountantKeyPath" , "" , "path to accountant private key for signing transactions" )
accountantKeyPassPhrase = NodeCmd . Flags ( ) . String ( "accountantKeyPassPhrase" , "" , "pass phrase used to unarmor the accountant key file" )
2023-01-17 05:30:50 -08:00
accountantCheckEnabled = NodeCmd . Flags ( ) . Bool ( "accountantCheckEnabled" , false , "Should accountant be enforced on transfers" )
2022-09-02 01:36:24 -07:00
2022-10-13 18:22:54 -07:00
aptosRPC = NodeCmd . Flags ( ) . String ( "aptosRPC" , "" , "aptos RPC URL" )
aptosAccount = NodeCmd . Flags ( ) . String ( "aptosAccount" , "" , "aptos account" )
aptosHandle = NodeCmd . Flags ( ) . String ( "aptosHandle" , "" , "aptos handle" )
2022-11-18 06:14:22 -08:00
suiRPC = NodeCmd . Flags ( ) . String ( "suiRPC" , "" , "sui RPC URL" )
suiWS = NodeCmd . Flags ( ) . String ( "suiWS" , "" , "sui WS URL" )
2023-04-17 10:56:52 -07:00
suiMoveEventType = NodeCmd . Flags ( ) . String ( "suiMoveEventType" , "" , "sui move event type for publish_message" )
2022-11-18 06:14:22 -08:00
2023-01-18 08:24:55 -08:00
solanaRPC = NodeCmd . Flags ( ) . String ( "solanaRPC" , "" , "Solana RPC URL (required)" )
2021-01-21 02:31:32 -08:00
2022-07-28 10:30:00 -07:00
pythnetContract = NodeCmd . Flags ( ) . String ( "pythnetContract" , "" , "Address of the PythNet program (required)" )
2023-01-18 08:24:55 -08:00
pythnetRPC = NodeCmd . Flags ( ) . String ( "pythnetRPC" , "" , "PythNet RPC URL (required)" )
pythnetWS = NodeCmd . Flags ( ) . String ( "pythnetWS" , "" , "PythNet WS URL" )
2022-07-28 10:30:00 -07:00
2022-09-28 07:39:58 -07:00
arbitrumRPC = NodeCmd . Flags ( ) . String ( "arbitrumRPC" , "" , "Arbitrum RPC URL" )
arbitrumContract = NodeCmd . Flags ( ) . String ( "arbitrumContract" , "" , "Arbitrum contract address" )
2023-04-03 07:24:17 -07:00
sepoliaRPC = NodeCmd . Flags ( ) . String ( "sepoliaRPC" , "" , "Sepolia RPC URL" )
sepoliaContract = NodeCmd . Flags ( ) . String ( "sepoliaContract" , "" , "Sepolia contract address" )
2022-11-10 05:50:08 -08:00
optimismRPC = NodeCmd . Flags ( ) . String ( "optimismRPC" , "" , "Optimism RPC URL" )
optimismContract = NodeCmd . Flags ( ) . String ( "optimismContract" , "" , "Optimism contract address" )
2023-02-23 15:37:35 -08:00
baseRPC = NodeCmd . Flags ( ) . String ( "baseRPC" , "" , "Base RPC URL" )
baseContract = NodeCmd . Flags ( ) . String ( "baseContract" , "" , "Base contract address" )
2021-08-30 07:19:00 -07:00
logLevel = NodeCmd . Flags ( ) . String ( "logLevel" , "info" , "Logging level (debug, info, warn, error, dpanic, panic, fatal)" )
2023-03-01 07:10:04 -08:00
publicRpcLogDetailStr = NodeCmd . Flags ( ) . String ( "publicRpcLogDetail" , "full" , "The detail with which public RPC requests shall be logged (none=no logging, minimal=only log gRPC methods, full=log gRPC method, payload (up to 200 bytes) and user agent (up to 200 bytes))" )
publicRpcLogToTelemetry = NodeCmd . Flags ( ) . Bool ( "logPublicRpcToTelemetry" , true , "whether or not to include publicRpc request logs in telemetry" )
2020-10-28 14:41:38 -07:00
2021-08-30 07:19:00 -07:00
unsafeDevMode = NodeCmd . Flags ( ) . Bool ( "unsafeDevMode" , false , "Launch node in unsafe, deterministic devnet mode" )
2022-10-31 07:14:01 -07:00
testnetMode = NodeCmd . Flags ( ) . Bool ( "testnetMode" , false , "Launch node in testnet mode (enables testnet-only features)" )
2021-08-30 07:19:00 -07:00
nodeName = NodeCmd . Flags ( ) . String ( "nodeName" , "" , "Node name to announce in gossip heartbeats" )
2021-05-12 22:57:08 -07:00
2021-08-30 07:19:00 -07:00
publicRPC = NodeCmd . Flags ( ) . String ( "publicRPC" , "" , "Listen address for public gRPC interface" )
publicWeb = NodeCmd . Flags ( ) . String ( "publicWeb" , "" , "Listen address for public REST and gRPC Web interface" )
2021-08-20 15:44:37 -07:00
2021-08-30 07:19:00 -07:00
tlsHostname = NodeCmd . Flags ( ) . String ( "tlsHostname" , "" , "If set, serve publicWeb as TLS with this hostname using Let's Encrypt" )
tlsProdEnv = NodeCmd . Flags ( ) . Bool ( "tlsProdEnv" , false ,
2021-08-20 15:44:37 -07:00
"Use the production Let's Encrypt environment instead of staging" )
2021-07-07 02:39:48 -07:00
2021-08-30 07:19:00 -07:00
disableHeartbeatVerify = NodeCmd . Flags ( ) . Bool ( "disableHeartbeatVerify" , false ,
2021-08-05 08:01:36 -07:00
"Disable heartbeat signature verification (useful during network startup)" )
2022-01-09 12:56:59 -08:00
disableTelemetry = NodeCmd . Flags ( ) . Bool ( "disableTelemetry" , false ,
"Disable telemetry" )
telemetryKey = NodeCmd . Flags ( ) . String ( "telemetryKey" , "" ,
"Telemetry write key" )
2023-05-23 12:53:26 -07:00
telemetryServiceAccountFile = NodeCmd . Flags ( ) . String ( "telemetryServiceAccountFile" , "" ,
"Google Cloud credentials json for accessing Cloud Logging" )
telemetryProject = NodeCmd . Flags ( ) . String ( "telemetryProject" , defaultTelemetryProject ,
"Google Cloud Project to use for Telemetry logging" )
2021-08-05 08:01:36 -07:00
2023-07-12 12:51:01 -07:00
telemetryLokiURL = NodeCmd . Flags ( ) . String ( "telemetryLokiURL" , "" , "Loki cloud logging URL" )
2022-07-19 11:08:06 -07:00
chainGovernorEnabled = NodeCmd . Flags ( ) . Bool ( "chainGovernorEnabled" , false , "Run the chain governor" )
2023-08-03 08:26:50 -07:00
2023-10-12 11:20:42 -07:00
ccqEnabled = NodeCmd . Flags ( ) . Bool ( "ccqEnabled" , false , "Enable cross chain query support" )
ccqAllowedRequesters = NodeCmd . Flags ( ) . String ( "ccqAllowedRequesters" , "" , "Comma separated list of signers allowed to submit cross chain queries" )
ccqP2pPort = NodeCmd . Flags ( ) . Uint ( "ccqP2pPort" , 8996 , "CCQ P2P UDP listener port" )
ccqP2pBootstrap = NodeCmd . Flags ( ) . String ( "ccqP2pBootstrap" , "" , "CCQ P2P bootstrap peers (comma-separated)" )
ccqAllowedPeers = NodeCmd . Flags ( ) . String ( "ccqAllowedPeers" , "" , "CCQ allowed P2P peers (comma-separated)" )
2023-08-03 08:26:50 -07:00
gatewayRelayerContract = NodeCmd . Flags ( ) . String ( "gatewayRelayerContract" , "" , "Address of the smart contract on wormchain to receive relayed VAAs" )
gatewayRelayerKeyPath = NodeCmd . Flags ( ) . String ( "gatewayRelayerKeyPath" , "" , "Path to gateway relayer private key for signing transactions" )
gatewayRelayerKeyPassPhrase = NodeCmd . Flags ( ) . String ( "gatewayRelayerKeyPassPhrase" , "" , "Pass phrase used to unarmor the gateway relayer key file" )
2020-10-28 14:41:38 -07:00
}
2020-08-17 05:55:51 -07:00
var (
rootCtx context . Context
rootCtxCancel context . CancelFunc
)
2020-08-19 05:23:00 -07:00
// "Why would anyone do this?" are famous last words.
//
// We already forcibly override RPC URLs and keys in dev mode to prevent security
// risks from operator error, but an extra warning won't hurt.
const devwarning = `
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
| NODE IS RUNNING IN INSECURE DEVELOPMENT MODE |
| |
2022-07-06 11:27:49 -07:00
| Do not use -- unsafeDevMode in prod . |
2020-08-19 05:23:00 -07:00
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
`
2021-08-30 07:19:00 -07:00
// NodeCmd represents the node command
var NodeCmd = & cobra . Command {
Use : "node" ,
Short : "Run the guardiand node" ,
Run : runNode ,
2020-10-28 14:41:38 -07:00
}
2020-08-02 14:12:58 -07:00
2022-07-06 11:27:49 -07:00
// This variable may be overridden by the -X linker flag to "dev" in which case
// we enforce the --unsafeDevMode flag. Only development binaries/docker images
// are distributed. Production binaries are required to be built from source by
// guardians to reduce risk from a compromised builder.
var Build = "prod"
2021-08-30 07:19:00 -07:00
func runNode ( cmd * cobra . Command , args [ ] string ) {
2022-07-06 11:27:49 -07:00
if Build == "dev" && ! * unsafeDevMode {
fmt . Println ( "This is a development build. --unsafeDevMode must be enabled." )
os . Exit ( 1 )
}
2020-08-19 05:23:00 -07:00
if * unsafeDevMode {
fmt . Print ( devwarning )
}
2023-04-26 08:05:16 -07:00
if * testnetMode || * unsafeDevMode {
fmt . Println ( "Not locking in memory." )
} else {
common . LockMemory ( )
}
2021-12-02 16:02:32 -08:00
common . SetRestrictiveUmask ( )
2020-10-22 07:51:56 -07:00
2021-08-02 04:26:57 -07:00
// Refuse to run as root in production mode.
if ! * unsafeDevMode && os . Geteuid ( ) == 0 {
fmt . Println ( "can't run as uid 0" )
os . Exit ( 1 )
}
2020-08-02 14:12:58 -07:00
// Set up logging. The go-log zap wrapper that libp2p uses is compatible with our
// usage of zap in supervisor, which is nice.
lvl , err := ipfslog . LevelFromString ( * logLevel )
if err != nil {
fmt . Println ( "Invalid log level" )
os . Exit ( 1 )
}
2022-01-25 03:59:18 -08:00
logger := zap . New ( zapcore . NewCore (
consoleEncoder { zapcore . NewConsoleEncoder (
zap . NewDevelopmentEncoderConfig ( ) ) } ,
zapcore . AddSync ( zapcore . Lock ( os . Stderr ) ) ,
zap . NewAtomicLevelAt ( zapcore . Level ( lvl ) ) ) )
2022-01-06 08:58:56 -08:00
if * unsafeDevMode {
// Use the hostname as nodeName. For production, we don't want to do this to
// prevent accidentally leaking sensitive hostnames.
hostname , err := os . Hostname ( )
if err != nil {
panic ( err )
}
* nodeName = hostname
// Put node name into the log for development.
logger = logger . Named ( * nodeName )
}
2020-08-02 14:12:58 -07:00
// Override the default go-log config, which uses a magic environment variable.
ipfslog . SetAllLoggers ( lvl )
2021-01-24 08:20:04 -08:00
// In devnet mode, we automatically set a number of flags that rely on deterministic keys.
if * unsafeDevMode {
2022-10-06 05:57:25 -07:00
g0key , err := peer . IDFromPrivateKey ( devnet . DeterministicP2PPrivKeyByIndex ( 0 ) )
if err != nil {
panic ( err )
2020-08-19 05:23:00 -07:00
}
2022-10-06 05:57:25 -07:00
// Use the first guardian node as bootstrap
* p2pBootstrap = fmt . Sprintf ( "/dns4/guardian-0.guardian/udp/%d/quic/p2p/%s" , * p2pPort , g0key . String ( ) )
2023-10-12 11:20:42 -07:00
* ccqP2pBootstrap = fmt . Sprintf ( "/dns4/guardian-0.guardian/udp/%d/quic/p2p/%s" , * ccqP2pPort , g0key . String ( ) )
2020-08-19 05:23:00 -07:00
// Deterministic ganache ETH devnet address.
2022-11-10 14:27:39 -08:00
* ethContract = unsafeDevModeEvmContractAddress ( * ethContract )
* bscContract = unsafeDevModeEvmContractAddress ( * bscContract )
* polygonContract = unsafeDevModeEvmContractAddress ( * polygonContract )
* avalancheContract = unsafeDevModeEvmContractAddress ( * avalancheContract )
* oasisContract = unsafeDevModeEvmContractAddress ( * oasisContract )
* auroraContract = unsafeDevModeEvmContractAddress ( * auroraContract )
* fantomContract = unsafeDevModeEvmContractAddress ( * fantomContract )
* karuraContract = unsafeDevModeEvmContractAddress ( * karuraContract )
* acalaContract = unsafeDevModeEvmContractAddress ( * acalaContract )
* klaytnContract = unsafeDevModeEvmContractAddress ( * klaytnContract )
* celoContract = unsafeDevModeEvmContractAddress ( * celoContract )
* moonbeamContract = unsafeDevModeEvmContractAddress ( * moonbeamContract )
* neonContract = unsafeDevModeEvmContractAddress ( * neonContract )
* arbitrumContract = unsafeDevModeEvmContractAddress ( * arbitrumContract )
* optimismContract = unsafeDevModeEvmContractAddress ( * optimismContract )
2023-02-23 15:37:35 -08:00
* baseContract = unsafeDevModeEvmContractAddress ( * baseContract )
2023-04-03 07:24:17 -07:00
* sepoliaContract = unsafeDevModeEvmContractAddress ( * sepoliaContract )
2020-08-19 05:23:00 -07:00
}
2020-08-02 14:12:58 -07:00
2020-08-03 13:33:35 -07:00
// Verify flags
2020-08-19 05:23:00 -07:00
if * nodeKeyPath == "" && ! * unsafeDevMode { // In devnet mode, keys are deterministically generated.
2020-11-20 12:18:29 -08:00
logger . Fatal ( "Please specify --nodeKey" )
2020-08-03 13:33:35 -07:00
}
2021-08-30 07:19:00 -07:00
if * guardianKeyPath == "" {
logger . Fatal ( "Please specify --guardianKey" )
2020-11-19 03:53:17 -08:00
}
2020-11-19 03:53:19 -08:00
if * adminSocketPath == "" {
2020-11-20 12:18:29 -08:00
logger . Fatal ( "Please specify --adminSocket" )
2020-11-19 03:53:19 -08:00
}
2022-11-18 07:36:22 -08:00
if * adminSocketPath == * publicGRPCSocketPath {
logger . Fatal ( "--adminSocket must not equal --publicGRPCSocket" )
}
if ( * publicRPC != "" || * publicWeb != "" ) && * publicGRPCSocketPath == "" {
logger . Fatal ( "If either --publicRPC or --publicWeb is specified, --publicGRPCSocket must also be specified" )
}
2021-07-21 11:56:25 -07:00
if * dataDir == "" {
logger . Fatal ( "Please specify --dataDir" )
}
2020-08-16 08:05:58 -07:00
if * ethRPC == "" {
2020-11-20 12:18:29 -08:00
logger . Fatal ( "Please specify --ethRPC" )
2020-08-16 08:05:58 -07:00
}
2020-08-19 05:23:00 -07:00
if * ethContract == "" {
2020-11-20 12:18:29 -08:00
logger . Fatal ( "Please specify --ethContract" )
2020-08-19 05:23:00 -07:00
}
2021-07-28 06:32:49 -07:00
if * bscRPC == "" {
logger . Fatal ( "Please specify --bscRPC" )
}
if * bscContract == "" {
logger . Fatal ( "Please specify --bscContract" )
}
2021-10-18 08:53:13 -07:00
if * polygonRPC == "" {
logger . Fatal ( "Please specify --polygonRPC" )
}
if * polygonContract == "" {
logger . Fatal ( "Please specify --polygonContract" )
}
2021-12-14 14:27:17 -08:00
if * avalancheRPC == "" {
logger . Fatal ( "Please specify --avalancheRPC" )
}
2021-12-21 12:55:31 -08:00
if * oasisRPC == "" {
logger . Fatal ( "Please specify --oasisRPC" )
}
2022-02-28 13:32:22 -08:00
if * fantomRPC == "" {
logger . Fatal ( "Please specify --fantomRPC" )
}
if * fantomContract == "" && ! * unsafeDevMode {
logger . Fatal ( "Please specify --fantomContract" )
}
2022-04-09 05:06:10 -07:00
if * auroraRPC == "" {
logger . Fatal ( "Please specify --auroraRPC" )
}
if * auroraContract == "" && ! * unsafeDevMode {
logger . Fatal ( "Please specify --auroraContract" )
}
2022-05-02 11:28:17 -07:00
if * karuraRPC == "" {
logger . Fatal ( "Please specify --karuraRPC" )
}
if * karuraContract == "" && ! * unsafeDevMode {
logger . Fatal ( "Please specify --karuraContract" )
}
2022-06-02 09:18:44 -07:00
if * acalaRPC == "" {
logger . Fatal ( "Please specify --acalaRPC" )
}
if * acalaContract == "" && ! * unsafeDevMode {
logger . Fatal ( "Please specify --acalaContract" )
}
2022-05-16 07:06:17 -07:00
if * klaytnRPC == "" {
logger . Fatal ( "Please specify --klaytnRPC" )
}
if * klaytnContract == "" && ! * unsafeDevMode {
logger . Fatal ( "Please specify --klaytnContract" )
}
2022-05-12 09:12:40 -07:00
if * celoRPC == "" {
logger . Fatal ( "Please specify --celoRPC" )
}
if * celoContract == "" && ! * unsafeDevMode {
logger . Fatal ( "Please specify --celoContract" )
}
2022-08-26 09:46:37 -07:00
if * nearRPC != "" {
if * nearContract == "" {
logger . Fatal ( "If --nearRPC is specified, then --nearContract must be specified" )
2022-08-05 10:49:16 -07:00
}
2022-08-26 09:46:37 -07:00
} else if * nearContract != "" {
2022-10-12 13:47:03 -07:00
logger . Fatal ( "If --nearRPC is not specified, then --nearContract must not be specified" )
2022-08-05 10:49:16 -07:00
}
2022-09-12 16:41:39 -07:00
if * moonbeamRPC == "" {
logger . Fatal ( "Please specify --moonbeamRPC" )
}
if * moonbeamContract == "" {
logger . Fatal ( "Please specify --moonbeamContract" )
}
2022-10-27 11:50:01 -07:00
if * arbitrumRPC == "" {
logger . Fatal ( "Please specify --arbitrumRPC" )
}
if * arbitrumContract == "" {
logger . Fatal ( "Please specify --arbitrumContract" )
}
2022-10-12 13:47:03 -07:00
if * xplaWS != "" {
if * xplaLCD == "" || * xplaContract == "" {
logger . Fatal ( "If --xplaWS is specified, then --xplaLCD and --xplaContract must be specified" )
}
} else if * xplaLCD != "" || * xplaContract != "" {
logger . Fatal ( "If --xplaWS is not specified, then --xplaLCD and --xplaContract must not be specified" )
}
2022-10-14 08:34:24 -07:00
if * aptosRPC != "" {
if * aptosAccount == "" {
logger . Fatal ( "If --aptosRPC is specified, then --aptosAccount must be specified" )
}
if * aptosHandle == "" {
logger . Fatal ( "If --aptosRPC is specified, then --aptosHandle must be specified" )
2022-10-13 18:22:54 -07:00
}
}
2022-11-18 06:14:22 -08:00
if * suiRPC != "" {
if * suiWS == "" {
logger . Fatal ( "If --suiRPC is specified, then --suiWS must be specified" )
}
2023-04-17 10:56:52 -07:00
if * suiMoveEventType == "" {
logger . Fatal ( "If --suiRPC is specified, then --suiMoveEventType must be specified" )
2022-11-18 06:14:22 -08:00
}
}
2022-10-13 18:22:54 -07:00
2022-11-10 11:56:38 -08:00
if ( * optimismRPC == "" ) != ( * optimismContract == "" ) {
logger . Fatal ( "Both --optimismContract and --optimismRPC must be set together or both unset" )
}
2023-07-18 05:17:27 -07:00
if ( * baseRPC == "" ) != ( * baseContract == "" ) {
logger . Fatal ( "Both --baseContract and --baseRPC must be set together or both unset" )
}
2023-08-14 08:13:20 -07:00
if * gatewayWS != "" {
if * gatewayLCD == "" || * gatewayContract == "" {
logger . Fatal ( "If --gatewayWS is specified, then --gatewayLCD and --gatewayContract must be specified" )
}
} else if * gatewayLCD != "" || * gatewayContract != "" {
logger . Fatal ( "If --gatewayWS is not specified, then --gatewayLCD and --gatewayContract must not be specified" )
}
2021-11-22 07:49:41 -08:00
if * testnetMode {
2022-06-14 07:22:49 -07:00
if * neonRPC == "" {
logger . Fatal ( "Please specify --neonRPC" )
}
if * neonContract == "" {
logger . Fatal ( "Please specify --neonContract" )
}
2023-04-03 07:24:17 -07:00
if * sepoliaRPC == "" {
logger . Fatal ( "Please specify --sepoliaRPC" )
}
if * sepoliaContract == "" {
logger . Fatal ( "Please specify --sepoliaContract" )
}
2021-11-22 07:49:41 -08:00
} else {
2022-06-14 07:22:49 -07:00
if * neonRPC != "" && ! * unsafeDevMode {
logger . Fatal ( "Please do not specify --neonRPC" )
}
if * neonContract != "" && ! * unsafeDevMode {
logger . Fatal ( "Please do not specify --neonContract" )
}
2023-04-03 07:24:17 -07:00
if * sepoliaRPC != "" && ! * unsafeDevMode {
logger . Fatal ( "Please do not specify --sepoliaRPC" )
}
if * sepoliaContract != "" && ! * unsafeDevMode {
logger . Fatal ( "Please do not specify --sepoliaContract" )
}
2021-11-22 07:49:41 -08:00
}
2023-03-01 07:10:04 -08:00
var publicRpcLogDetail common . GrpcLogDetail
switch * publicRpcLogDetailStr {
case "none" :
publicRpcLogDetail = common . GrpcLogDetailNone
case "minimal" :
publicRpcLogDetail = common . GrpcLogDetailMinimal
case "full" :
publicRpcLogDetail = common . GrpcLogDetailFull
default :
logger . Fatal ( "--publicRpcLogDetail should be one of (none, minimal, full)" )
}
2020-08-17 10:22:12 -07:00
if * nodeName == "" {
2020-11-20 12:18:29 -08:00
logger . Fatal ( "Please specify --nodeName" )
2020-08-17 10:22:12 -07:00
}
2021-01-21 02:31:32 -08:00
2022-07-10 17:47:10 -07:00
// Solana, Terra Classic, Terra 2, and Algorand are optional in devnet
if ! * unsafeDevMode {
2021-01-21 02:31:32 -08:00
2022-07-10 17:47:10 -07:00
if * solanaContract == "" {
logger . Fatal ( "Please specify --solanaContract" )
2021-12-22 08:22:04 -08:00
}
2022-07-10 17:47:10 -07:00
if * solanaRPC == "" {
2022-08-26 06:45:47 -07:00
logger . Fatal ( "Please specify --solanaRPC" )
2022-05-10 04:41:59 -07:00
}
2022-07-10 17:47:10 -07:00
if * terraWS == "" {
logger . Fatal ( "Please specify --terraWS" )
}
if * terraLCD == "" {
logger . Fatal ( "Please specify --terraLCD" )
2022-05-10 04:41:59 -07:00
}
2022-07-10 17:47:10 -07:00
if * terraContract == "" {
logger . Fatal ( "Please specify --terraContract" )
2021-12-22 08:22:04 -08:00
}
2022-07-10 17:47:10 -07:00
if * terra2WS == "" {
logger . Fatal ( "Please specify --terra2WS" )
}
if * terra2LCD == "" {
logger . Fatal ( "Please specify --terra2LCD" )
}
if * terra2Contract == "" {
logger . Fatal ( "Please specify --terra2Contract" )
}
2022-08-16 08:14:48 -07:00
if * algorandIndexerRPC == "" {
logger . Fatal ( "Please specify --algorandIndexerRPC" )
}
if * algorandAlgodRPC == "" {
logger . Fatal ( "Please specify --algorandAlgodRPC" )
}
if * algorandAlgodToken == "" {
logger . Fatal ( "Please specify --algorandAlgodToken" )
}
if * algorandAppID == 0 {
logger . Fatal ( "Please specify --algorandAppID" )
}
2022-07-28 10:30:00 -07:00
2022-08-26 06:45:47 -07:00
if * pythnetContract == "" {
logger . Fatal ( "Please specify --pythnetContract" )
}
if * pythnetRPC == "" {
logger . Fatal ( "Please specify --pythnetRPC" )
2022-07-10 17:47:10 -07:00
}
2023-08-30 14:49:51 -07:00
if * pythnetWS == "" {
logger . Fatal ( "Please specify --pythnetWS" )
}
2022-12-07 11:43:44 -08:00
if * injectiveWS == "" {
logger . Fatal ( "Please specify --injectiveWS" )
}
if * injectiveLCD == "" {
logger . Fatal ( "Please specify --injectiveLCD" )
}
if * injectiveContract == "" {
logger . Fatal ( "Please specify --injectiveContract" )
}
2021-12-22 08:22:04 -08:00
}
2022-07-10 17:47:10 -07:00
2023-05-23 12:53:26 -07:00
if * telemetryKey != "" && * telemetryServiceAccountFile != "" {
logger . Fatal ( "Please do not specify both --telemetryKey and --telemetryServiceAccountFile" )
}
2023-05-24 11:17:08 -07:00
// Determine execution mode
// TODO: refactor usage of these variables elsewhere. *unsafeDevMode and *testnetMode should not be accessed directly.
var env common . Environment
if * unsafeDevMode {
env = common . UnsafeDevNet
} else if * testnetMode {
env = common . TestNet
} else {
env = common . MainNet
}
if * unsafeDevMode && * testnetMode {
logger . Fatal ( "Cannot be in unsafeDevMode and testnetMode at the same time." )
}
2021-10-18 08:23:55 -07:00
// Complain about Infura on mainnet.
//
// As it turns out, Infura has a bug where it would sometimes incorrectly round
// block timestamps, which causes consensus issues - the timestamp is part of
// the VAA and nodes using Infura would sometimes derive an incorrect VAA,
// accidentally attacking the network by signing a conflicting VAA.
//
// Node operators do not usually rely on Infura in the first place - doing
// so is insecure, since nodes blindly trust the connected nodes to verify
// on-chain message proofs. However, node operators sometimes used
// Infura during migrations where their primary node was offline, causing
// the aforementioned consensus oddities which were eventually found to
// be Infura-related. This is generally to the detriment of network security
// and a judgement call made by individual operators. In the case of Infura,
// we know it's actively dangerous so let's make an opinionated argument.
//
// Insert "I'm a sign, not a cop" meme.
//
2021-10-26 16:42:00 -07:00
if strings . Contains ( * ethRPC , "mainnet.infura.io" ) ||
strings . Contains ( * polygonRPC , "polygon-mainnet.infura.io" ) {
2021-10-18 08:23:55 -07:00
logger . Fatal ( "Infura is known to send incorrect blocks - please use your own nodes" )
}
2020-11-19 03:53:17 -08:00
// In devnet mode, we generate a deterministic guardian key and write it to disk.
if * unsafeDevMode {
2023-09-27 10:06:12 -07:00
err := devnet . GenerateAndStoreDevnetGuardianKey ( * guardianKeyPath )
2020-11-19 03:53:17 -08:00
if err != nil {
logger . Fatal ( "failed to generate devnet guardian key" , zap . Error ( err ) )
}
}
2021-07-30 13:40:01 -07:00
// Database
2023-05-24 14:23:42 -07:00
db := db . OpenDb ( logger , dataDir )
2021-07-30 13:40:01 -07:00
defer db . Close ( )
2020-08-17 10:36:17 -07:00
// Guardian key
2023-09-27 10:06:12 -07:00
gk , err := common . LoadGuardianKey ( * guardianKeyPath , * unsafeDevMode )
2020-11-19 03:53:17 -08:00
if err != nil {
logger . Fatal ( "failed to load guardian key" , zap . Error ( err ) )
}
logger . Info ( "Loaded guardian key" , zap . String (
2023-05-24 14:23:42 -07:00
"address" , ethcrypto . PubkeyToAddress ( gk . PublicKey ) . String ( ) ) )
2023-01-20 13:15:13 -08:00
2020-10-28 14:41:37 -07:00
// Load p2p private key
2023-05-24 14:23:42 -07:00
var p2pKey libp2p_crypto . PrivKey
2020-10-28 14:41:37 -07:00
if * unsafeDevMode {
idx , err := devnet . GetDevnetIndex ( )
if err != nil {
logger . Fatal ( "Failed to parse hostname - are we running in devnet?" )
}
2023-05-24 14:23:42 -07:00
p2pKey = devnet . DeterministicP2PPrivKeyByIndex ( int64 ( idx ) )
2023-06-14 13:39:30 -07:00
if idx != 0 {
// try to connect to guardian-0
for {
_ , err := net . LookupIP ( "guardian-0.guardian" )
if err == nil {
break
}
logger . Info ( "Error resolving guardian-0.guardian. Trying again..." )
time . Sleep ( time . Second )
}
2023-06-27 10:43:54 -07:00
// TODO this is a hack. If this is not the bootstrap Guardian, we wait 10s such that the bootstrap Guardian has enough time to start.
// This may no longer be necessary because now the p2p.go ensures that it can connect to at least one bootstrap peer and will
// exit the whole guardian if it is unable to. Sleeping here for a bit may reduce overall startup time by preventing unnecessary restarts, though.
logger . Info ( "This is not a bootstrap Guardian. Waiting another 10 seconds for the bootstrap guardian to come online." )
2023-06-14 13:39:30 -07:00
time . Sleep ( time . Second * 10 )
}
2020-10-28 14:41:37 -07:00
} else {
2023-05-24 14:23:42 -07:00
p2pKey , err = common . GetOrCreateNodeKey ( logger , * nodeKeyPath )
2020-10-28 14:41:37 -07:00
if err != nil {
logger . Fatal ( "Failed to load node key" , zap . Error ( err ) )
}
}
2023-05-24 14:23:42 -07:00
rpcMap := make ( map [ string ] string )
rpcMap [ "acalaRPC" ] = * acalaRPC
rpcMap [ "algorandIndexerRPC" ] = * algorandIndexerRPC
rpcMap [ "algorandAlgodRPC" ] = * algorandAlgodRPC
rpcMap [ "aptosRPC" ] = * aptosRPC
rpcMap [ "arbitrumRPC" ] = * arbitrumRPC
rpcMap [ "auroraRPC" ] = * auroraRPC
rpcMap [ "avalancheRPC" ] = * avalancheRPC
rpcMap [ "baseRPC" ] = * baseRPC
rpcMap [ "bscRPC" ] = * bscRPC
rpcMap [ "celoRPC" ] = * celoRPC
rpcMap [ "ethRPC" ] = * ethRPC
rpcMap [ "fantomRPC" ] = * fantomRPC
rpcMap [ "ibcLCD" ] = * ibcLCD
rpcMap [ "ibcWS" ] = * ibcWS
rpcMap [ "karuraRPC" ] = * karuraRPC
rpcMap [ "klaytnRPC" ] = * klaytnRPC
rpcMap [ "moonbeamRPC" ] = * moonbeamRPC
rpcMap [ "nearRPC" ] = * nearRPC
rpcMap [ "neonRPC" ] = * neonRPC
rpcMap [ "oasisRPC" ] = * oasisRPC
rpcMap [ "optimismRPC" ] = * optimismRPC
rpcMap [ "polygonRPC" ] = * polygonRPC
rpcMap [ "pythnetRPC" ] = * pythnetRPC
rpcMap [ "pythnetWS" ] = * pythnetWS
rpcMap [ "sei" ] = "IBC"
if env == common . TestNet {
rpcMap [ "sepoliaRPC" ] = * sepoliaRPC
}
rpcMap [ "solanaRPC" ] = * solanaRPC
rpcMap [ "suiRPC" ] = * suiRPC
rpcMap [ "terraWS" ] = * terraWS
rpcMap [ "terraLCD" ] = * terraLCD
rpcMap [ "terra2WS" ] = * terra2WS
rpcMap [ "terra2LCD" ] = * terra2LCD
2023-08-14 08:13:20 -07:00
rpcMap [ "gatewayWS" ] = * gatewayWS
rpcMap [ "gatewayLCD" ] = * gatewayLCD
2023-05-24 14:23:42 -07:00
rpcMap [ "xplaWS" ] = * xplaWS
rpcMap [ "xplaLCD" ] = * xplaLCD
// Node's main lifecycle context.
rootCtx , rootCtxCancel = context . WithCancel ( context . Background ( ) )
defer rootCtxCancel ( )
// Handle SIGTERM
sigterm := make ( chan os . Signal , 1 )
signal . Notify ( sigterm , syscall . SIGTERM )
go func ( ) {
<- sigterm
logger . Info ( "Received sigterm. exiting." )
rootCtxCancel ( )
} ( )
2023-07-12 12:51:01 -07:00
usingLoki := * telemetryLokiURL != ""
usingGCP := * telemetryKey != "" || * telemetryServiceAccountFile != ""
var hasTelemetryCredential bool = usingGCP || usingLoki
2023-05-23 12:53:26 -07:00
2023-05-24 14:23:42 -07:00
// Telemetry is enabled by default in mainnet/testnet. In devnet it is disabled by default
2023-05-23 12:53:26 -07:00
if ! * disableTelemetry && ( ! * unsafeDevMode || * unsafeDevMode && hasTelemetryCredential ) {
if ! hasTelemetryCredential {
2023-07-12 12:51:01 -07:00
logger . Fatal ( "Please either specify --telemetryKey, --telemetryServiceAccountFile or --telemetryLokiURL or set --disableTelemetry=false" )
2022-01-09 12:56:59 -08:00
}
2023-07-12 12:51:01 -07:00
if usingLoki && usingGCP {
logger . Fatal ( "May only enable one telemetry logger at a time, either specify --telemetryLokiURL or --telemetryKey/--telemetryServiceAccountFile" )
2022-01-09 12:56:59 -08:00
}
// Get libp2p peer ID from private key
2023-05-24 14:23:42 -07:00
pk := p2pKey . GetPublic ( )
2022-01-09 12:56:59 -08:00
peerID , err := peer . IDFromPublicKey ( pk )
if err != nil {
logger . Fatal ( "Failed to get peer ID from private key" , zap . Error ( err ) )
}
2023-05-23 12:53:26 -07:00
labels := map [ string ] string {
2022-01-09 12:56:59 -08:00
"node_name" : * nodeName ,
"node_key" : peerID . Pretty ( ) ,
2023-05-24 14:23:42 -07:00
"guardian_addr" : ethcrypto . PubkeyToAddress ( gk . PublicKey ) . String ( ) ,
2022-01-09 12:56:59 -08:00
"network" : * p2pNetworkID ,
"version" : version . Version ( ) ,
2023-05-23 12:53:26 -07:00
}
2023-05-23 12:56:37 -07:00
skipPrivateLogs := ! * publicRpcLogToTelemetry
2023-07-12 12:51:01 -07:00
var tm * telemetry . Telemetry
if usingLoki {
logger . Info ( "Using Loki telemetry logger" ,
zap . String ( "publicRpcLogDetail" , * publicRpcLogDetailStr ) ,
zap . Bool ( "logPublicRpcToTelemetry" , * publicRpcLogToTelemetry ) )
2023-08-10 10:11:38 -07:00
tm , err = telemetry . NewLokiCloudLogger ( context . Background ( ) , logger , * telemetryLokiURL , "wormhole" , skipPrivateLogs , labels )
2023-07-12 12:51:01 -07:00
if err != nil {
logger . Fatal ( "Failed to initialize telemetry" , zap . Error ( err ) )
}
} else {
logger . Info ( "Using Google Cloud telemetry logger" ,
zap . String ( "publicRpcLogDetail" , * publicRpcLogDetailStr ) ,
zap . Bool ( "logPublicRpcToTelemetry" , * publicRpcLogToTelemetry ) )
var options [ ] googleapi_option . ClientOption
if * telemetryKey != "" {
creds , err := decryptTelemetryServiceAccount ( )
if err != nil {
logger . Fatal ( "Failed to decrypt telemetry service account" , zap . Error ( err ) )
}
options = append ( options , googleapi_option . WithCredentialsJSON ( creds ) )
}
if * telemetryServiceAccountFile != "" {
options = append ( options , googleapi_option . WithCredentialsFile ( * telemetryServiceAccountFile ) )
}
tm , err = telemetry . NewGoogleCloudLogger ( context . Background ( ) , * telemetryProject , skipPrivateLogs , labels , options ... )
if err != nil {
logger . Fatal ( "Failed to initialize telemetry" , zap . Error ( err ) )
}
2022-01-09 12:56:59 -08:00
}
2023-05-23 12:53:26 -07:00
2023-07-12 12:51:01 -07:00
defer tm . Close ( )
logger = tm . WrapLogger ( logger ) // Wrap logger with telemetry logger
2022-01-09 12:56:59 -08:00
}
2023-05-23 12:59:01 -07:00
// log golang version
logger . Info ( "golang version" , zap . String ( "golang_version" , runtime . Version ( ) ) )
2022-01-09 12:56:59 -08:00
// Redirect ipfs logs to plain zap
ipfslog . SetPrimaryCore ( logger . Core ( ) )
2023-08-23 07:12:58 -07:00
wormchainId := "wormchain"
if * testnetMode {
wormchainId = "wormchain-testnet-0"
}
2023-08-22 12:49:49 -07:00
var accountantWormchainConn * wormconn . ClientConn
if * accountantContract != "" {
// TODO: wormchainKeyPath and wormchainKeyPassPhrase are being replaced by accountantKeyPath and accountantKeyPassPhrase.
// Give the guardians time to migrate off of the old parameters, but then remove them.
keyPath := * accountantKeyPath
if keyPath == "" {
if * wormchainKeyPath == "" {
logger . Fatal ( "if accountantContract is specified, accountantKeyPath is required" , zap . String ( "component" , "gacct" ) )
}
logger . Error ( "the wormchainKeyPath parameter is deprecated, please change to accountantKeyPath" , zap . String ( "component" , "gacct" ) )
keyPath = * wormchainKeyPath
} else if * wormchainKeyPath != "" {
logger . Fatal ( "the wormchainKeyPath parameter is obsolete, please remove it" , zap . String ( "component" , "gacct" ) )
2023-01-16 04:33:01 -08:00
}
2023-08-22 12:49:49 -07:00
keyPassPhrase := * accountantKeyPassPhrase
if keyPassPhrase == "" {
if * wormchainKeyPassPhrase == "" {
logger . Fatal ( "if accountantContract is specified, accountantKeyPassPhrase is required" , zap . String ( "component" , "gacct" ) )
}
logger . Error ( "the wormchainKeyPassPhrase parameter is deprecated, please change to accountantKeyPassPhrase" , zap . String ( "component" , "gacct" ) )
keyPassPhrase = * wormchainKeyPassPhrase
} else if * wormchainKeyPassPhrase != "" {
logger . Fatal ( "the wormchainKeyPassPhrase parameter is obsolete, please remove it" , zap . String ( "component" , "gacct" ) )
2023-01-16 04:33:01 -08:00
}
2023-08-22 12:49:49 -07:00
keyPathName := keyPath
2023-01-16 04:33:01 -08:00
if * unsafeDevMode {
idx , err := devnet . GetDevnetIndex ( )
if err != nil {
2023-08-22 12:49:49 -07:00
logger . Fatal ( "failed to get devnet index" , zap . Error ( err ) , zap . String ( "component" , "gacct" ) )
2023-01-16 04:33:01 -08:00
}
2023-08-22 12:49:49 -07:00
keyPathName = fmt . Sprint ( keyPath , idx )
2023-01-16 04:33:01 -08:00
}
2023-08-22 12:49:49 -07:00
wormchainKey , err := wormconn . LoadWormchainPrivKey ( keyPathName , keyPassPhrase )
2023-01-16 04:33:01 -08:00
if err != nil {
2023-08-22 12:49:49 -07:00
logger . Fatal ( "failed to load wormchain private key" , zap . Error ( err ) , zap . String ( "component" , "gacct" ) )
2023-01-16 04:33:01 -08:00
}
// Connect to wormchain.
2023-08-22 12:49:49 -07:00
logger . Info ( "Connecting to wormchain" , zap . String ( "wormchainURL" , * wormchainURL ) , zap . String ( "keyPath" , keyPathName ) , zap . String ( "component" , "gacct" ) )
2023-08-23 07:12:58 -07:00
accountantWormchainConn , err = wormconn . NewConn ( rootCtx , * wormchainURL , wormchainKey , wormchainId )
2023-01-16 04:33:01 -08:00
if err != nil {
2023-08-22 12:49:49 -07:00
logger . Fatal ( "failed to connect to wormchain" , zap . Error ( err ) , zap . String ( "component" , "gacct" ) )
2023-01-16 04:33:01 -08:00
}
}
2023-08-03 08:26:50 -07:00
var gatewayRelayerWormchainConn * wormconn . ClientConn
if * gatewayRelayerContract != "" {
if * wormchainURL == "" {
logger . Fatal ( "if gatewayRelayerContract is specified, wormchainURL is required" , zap . String ( "component" , "gwrelayer" ) )
}
if * gatewayRelayerKeyPath == "" {
logger . Fatal ( "if gatewayRelayerContract is specified, gatewayRelayerKeyPath is required" , zap . String ( "component" , "gwrelayer" ) )
}
if * gatewayRelayerKeyPassPhrase == "" {
logger . Fatal ( "if gatewayRelayerContract is specified, gatewayRelayerKeyPassPhrase is required" , zap . String ( "component" , "gwrelayer" ) )
}
wormchainKeyPathName := * gatewayRelayerKeyPath
if * unsafeDevMode {
idx , err := devnet . GetDevnetIndex ( )
if err != nil {
logger . Fatal ( "failed to get devnet index" , zap . Error ( err ) , zap . String ( "component" , "gwrelayer" ) )
}
wormchainKeyPathName = fmt . Sprint ( * gatewayRelayerKeyPath , idx )
}
2023-08-22 12:49:49 -07:00
wormchainKey , err := wormconn . LoadWormchainPrivKey ( wormchainKeyPathName , * gatewayRelayerKeyPassPhrase )
2023-08-03 08:26:50 -07:00
if err != nil {
logger . Fatal ( "failed to load private key" , zap . Error ( err ) , zap . String ( "component" , "gwrelayer" ) )
}
2023-08-22 12:49:49 -07:00
logger . Info ( "Connecting to wormchain" , zap . String ( "wormchainURL" , * wormchainURL ) , zap . String ( "keyPath" , wormchainKeyPathName ) , zap . String ( "component" , "gwrelayer" ) )
2023-08-23 07:12:58 -07:00
gatewayRelayerWormchainConn , err = wormconn . NewConn ( rootCtx , * wormchainURL , wormchainKey , wormchainId )
2023-08-03 08:26:50 -07:00
if err != nil {
logger . Fatal ( "failed to connect to wormchain" , zap . Error ( err ) , zap . String ( "component" , "gwrelayer" ) )
}
}
2023-05-24 14:23:42 -07:00
var watcherConfigs = [ ] watchers . WatcherConfig { }
2023-01-16 04:33:01 -08:00
2023-05-24 14:23:42 -07:00
if shouldStart ( ethRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "eth" ,
ChainID : vaa . ChainIDEthereum ,
Rpc : * ethRPC ,
Contract : * ethContract ,
GuardianSetUpdateChain : true ,
2021-07-28 06:32:49 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2022-06-06 13:17:14 -07:00
2023-05-24 14:23:42 -07:00
if shouldStart ( bscRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "bsc" ,
ChainID : vaa . ChainIDBSC ,
Rpc : * bscRPC ,
Contract : * bscContract ,
WaitForConfirmations : true ,
2022-04-09 05:06:10 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( polygonRPC ) {
// Checkpointing is required in mainnet, so we don't need to wait for confirmations.
waitForConfirmations := * unsafeDevMode || * testnetMode
if ! waitForConfirmations && * polygonRootChainRpc == "" {
log . Fatal ( "Polygon checkpointing is required in mainnet" )
2022-02-28 13:32:22 -08:00
}
2023-05-24 14:23:42 -07:00
wc := & evm . WatcherConfig {
NetworkID : "polygon" ,
ChainID : vaa . ChainIDPolygon ,
Rpc : * polygonRPC ,
Contract : * polygonContract ,
WaitForConfirmations : waitForConfirmations ,
RootChainRpc : * polygonRootChainRpc ,
RootChainContract : * polygonRootChainContractAddress ,
2022-05-02 11:28:17 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( avalancheRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "avalanche" ,
ChainID : vaa . ChainIDAvalanche ,
Rpc : * avalancheRPC ,
Contract : * avalancheContract ,
2022-06-02 09:18:44 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( oasisRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "oasis" ,
ChainID : vaa . ChainIDOasis ,
Rpc : * oasisRPC ,
Contract : * oasisContract ,
2022-05-16 07:06:17 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( auroraRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "aurora" ,
ChainID : vaa . ChainIDAurora ,
Rpc : * auroraRPC ,
Contract : * auroraContract ,
2022-05-12 09:12:40 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( fantomRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "fantom" ,
ChainID : vaa . ChainIDFantom ,
Rpc : * fantomRPC ,
Contract : * fantomContract ,
2022-09-12 16:41:39 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( karuraRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "karura" ,
ChainID : vaa . ChainIDKarura ,
Rpc : * karuraRPC ,
Contract : * karuraContract ,
2022-10-20 09:43:43 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( acalaRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "acala" ,
ChainID : vaa . ChainIDAcala ,
Rpc : * acalaRPC ,
Contract : * acalaContract ,
2022-10-20 09:43:43 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( klaytnRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "klaytn" ,
ChainID : vaa . ChainIDKlaytn ,
Rpc : * klaytnRPC ,
Contract : * klaytnContract ,
2021-11-22 07:49:41 -08:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( celoRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "celo" ,
ChainID : vaa . ChainIDCelo ,
Rpc : * celoRPC ,
Contract : * celoContract ,
2022-10-27 11:50:01 -07:00
}
2023-02-15 09:52:31 -08:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( moonbeamRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "moonbeam" ,
ChainID : vaa . ChainIDMoonbeam ,
Rpc : * moonbeamRPC ,
Contract : * moonbeamContract ,
2022-11-10 11:56:38 -08:00
}
2021-11-22 07:49:41 -08:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( arbitrumRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "arbitrum" ,
ChainID : vaa . ChainIDArbitrum ,
Rpc : * arbitrumRPC ,
Contract : * arbitrumContract ,
L1FinalizerRequired : "eth" ,
2020-11-16 04:28:07 -08:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( optimismRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "optimism" ,
ChainID : vaa . ChainIDOptimism ,
Rpc : * optimismRPC ,
Contract : * optimismContract ,
2022-06-22 07:29:21 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2023-07-18 05:17:27 -07:00
if shouldStart ( baseRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "base" ,
ChainID : vaa . ChainIDBase ,
Rpc : * baseRPC ,
Contract : * baseContract ,
}
watcherConfigs = append ( watcherConfigs , wc )
}
2023-05-24 14:23:42 -07:00
if shouldStart ( terraWS ) {
wc := & cosmwasm . WatcherConfig {
NetworkID : "terra" ,
ChainID : vaa . ChainIDTerra ,
Websocket : * terraWS ,
Lcd : * terraLCD ,
Contract : * terraContract ,
2022-07-06 07:19:57 -07:00
}
2023-04-17 10:56:52 -07:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( terra2WS ) {
wc := & cosmwasm . WatcherConfig {
NetworkID : "terra2" ,
ChainID : vaa . ChainIDTerra2 ,
Websocket : * terra2WS ,
Lcd : * terra2LCD ,
Contract : * terra2Contract ,
2021-12-22 08:22:04 -08:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( xplaWS ) {
wc := & cosmwasm . WatcherConfig {
NetworkID : "xpla" ,
ChainID : vaa . ChainIDXpla ,
Websocket : * xplaWS ,
Lcd : * xplaLCD ,
Contract : * xplaContract ,
2022-08-05 10:49:16 -07:00
}
2021-12-22 08:22:04 -08:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( injectiveWS ) {
wc := & cosmwasm . WatcherConfig {
NetworkID : "injective" ,
ChainID : vaa . ChainIDInjective ,
Websocket : * injectiveWS ,
Lcd : * injectiveLCD ,
Contract : * injectiveContract ,
2022-10-13 18:22:54 -07:00
}
2022-09-02 01:36:24 -07:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
if shouldStart ( algorandIndexerRPC ) {
wc := & algorand . WatcherConfig {
NetworkID : "algorand" ,
ChainID : vaa . ChainIDAlgorand ,
IndexerRPC : * algorandIndexerRPC ,
IndexerToken : * algorandIndexerToken ,
AlgodRPC : * algorandAlgodRPC ,
AlgodToken : * algorandAlgodToken ,
AppID : * algorandAppID ,
2022-11-18 06:14:22 -08:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2022-11-18 06:14:22 -08:00
2023-05-24 14:23:42 -07:00
if shouldStart ( nearRPC ) {
wc := & near . WatcherConfig {
NetworkID : "near" ,
ChainID : vaa . ChainIDNear ,
Rpc : * nearRPC ,
Contract : * nearContract ,
2022-07-28 10:30:00 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2022-07-28 10:30:00 -07:00
2023-05-24 14:23:42 -07:00
if shouldStart ( aptosRPC ) {
wc := & aptos . WatcherConfig {
NetworkID : "aptos" ,
ChainID : vaa . ChainIDAptos ,
Rpc : * aptosRPC ,
Account : * aptosAccount ,
Handle : * aptosHandle ,
2020-08-20 12:48:58 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2020-08-20 12:48:58 -07:00
2023-05-24 14:23:42 -07:00
if shouldStart ( suiRPC ) {
wc := & sui . WatcherConfig {
NetworkID : "sui" ,
ChainID : vaa . ChainIDSui ,
Rpc : * suiRPC ,
Websocket : * suiWS ,
SuiMoveEventType : * suiMoveEventType ,
2022-12-07 11:43:44 -08:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2022-12-07 11:43:44 -08:00
2023-05-24 14:23:42 -07:00
if shouldStart ( solanaRPC ) {
// confirmed watcher
wc := & solana . WatcherConfig {
NetworkID : "solana-confirmed" ,
ChainID : vaa . ChainIDSolana ,
Rpc : * solanaRPC ,
Websocket : "" ,
Contract : * solanaContract ,
ReceiveObsReq : false ,
Commitment : rpc . CommitmentConfirmed ,
2022-10-20 09:43:43 -07:00
}
2023-04-03 07:24:17 -07:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
2023-04-17 07:54:36 -07:00
2023-05-24 14:23:42 -07:00
// finalized watcher
wc = & solana . WatcherConfig {
NetworkID : "solana-finalized" ,
ChainID : vaa . ChainIDSolana ,
Rpc : * solanaRPC ,
Websocket : "" ,
Contract : * solanaContract ,
ReceiveObsReq : true ,
Commitment : rpc . CommitmentFinalized ,
}
watcherConfigs = append ( watcherConfigs , wc )
}
2023-04-17 07:54:36 -07:00
2023-05-24 14:23:42 -07:00
if shouldStart ( pythnetRPC ) {
wc := & solana . WatcherConfig {
NetworkID : "pythnet" ,
ChainID : vaa . ChainIDPythNet ,
Rpc : * pythnetRPC ,
Websocket : * pythnetWS ,
Contract : * pythnetContract ,
ReceiveObsReq : false ,
Commitment : rpc . CommitmentConfirmed ,
}
2023-04-17 07:54:36 -07:00
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2023-04-17 07:54:36 -07:00
2023-08-14 08:13:20 -07:00
if shouldStart ( gatewayWS ) {
wc := & cosmwasm . WatcherConfig {
NetworkID : "gateway" ,
ChainID : vaa . ChainIDWormchain ,
Websocket : * gatewayWS ,
Lcd : * gatewayLCD ,
Contract : * gatewayContract ,
}
watcherConfigs = append ( watcherConfigs , wc )
}
2023-05-24 14:23:42 -07:00
if * testnetMode {
if shouldStart ( neonRPC ) {
if ! shouldStart ( solanaRPC ) {
log . Fatalf ( "If neon is enabled then solana must also be enabled." )
2023-04-17 07:54:36 -07:00
}
2023-05-24 14:23:42 -07:00
wc := & evm . WatcherConfig {
NetworkID : "neon" ,
ChainID : vaa . ChainIDNeon ,
Rpc : * neonRPC ,
Contract : * neonContract ,
L1FinalizerRequired : "solana-finalized" ,
2023-04-17 07:54:36 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
}
2022-10-20 09:43:43 -07:00
2023-05-24 14:23:42 -07:00
if shouldStart ( sepoliaRPC ) {
wc := & evm . WatcherConfig {
NetworkID : "sepolia" ,
ChainID : vaa . ChainIDSepolia ,
Rpc : * sepoliaRPC ,
Contract : * sepoliaContract ,
2022-07-19 11:08:06 -07:00
}
2023-05-24 14:23:42 -07:00
watcherConfigs = append ( watcherConfigs , wc )
2023-01-20 13:15:13 -08:00
}
2023-05-24 14:23:42 -07:00
}
2023-01-20 13:15:13 -08:00
2023-05-24 14:23:42 -07:00
var ibcWatcherConfig * node . IbcWatcherConfig = nil
if shouldStart ( ibcWS ) {
ibcWatcherConfig = & node . IbcWatcherConfig {
Websocket : * ibcWS ,
Lcd : * ibcLCD ,
Contract : * ibcContract ,
2020-11-19 03:53:19 -08:00
}
2023-05-24 14:23:42 -07:00
}
2022-11-18 07:36:22 -08:00
2023-05-24 14:23:42 -07:00
guardianNode := node . NewGuardianNode (
env ,
gk ,
)
2022-11-18 07:36:22 -08:00
2023-05-24 14:23:42 -07:00
guardianOptions := [ ] * node . GuardianOption {
2023-06-08 13:37:29 -07:00
node . GuardianOptionDatabase ( db ) ,
2023-05-24 14:23:42 -07:00
node . GuardianOptionWatchers ( watcherConfigs , ibcWatcherConfig ) ,
2023-08-22 12:49:49 -07:00
node . GuardianOptionAccountant ( * accountantContract , * accountantWS , * accountantCheckEnabled , accountantWormchainConn ) ,
2023-05-24 14:23:42 -07:00
node . GuardianOptionGovernor ( * chainGovernorEnabled ) ,
2023-08-03 08:26:50 -07:00
node . GuardianOptionGatewayRelayer ( * gatewayRelayerContract , gatewayRelayerWormchainConn ) ,
2023-10-12 11:20:42 -07:00
node . GuardianOptionQueryHandler ( * ccqEnabled , * ccqAllowedRequesters ) ,
2023-05-24 14:23:42 -07:00
node . GuardianOptionAdminService ( * adminSocketPath , ethRPC , ethContract , rpcMap ) ,
2023-10-12 11:20:42 -07:00
node . GuardianOptionP2P ( p2pKey , * p2pNetworkID , * p2pBootstrap , * nodeName , * disableHeartbeatVerify , * p2pPort , * ccqP2pBootstrap , * ccqP2pPort , * ccqAllowedPeers , ibc . GetFeatures ) ,
2023-05-24 14:23:42 -07:00
node . GuardianOptionStatusServer ( * statusAddr ) ,
2023-06-08 13:51:07 -07:00
node . GuardianOptionProcessor ( ) ,
2023-05-24 14:23:42 -07:00
}
2022-11-18 07:36:22 -08:00
2023-05-24 14:23:42 -07:00
if shouldStart ( publicGRPCSocketPath ) {
guardianOptions = append ( guardianOptions , node . GuardianOptionPublicRpcSocket ( * publicGRPCSocketPath , publicRpcLogDetail ) )
2022-11-18 07:36:22 -08:00
2023-05-24 14:23:42 -07:00
if shouldStart ( publicRPC ) {
guardianOptions = append ( guardianOptions , node . GuardianOptionPublicrpcTcpService ( * publicRPC , publicRpcLogDetail ) )
}
2022-11-18 07:36:22 -08:00
2023-05-24 14:23:42 -07:00
if shouldStart ( publicWeb ) {
guardianOptions = append ( guardianOptions ,
node . GuardianOptionPublicWeb ( * publicWeb , * publicGRPCSocketPath , * tlsHostname , * tlsProdEnv , path . Join ( * dataDir , "autocert" ) ) ,
)
2021-07-30 16:18:53 -07:00
}
2023-05-24 14:23:42 -07:00
}
2020-11-19 03:53:19 -08:00
2023-05-24 14:23:42 -07:00
// Run supervisor with Guardian Node as root.
supervisor . New ( rootCtx , logger , guardianNode . Run ( rootCtxCancel , guardianOptions ... ) ,
2020-10-22 03:20:11 -07:00
// It's safer to crash and restart the process in case we encounter a panic,
// rather than attempting to reschedule the runnable.
supervisor . WithPropagatePanic )
2020-08-02 14:12:58 -07:00
2021-08-30 11:40:38 -07:00
<- rootCtx . Done ( )
logger . Info ( "root context cancelled, exiting..." )
2020-08-02 14:12:58 -07:00
}
2022-01-09 12:56:59 -08:00
func decryptTelemetryServiceAccount ( ) ( [ ] byte , error ) {
// Decrypt service account credentials
key , err := base64 . StdEncoding . DecodeString ( * telemetryKey )
if err != nil {
return nil , fmt . Errorf ( "failed to decode: %w" , err )
}
2023-05-23 12:53:26 -07:00
ciphertext , err := base64 . StdEncoding . DecodeString ( defaultTelemetryServiceAccountEnc )
2022-01-09 12:56:59 -08:00
if err != nil {
panic ( err )
}
creds , err := common . DecryptAESGCM ( ciphertext , key )
if err != nil {
return nil , fmt . Errorf ( "failed to decrypt: %w" , err )
}
return creds , err
}
2022-10-20 09:43:43 -07:00
func shouldStart ( rpc * string ) bool {
return * rpc != "" && * rpc != "none"
}
2022-11-10 14:27:39 -08:00
func unsafeDevModeEvmContractAddress ( contractAddr string ) string {
if contractAddr != "" {
return contractAddr
}
return devnet . GanacheWormholeContractAddress . Hex ( )
}