*: add ropsten chainID and guardiand implementation

Change-Id: Ib99316c28237d946eb2b6d013f4e275a620d4aa8
This commit is contained in:
Leo 2021-11-22 16:49:41 +01:00 committed by Leopold Schabel
parent dac68d093c
commit 8800d7bfd3
7 changed files with 151 additions and 48 deletions

View File

@ -64,10 +64,19 @@ func runListNodes(cmd *cobra.Command, args []string) {
w := tabwriter.NewWriter(os.Stdout, 0, 8, 2, ' ', 0)
if showDetails {
_, _ = w.Write([]byte("Node key\tGuardian key\tNode name\tVersion\tLast seen\tUptime\tSolana\tEthereum\tTerra\tBSC\tPolygon\n"))
if *testnetMode {
// Include Ropsten in testnet mode
if showDetails {
_, _ = w.Write([]byte("Node key\tGuardian key\tNode name\tVersion\tLast seen\tUptime\tSolana\tEthereum\tTerra\tBSC\tPolygon\tRopsten\n"))
} else {
_, _ = w.Write([]byte("Node key\tGuardian key\tNode name\tVersion\tLast seen\tSolana\tEthereum\tTerra\tBSC\tPolygon\tRopsten\n"))
}
} else {
_, _ = w.Write([]byte("Node key\tGuardian key\tNode name\tVersion\tLast seen\tSolana\tEthereum\tTerra\tBSC\tPolygon\n"))
if showDetails {
_, _ = w.Write([]byte("Node key\tGuardian key\tNode name\tVersion\tLast seen\tUptime\tSolana\tEthereum\tTerra\tBSC\tPolygon\n"))
} else {
_, _ = w.Write([]byte("Node key\tGuardian key\tNode name\tVersion\tLast seen\tSolana\tEthereum\tTerra\tBSC\tPolygon\n"))
}
}
for _, h := range nodes {
@ -91,45 +100,92 @@ func runListNodes(cmd *cobra.Command, args []string) {
}
}
if showDetails {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%s\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\n",
h.P2PNodeAddr,
h.RawHeartbeat.GuardianAddr,
h.RawHeartbeat.NodeName,
h.RawHeartbeat.Version,
time.Since(last),
time.Since(boot),
truncAddrs[vaa.ChainIDSolana],
heights[vaa.ChainIDSolana],
errors[vaa.ChainIDSolana],
truncAddrs[vaa.ChainIDEthereum],
heights[vaa.ChainIDEthereum],
errors[vaa.ChainIDEthereum],
truncAddrs[vaa.ChainIDTerra],
heights[vaa.ChainIDTerra],
errors[vaa.ChainIDTerra],
truncAddrs[vaa.ChainIDBSC],
heights[vaa.ChainIDBSC],
errors[vaa.ChainIDBSC],
truncAddrs[vaa.ChainIDPolygon],
heights[vaa.ChainIDPolygon],
errors[vaa.ChainIDPolygon],
)
if *testnetMode {
if showDetails {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%s\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\n",
h.P2PNodeAddr,
h.RawHeartbeat.GuardianAddr,
h.RawHeartbeat.NodeName,
h.RawHeartbeat.Version,
time.Since(last),
time.Since(boot),
truncAddrs[vaa.ChainIDSolana],
heights[vaa.ChainIDSolana],
errors[vaa.ChainIDSolana],
truncAddrs[vaa.ChainIDEthereum],
heights[vaa.ChainIDEthereum],
errors[vaa.ChainIDEthereum],
truncAddrs[vaa.ChainIDTerra],
heights[vaa.ChainIDTerra],
errors[vaa.ChainIDTerra],
truncAddrs[vaa.ChainIDBSC],
heights[vaa.ChainIDBSC],
errors[vaa.ChainIDBSC],
truncAddrs[vaa.ChainIDPolygon],
heights[vaa.ChainIDPolygon],
errors[vaa.ChainIDPolygon],
truncAddrs[vaa.ChainIDEthereumRopsten],
heights[vaa.ChainIDEthereumRopsten],
errors[vaa.ChainIDEthereumRopsten],
)
} else {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\t%d\n",
h.P2PNodeAddr,
h.RawHeartbeat.GuardianAddr,
h.RawHeartbeat.NodeName,
h.RawHeartbeat.Version,
time.Since(last),
heights[vaa.ChainIDSolana],
heights[vaa.ChainIDEthereum],
heights[vaa.ChainIDTerra],
heights[vaa.ChainIDBSC],
heights[vaa.ChainIDPolygon],
heights[vaa.ChainIDEthereumRopsten],
)
}
} else {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n",
h.P2PNodeAddr,
h.RawHeartbeat.GuardianAddr,
h.RawHeartbeat.NodeName,
h.RawHeartbeat.Version,
time.Since(last),
heights[vaa.ChainIDSolana],
heights[vaa.ChainIDEthereum],
heights[vaa.ChainIDTerra],
heights[vaa.ChainIDBSC],
heights[vaa.ChainIDPolygon],
)
if showDetails {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%s\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\t%s %d (%d)\n",
h.P2PNodeAddr,
h.RawHeartbeat.GuardianAddr,
h.RawHeartbeat.NodeName,
h.RawHeartbeat.Version,
time.Since(last),
time.Since(boot),
truncAddrs[vaa.ChainIDSolana],
heights[vaa.ChainIDSolana],
errors[vaa.ChainIDSolana],
truncAddrs[vaa.ChainIDEthereum],
heights[vaa.ChainIDEthereum],
errors[vaa.ChainIDEthereum],
truncAddrs[vaa.ChainIDTerra],
heights[vaa.ChainIDTerra],
errors[vaa.ChainIDTerra],
truncAddrs[vaa.ChainIDBSC],
heights[vaa.ChainIDBSC],
errors[vaa.ChainIDBSC],
truncAddrs[vaa.ChainIDPolygon],
heights[vaa.ChainIDPolygon],
errors[vaa.ChainIDPolygon],
)
} else {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\n",
h.P2PNodeAddr,
h.RawHeartbeat.GuardianAddr,
h.RawHeartbeat.NodeName,
h.RawHeartbeat.Version,
time.Since(last),
heights[vaa.ChainIDSolana],
heights[vaa.ChainIDEthereum],
heights[vaa.ChainIDTerra],
heights[vaa.ChainIDBSC],
heights[vaa.ChainIDPolygon],
)
}
}
}

View File

@ -69,6 +69,9 @@ var (
polygonRPC *string
polygonContract *string
ethRopstenRPC *string
ethRopstenContract *string
terraWS *string
terraLCD *string
terraContract *string
@ -79,6 +82,7 @@ var (
logLevel *string
unsafeDevMode *bool
testnetMode *bool
devNumGuardians *uint
nodeName *string
@ -125,6 +129,9 @@ func init() {
polygonRPC = NodeCmd.Flags().String("polygonRPC", "", "Polygon RPC URL")
polygonContract = NodeCmd.Flags().String("polygonContract", "", "Polygon contract address")
ethRopstenRPC = NodeCmd.Flags().String("ethRopstenRPC", "", "Ethereum Ropsten RPC URL")
ethRopstenContract = NodeCmd.Flags().String("ethRopstenContract", "", "Ethereum Ropsten contract address")
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")
@ -135,6 +142,7 @@ func init() {
logLevel = NodeCmd.Flags().String("logLevel", "info", "Logging level (debug, info, warn, error, dpanic, panic, fatal)")
unsafeDevMode = NodeCmd.Flags().Bool("unsafeDevMode", false, "Launch node in unsafe, deterministic devnet mode")
testnetMode = NodeCmd.Flags().Bool("testnetMode", false, "Launch node in testnet mode (enables testnet-only features like Ropsten)")
devNumGuardians = NodeCmd.Flags().Uint("devNumGuardians", 5, "Number of devnet guardians to include in guardian set")
nodeName = NodeCmd.Flags().String("nodeName", "", "Node name to announce in gossip heartbeats")
@ -249,6 +257,9 @@ func runNode(cmd *cobra.Command, args []string) {
readiness.RegisterComponent(common.ReadinessTerraSyncing)
readiness.RegisterComponent(common.ReadinessBSCSyncing)
readiness.RegisterComponent(common.ReadinessPolygonSyncing)
if *testnetMode {
readiness.RegisterComponent(common.ReadinessEthRopstenSyncing)
}
if *statusAddr != "" {
// Use a custom routing instead of using http.DefaultServeMux directly to avoid accidentally exposing packages
@ -331,6 +342,21 @@ func runNode(cmd *cobra.Command, args []string) {
if *polygonContract == "" {
logger.Fatal("Please specify --polygonContract")
}
if *testnetMode {
if *ethRopstenRPC == "" {
logger.Fatal("Please specify --ethRopstenRPC")
}
if *ethRopstenContract == "" {
logger.Fatal("Please specify --ethRopstenContract")
}
} else {
if *ethRopstenRPC != "" {
logger.Fatal("Please do not specify --ethRopstenRPC in non-testnet mode")
}
if *ethRopstenContract != "" {
logger.Fatal("Please do not specify --ethRopstenContract in non-testnet mode")
}
}
if *nodeName == "" {
logger.Fatal("Please specify --nodeName")
}
@ -396,6 +422,7 @@ func runNode(cmd *cobra.Command, args []string) {
ethContractAddr := eth_common.HexToAddress(*ethContract)
bscContractAddr := eth_common.HexToAddress(*bscContract)
polygonContractAddr := eth_common.HexToAddress(*polygonContract)
ethRopstenContractAddr := eth_common.HexToAddress(*ethRopstenContract)
solAddress, err := solana_types.PublicKeyFromBase58(*solanaContract)
if err != nil {
logger.Fatal("invalid Solana contract address", zap.Error(err))
@ -528,6 +555,13 @@ func runNode(cmd *cobra.Command, args []string) {
return err
}
if *testnetMode {
if err := supervisor.Run(ctx, "ethropstenwatch",
ethereum.NewEthWatcher(*ethRopstenRPC, ethRopstenContractAddr, "ethropsten", common.ReadinessEthRopstenSyncing, vaa.ChainIDEthereumRopsten, lockC, setC).Run); err != nil {
return err
}
}
// Start Terra watcher only if configured
logger.Info("Starting Terra watcher")
if err := supervisor.Run(ctx, "terrawatch",

View File

@ -3,9 +3,10 @@ package common
import "github.com/certusone/wormhole/node/pkg/readiness"
const (
ReadinessEthSyncing readiness.Component = "ethSyncing"
ReadinessSolanaSyncing readiness.Component = "solanaSyncing"
ReadinessTerraSyncing readiness.Component = "terraSyncing"
ReadinessBSCSyncing readiness.Component = "bscSyncing"
ReadinessPolygonSyncing readiness.Component = "polygonSyncing"
ReadinessEthSyncing readiness.Component = "ethSyncing"
ReadinessSolanaSyncing readiness.Component = "solanaSyncing"
ReadinessTerraSyncing readiness.Component = "terraSyncing"
ReadinessBSCSyncing readiness.Component = "bscSyncing"
ReadinessPolygonSyncing readiness.Component = "polygonSyncing"
ReadinessEthRopstenSyncing readiness.Component = "ethRopstenSyncing"
)

View File

@ -94,6 +94,8 @@ func (c ChainID) String() string {
return "bsc"
case ChainIDPolygon:
return "polygon"
case ChainIDEthereumRopsten:
return "ethereum-ropsten"
default:
return fmt.Sprintf("unknown chain ID: %d", c)
}
@ -113,6 +115,8 @@ func ChainIDFromString(s string) (ChainID, error) {
return ChainIDBSC, nil
case "polygon":
return ChainIDPolygon, nil
case "ethereum-ropsten":
return ChainIDEthereumRopsten, nil
default:
return ChainIDUnset, fmt.Errorf("unknown chain ID: %s", s)
}
@ -130,6 +134,8 @@ const (
ChainIDBSC ChainID = 4
// ChainIDPolygon is the ChainID of Polygon
ChainIDPolygon ChainID = 5
// ChainIDEthereumRopsten is the ChainID of Ethereum Ropsten
ChainIDEthereumRopsten ChainID = 10001
minVAALength = 1 + 4 + 52 + 4 + 1 + 1
SupportedVAAVersion = 0x01

View File

@ -14,6 +14,9 @@ enum ChainID {
CHAIN_ID_TERRA = 3;
CHAIN_ID_BSC = 4;
CHAIN_ID_POLYGON = 5;
// Special case - Eth has two testnets. CHAIN_ID_ETHEREUM is Goerli,
// but we also want to connect to Ropsten, so we add a separate chain.
CHAIN_ID_ETHEREUM_ROPSTEN = 10001;
}
// MessageID is a VAA's globally unique identifier (see data availability design document).

View File

@ -5,6 +5,7 @@ import {
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
CHAIN_ID_POLYGON,
CHAIN_ID_ETHEREUM_ROPSTEN,
} from "./consts";
import { humanAddress, canonicalAddress, isNativeDenom } from "../terra";
import { PublicKey } from "@solana/web3.js";
@ -14,6 +15,7 @@ import { arrayify, zeroPad } from "@ethersproject/bytes";
export const isEVMChain = (chainId: ChainId) =>
chainId === CHAIN_ID_ETH ||
chainId === CHAIN_ID_BSC ||
chainId === CHAIN_ID_ETHEREUM_ROPSTEN ||
chainId === CHAIN_ID_POLYGON;
export const isHexNativeTerra = (h: string) => h.startsWith("01");
@ -29,7 +31,7 @@ export const hexToNativeString = (h: string | undefined, c: ChainId) => {
? undefined
: c === CHAIN_ID_SOLANA
? new PublicKey(hexToUint8Array(h)).toString()
: c === CHAIN_ID_ETH || c === CHAIN_ID_BSC || c === CHAIN_ID_POLYGON
: c === CHAIN_ID_ETH || c === CHAIN_ID_BSC || c === CHAIN_ID_POLYGON || c === CHAIN_ID_ETHEREUM_ROPSTEN
? hexZeroPad(hexValue(hexToUint8Array(h)), 20)
: c === CHAIN_ID_TERRA
? isHexNativeTerra(h)

View File

@ -1,9 +1,10 @@
export type ChainId = 1 | 2 | 3 | 4 | 5;
export type ChainId = 1 | 2 | 3 | 4 | 5 | 10001;
export const CHAIN_ID_SOLANA: ChainId = 1;
export const CHAIN_ID_ETH: ChainId = 2;
export const CHAIN_ID_TERRA: ChainId = 3;
export const CHAIN_ID_BSC: ChainId = 4;
export const CHAIN_ID_POLYGON: ChainId = 5;
export const CHAIN_ID_ETHEREUM_ROPSTEN: ChainId = 10001;
export const WSOL_ADDRESS = "So11111111111111111111111111111111111111112";
export const WSOL_DECIMALS = 9;