add offchain-relayer (#10)

* add offchain-relayer

* Update test to use off-chain relayer

Co-authored-by: Drew <dsterioti@users.noreply.github.com>
This commit is contained in:
Justin Schuldt 2022-09-30 12:58:39 -05:00 committed by GitHub
parent d3b6470936
commit fbadea1de9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 10193 additions and 8 deletions

View File

@ -26,8 +26,8 @@ lib/forge-std:
wormhole_dependencies: wormhole/ethereum/build
wormhole/ethereum/build:
git clone --depth 1 --branch feat/batch_vaas --single-branch https://github.com/certusone/wormhole.git
cd wormhole/ethereum && npm ci && npm run build && make .env
git clone --depth 1 --branch scratch/batch_vaa_integration --single-branch https://github.com/certusone/wormhole.git
cd wormhole/ethereum && npm ci && npm run build && npm run abigen && make .env
dependencies: node_modules forge_dependencies wormhole_dependencies

View File

@ -0,0 +1,23 @@
evmRPC: ws://localhost:8545
evmContract: 0x2f3efA6bbDC5fAf4dC1a600765c7B7829e47bE10
evmWormholeChainID: 2
evmNetworkID: 1
evm2RPC: ws://localhost:8546
evm2Contract: 0x2f3efA6bbDC5fAf4dC1a600765c7B7829e47bE10
evm2WormholeChainID: 4
evm2NetworkID: 56
nodeName: generic-relayer
senderKeyHex: 4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d
spyRPC: localhost:7072
guardianRPC: localhost:7070
unsafeDevMode: true
logLevel: debug
statusAddr: :6066

74
offchain-relayer/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,74 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "relay",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"buildFlags": "-gcflags='all=-N -l' --ldflags '-extldflags \"-Wl,--allow-multiple-definition\" -X \"github.com/certusone/wormhole/node/cmd/guardiand.Build=dev\"'",
"args": [
"relay",
"--evmRPC",
"ws://localhost:8545",
"--evmContract",
"0x2f3efA6bbDC5fAf4dC1a600765c7B7829e47bE10",
"--evmWormholeChainID",
"2",
"--evmNetworkID",
"1",
"--evm2RPC",
"ws://localhost:8546",
"--evm2Contract",
"0x2f3efA6bbDC5fAf4dC1a600765c7B7829e47bE10",
"--evm2WormholeChainID",
"4",
"--evm2NetworkID",
"56",
"--nodeName",
"generic-relayer",
"--dataDir",
"/home/your-user/tmp",
"--senderKeyHex",
"4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d",
"--spyRPC",
"localhost:7072",
"--guardianRPC",
"localhost:7070",
"--unsafeDevMode",
"--logLevel",
"debug",
"--statusAddr",
":6066"
],
"env": {
},
},
{
"name": "Connect to relay with dlv",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "${workspaceFolder}",
"port": 2345,
"host": "127.0.0.1"
},
]
}

View File

@ -0,0 +1,57 @@
## prereqs
- tilt up and running with the Spy relayer enabled (`--spy_relayer=True`).
- the CoreRelayer deployed to tilt.
- Golang >= 1.17
- `jq` installed and available in your path
## relayer config
Config like contract addresses and RPC endpoints gets read from the `.relayer.yaml` file. any of the args can also be passed at runtime to override the values from the yaml file.
## start the relayer
```bash
./start-relayer.sh
```
## creating Go clients from ABIs
CoreRelayer
```bash
jq '.abi' ./ethereum/build/CoreRelayer.sol/CoreRelayer.json | docker run -i --rm -v $(pwd):/root -u $(id -u):$(id -g) ethereum/client-go:alltools-stable abigen --abi - --pkg core_relayer --type CoreRelayer --out /root/offchain-relayer/relay/ethereum/core_relayer/abi.go
```
## get the deployed replayer contract address
```bash
CHAINID=1337 && jq '.transactions[] | select(.contractName == "ERC1967Proxy") | .contractAddress' ethereum/broadcast/deploy_contracts.sol/$CHAINID/run-latest.json
```
## wormhole ChainID to network ID
```solidity
// Wormhole chain ids explicitly enumerated
if (chain == 2) { evmChainId = 1; // ethereum
} else if (chain == 4) { evmChainId = 56; // bsc
} else if (chain == 5) { evmChainId = 137; // polygon
} else if (chain == 6) { evmChainId = 43114; // avalanche
} else if (chain == 7) { evmChainId = 42262; // oasis
} else if (chain == 9) { evmChainId = 1313161554; // aurora
} else if (chain == 10) { evmChainId = 250; // fantom
} else if (chain == 11) { evmChainId = 686; // karura
} else if (chain == 12) { evmChainId = 787; // acala
} else if (chain == 13) { evmChainId = 8217; // klaytn
} else if (chain == 14) { evmChainId = 42220; // celo
} else if (chain == 16) { evmChainId = 1284; // moonbeam
} else if (chain == 17) { evmChainId = 245022934; // neon
} else if (chain == 23) { evmChainId = 42161; // arbitrum
} else if (chain == 24) { evmChainId = 10; // optimism
} else if (chain == 25) { evmChainId = 100; // gnosis
} else {
revert("Unknown chain id.");
}
```

View File

@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -exuo pipefail
# function for updating or inserting a KEY: value pair in a file.
function upsert_env_file {
file=${1} # file will be created if it does not exist.
key=${2} # line must start with the key.
new_value=${3}
# replace the value if it exists, else, append it to the file
if [[ -f $file ]] && grep -q "^$key:" $file; then
# file has the key, update it:
if [[ "$OSTYPE" == "darwin"* ]]; then
# on macOS's sed, the -i flag needs the '' argument to not create
# backup files
sed -i '' -e "/^$key:/s/:\ .*/:\ $new_value/" $file
else
sed -i -e "/^$key:/s/:\ .*/:\ $new_value/" $file
fi
else
# file does not have the key, add it:
echo "$key: $new_value" >> $file
fi
}
ETH_EVM_CHAINID="1337"
BSC_EVM_CHAINID="1397"
ETHEREUM_ROOT="$(pwd)/../ethereum"
ETH_FORGE_BROADCAST="$ETHEREUM_ROOT/broadcast/deploy_contracts.sol/$ETH_EVM_CHAINID/run-latest.json"
BSC_FORGE_BROADCAST="$ETHEREUM_ROOT/broadcast/deploy_contracts.sol/$BSC_EVM_CHAINID/run-latest.json"
ethAddr=$(jq --raw-output -c '.transactions[] | select(.contractName == "ERC1967Proxy") | .contractAddress' $ETH_FORGE_BROADCAST)
bscAddr=$(jq --raw-output -c '.transactions[] | select(.contractName == "ERC1967Proxy") | .contractAddress' $BSC_FORGE_BROADCAST)
upsert_env_file "./.relayer.yaml" "evmContract" $ethAddr
upsert_env_file "./.relayer.yaml" "evm2Contract" $bscAddr

98
offchain-relayer/go.mod Normal file
View File

@ -0,0 +1,98 @@
module github.com/certusone/generic-relayer/offchain-relayer
go 1.17
require (
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
github.com/certusone/wormhole/node v0.0.0-20220921172135-f14835f4b4d8 // indirect
github.com/certusone/wormhole/node/pkg/proto/gossip v0.0.0-00010101000000-000000000000 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/ethereum/go-ethereum v1.10.25 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/gogo/protobuf v1.3.3 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/ipfs/go-cid v0.3.2 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.23.1 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/miguelmota/go-ethereum-hdwallet v0.1.1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multiaddr v0.7.0 // indirect
github.com/multiformats/go-multibase v0.1.1 // indirect
github.com/multiformats/go-multicodec v0.6.0 // indirect
github.com/multiformats/go-multihash v0.2.1 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/prometheus/client_golang v1.13.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/rjeczalik/notify v0.9.1 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.13.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20220921172135-f14835f4b4d8 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc // indirect
google.golang.org/grpc v1.49.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.1.7 // indirect
)
// Needed for cosmos-sdk based chains. See
// https://github.com/cosmos/cosmos-sdk/issues/10925 for more details.
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
// replace the (nonexistant?) version of the sdk pinned in wormhole's go.mod with a recent version that resolves
replace github.com/wormhole-foundation/wormhole/sdk v0.0.0-00010101000000-000000000000 => github.com/wormhole-foundation/wormhole/sdk v0.0.0-20220921172135-f14835f4b4d8
replace github.com/certusone/wormhole/node/pkg/proto/gossip => ./relay/proto/gossip

1008
offchain-relayer/go.sum Normal file

File diff suppressed because it is too large Load Diff

62
offchain-relayer/main.go Normal file
View File

@ -0,0 +1,62 @@
package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/certusone/generic-relayer/offchain-relayer/relay"
)
var cfgFile string
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "offchain-relayer",
Short: "Wormhole relayer for multichain dapp",
}
// main adds all child commands to the root command and sets flags appropriately.
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is {pwd}/.relayer.yaml)")
rootCmd.AddCommand(relay.RelayCmd)
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
wd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(wd)
// Search config in working directory with name ".relayer" (without extension).
viper.AddConfigPath(wd)
viper.SetConfigName(".relayer")
}
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,29 @@
package relay
import (
"unicode"
"go.uber.org/zap/buffer"
"go.uber.org/zap/zapcore"
)
type consoleEncoder struct {
zapcore.Encoder
}
func (e consoleEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
buf, err := e.Encoder.EncodeEntry(entry, fields)
if err != nil {
buf.Free()
return nil, err
}
b := buf.Bytes()
for i := range b {
if unicode.IsControl(rune(b[i])) && !unicode.IsSpace(rune(b[i])) {
b[i] = '\x1A' // Substitute character
}
}
return buf, nil
}

View File

@ -0,0 +1,3 @@
module github.com/certusone/wormhole/node/pkg/proto/gossip
go 1.17

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,910 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: publicrpc/v1/publicrpc.proto
/*
Package publicrpcv1 is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package publicrpcv1
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
func request_PublicRPCService_GetLastHeartbeats_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetLastHeartbeatsRequest
var metadata runtime.ServerMetadata
msg, err := client.GetLastHeartbeats(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GetLastHeartbeats_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetLastHeartbeatsRequest
var metadata runtime.ServerMetadata
msg, err := server.GetLastHeartbeats(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_PublicRPCService_GetSignedVAA_0 = &utilities.DoubleArray{Encoding: map[string]int{"message_id": 0, "emitter_chain": 1, "emitter_address": 2, "sequence": 3}, Base: []int{1, 1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 2, 2, 2, 3, 4, 5}}
)
func request_PublicRPCService_GetSignedVAA_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetSignedVAARequest
var metadata runtime.ServerMetadata
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["message_id.emitter_chain"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
e, err = runtime.Enum(val, ChainID_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
protoReq.MessageId.EmitterChain = ChainID(e)
val, ok = pathParams["message_id.emitter_address"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
}
val, ok = pathParams["message_id.sequence"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedVAA_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetSignedVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GetSignedVAA_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetSignedVAARequest
var metadata runtime.ServerMetadata
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["message_id.emitter_chain"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
e, err = runtime.Enum(val, ChainID_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
protoReq.MessageId.EmitterChain = ChainID(e)
val, ok = pathParams["message_id.emitter_address"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
}
val, ok = pathParams["message_id.sequence"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedVAA_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetSignedVAA(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_PublicRPCService_GetSignedBatchVAA_0 = &utilities.DoubleArray{Encoding: map[string]int{"batch_id": 0, "emitter_chain": 1, "tx_id": 2}, Base: []int{1, 1, 1, 2, 0, 0}, Check: []int{0, 1, 2, 2, 3, 4}}
)
func request_PublicRPCService_GetSignedBatchVAA_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetSignedBatchVAARequest
var metadata runtime.ServerMetadata
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["batch_id.emitter_chain"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.emitter_chain")
}
err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.emitter_chain", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.emitter_chain", err)
}
e, err = runtime.Enum(val, ChainID_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "batch_id.emitter_chain", err)
}
protoReq.BatchId.EmitterChain = ChainID(e)
val, ok = pathParams["batch_id.tx_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.tx_id")
}
err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.tx_id", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.tx_id", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedBatchVAA_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetSignedBatchVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GetSignedBatchVAA_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetSignedBatchVAARequest
var metadata runtime.ServerMetadata
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["batch_id.emitter_chain"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.emitter_chain")
}
err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.emitter_chain", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.emitter_chain", err)
}
e, err = runtime.Enum(val, ChainID_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "batch_id.emitter_chain", err)
}
protoReq.BatchId.EmitterChain = ChainID(e)
val, ok = pathParams["batch_id.tx_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "batch_id.tx_id")
}
err = runtime.PopulateFieldFromPath(&protoReq, "batch_id.tx_id", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "batch_id.tx_id", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GetSignedBatchVAA_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetSignedBatchVAA(ctx, &protoReq)
return msg, metadata, err
}
func request_PublicRPCService_GetCurrentGuardianSet_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetCurrentGuardianSetRequest
var metadata runtime.ServerMetadata
msg, err := client.GetCurrentGuardianSet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GetCurrentGuardianSet_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GetCurrentGuardianSetRequest
var metadata runtime.ServerMetadata
msg, err := server.GetCurrentGuardianSet(ctx, &protoReq)
return msg, metadata, err
}
func request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorGetAvailableNotionalByChainRequest
var metadata runtime.ServerMetadata
msg, err := client.GovernorGetAvailableNotionalByChain(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorGetAvailableNotionalByChainRequest
var metadata runtime.ServerMetadata
msg, err := server.GovernorGetAvailableNotionalByChain(ctx, &protoReq)
return msg, metadata, err
}
func request_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorGetEnqueuedVAAsRequest
var metadata runtime.ServerMetadata
msg, err := client.GovernorGetEnqueuedVAAs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorGetEnqueuedVAAsRequest
var metadata runtime.ServerMetadata
msg, err := server.GovernorGetEnqueuedVAAs(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_PublicRPCService_GovernorIsVAAEnqueued_0 = &utilities.DoubleArray{Encoding: map[string]int{"message_id": 0, "emitter_chain": 1, "emitter_address": 2, "sequence": 3}, Base: []int{1, 1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 2, 2, 2, 3, 4, 5}}
)
func request_PublicRPCService_GovernorIsVAAEnqueued_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorIsVAAEnqueuedRequest
var metadata runtime.ServerMetadata
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["message_id.emitter_chain"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
e, err = runtime.Enum(val, ChainID_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
protoReq.MessageId.EmitterChain = ChainID(e)
val, ok = pathParams["message_id.emitter_address"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
}
val, ok = pathParams["message_id.sequence"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GovernorIsVAAEnqueued_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GovernorIsVAAEnqueued(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GovernorIsVAAEnqueued_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorIsVAAEnqueuedRequest
var metadata runtime.ServerMetadata
var (
val string
e int32
ok bool
err error
_ = err
)
val, ok = pathParams["message_id.emitter_chain"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_chain")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_chain", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
e, err = runtime.Enum(val, ChainID_value)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "message_id.emitter_chain", err)
}
protoReq.MessageId.EmitterChain = ChainID(e)
val, ok = pathParams["message_id.emitter_address"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.emitter_address")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.emitter_address", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.emitter_address", err)
}
val, ok = pathParams["message_id.sequence"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "message_id.sequence")
}
err = runtime.PopulateFieldFromPath(&protoReq, "message_id.sequence", val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "message_id.sequence", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PublicRPCService_GovernorIsVAAEnqueued_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GovernorIsVAAEnqueued(ctx, &protoReq)
return msg, metadata, err
}
func request_PublicRPCService_GovernorGetTokenList_0(ctx context.Context, marshaler runtime.Marshaler, client PublicRPCServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorGetTokenListRequest
var metadata runtime.ServerMetadata
msg, err := client.GovernorGetTokenList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_PublicRPCService_GovernorGetTokenList_0(ctx context.Context, marshaler runtime.Marshaler, server PublicRPCServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq GovernorGetTokenListRequest
var metadata runtime.ServerMetadata
msg, err := server.GovernorGetTokenList(ctx, &protoReq)
return msg, metadata, err
}
// RegisterPublicRPCServiceHandlerServer registers the http handlers for service PublicRPCService to "mux".
// UnaryRPC :call PublicRPCServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterPublicRPCServiceHandlerFromEndpoint instead.
func RegisterPublicRPCServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server PublicRPCServiceServer) error {
mux.Handle("GET", pattern_PublicRPCService_GetLastHeartbeats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetLastHeartbeats", runtime.WithHTTPPathPattern("/v1/heartbeats"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GetLastHeartbeats_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetLastHeartbeats_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GetSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedVAA", runtime.WithHTTPPathPattern("/v1/signed_vaa/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GetSignedVAA_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetSignedVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GetSignedBatchVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA", runtime.WithHTTPPathPattern("/v1/signed_batch_vaa/{batch_id.emitter_chain}/{batch_id.tx_id}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GetSignedBatchVAA_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetSignedBatchVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GetCurrentGuardianSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet", runtime.WithHTTPPathPattern("/v1/guardianset/current"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GetCurrentGuardianSet_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetCurrentGuardianSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorGetAvailableNotionalByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain", runtime.WithHTTPPathPattern("/v1/governor/available_notional_by_chain"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorGetEnqueuedVAAs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs", runtime.WithHTTPPathPattern("/v1/governor/enqueued_vaas"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GovernorGetEnqueuedVAAs_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorIsVAAEnqueued_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued", runtime.WithHTTPPathPattern("/v1/governor/is_vaa_enqueued/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GovernorIsVAAEnqueued_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorIsVAAEnqueued_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorGetTokenList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetTokenList", runtime.WithHTTPPathPattern("/v1/governor/token_list"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_PublicRPCService_GovernorGetTokenList_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorGetTokenList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterPublicRPCServiceHandlerFromEndpoint is same as RegisterPublicRPCServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterPublicRPCServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterPublicRPCServiceHandler(ctx, mux, conn)
}
// RegisterPublicRPCServiceHandler registers the http handlers for service PublicRPCService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterPublicRPCServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterPublicRPCServiceHandlerClient(ctx, mux, NewPublicRPCServiceClient(conn))
}
// RegisterPublicRPCServiceHandlerClient registers the http handlers for service PublicRPCService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "PublicRPCServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "PublicRPCServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "PublicRPCServiceClient" to call the correct interceptors.
func RegisterPublicRPCServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client PublicRPCServiceClient) error {
mux.Handle("GET", pattern_PublicRPCService_GetLastHeartbeats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetLastHeartbeats", runtime.WithHTTPPathPattern("/v1/heartbeats"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GetLastHeartbeats_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetLastHeartbeats_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GetSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedVAA", runtime.WithHTTPPathPattern("/v1/signed_vaa/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GetSignedVAA_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetSignedVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GetSignedBatchVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA", runtime.WithHTTPPathPattern("/v1/signed_batch_vaa/{batch_id.emitter_chain}/{batch_id.tx_id}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GetSignedBatchVAA_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetSignedBatchVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GetCurrentGuardianSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet", runtime.WithHTTPPathPattern("/v1/guardianset/current"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GetCurrentGuardianSet_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GetCurrentGuardianSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorGetAvailableNotionalByChain_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain", runtime.WithHTTPPathPattern("/v1/governor/available_notional_by_chain"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GovernorGetAvailableNotionalByChain_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorGetAvailableNotionalByChain_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorGetEnqueuedVAAs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs", runtime.WithHTTPPathPattern("/v1/governor/enqueued_vaas"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GovernorGetEnqueuedVAAs_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorGetEnqueuedVAAs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorIsVAAEnqueued_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued", runtime.WithHTTPPathPattern("/v1/governor/is_vaa_enqueued/{message_id.emitter_chain}/{message_id.emitter_address}/{message_id.sequence}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GovernorIsVAAEnqueued_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorIsVAAEnqueued_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_PublicRPCService_GovernorGetTokenList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/publicrpc.v1.PublicRPCService/GovernorGetTokenList", runtime.WithHTTPPathPattern("/v1/governor/token_list"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_PublicRPCService_GovernorGetTokenList_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_PublicRPCService_GovernorGetTokenList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_PublicRPCService_GetLastHeartbeats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "heartbeats"}, ""))
pattern_PublicRPCService_GetSignedVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "signed_vaa", "message_id.emitter_chain", "message_id.emitter_address", "message_id.sequence"}, ""))
pattern_PublicRPCService_GetSignedBatchVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "signed_batch_vaa", "batch_id.emitter_chain", "batch_id.tx_id"}, ""))
pattern_PublicRPCService_GetCurrentGuardianSet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "guardianset", "current"}, ""))
pattern_PublicRPCService_GovernorGetAvailableNotionalByChain_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "governor", "available_notional_by_chain"}, ""))
pattern_PublicRPCService_GovernorGetEnqueuedVAAs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "governor", "enqueued_vaas"}, ""))
pattern_PublicRPCService_GovernorIsVAAEnqueued_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "governor", "is_vaa_enqueued", "message_id.emitter_chain", "message_id.emitter_address", "message_id.sequence"}, ""))
pattern_PublicRPCService_GovernorGetTokenList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "governor", "token_list"}, ""))
)
var (
forward_PublicRPCService_GetLastHeartbeats_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GetSignedVAA_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GetSignedBatchVAA_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GetCurrentGuardianSet_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GovernorGetAvailableNotionalByChain_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GovernorGetEnqueuedVAAs_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GovernorIsVAAEnqueued_0 = runtime.ForwardResponseMessage
forward_PublicRPCService_GovernorGetTokenList_0 = runtime.ForwardResponseMessage
)

View File

@ -0,0 +1,359 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package publicrpcv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// PublicRPCServiceClient is the client API for PublicRPCService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type PublicRPCServiceClient interface {
// GetLastHeartbeats returns the last heartbeat received for each guardian node in the
// node's active guardian set. Heartbeats received by nodes not in the guardian set are ignored.
// The heartbeat value is null if no heartbeat has yet been received.
GetLastHeartbeats(ctx context.Context, in *GetLastHeartbeatsRequest, opts ...grpc.CallOption) (*GetLastHeartbeatsResponse, error)
GetSignedVAA(ctx context.Context, in *GetSignedVAARequest, opts ...grpc.CallOption) (*GetSignedVAAResponse, error)
GetSignedBatchVAA(ctx context.Context, in *GetSignedBatchVAARequest, opts ...grpc.CallOption) (*GetSignedBatchVAAResponse, error)
GetCurrentGuardianSet(ctx context.Context, in *GetCurrentGuardianSetRequest, opts ...grpc.CallOption) (*GetCurrentGuardianSetResponse, error)
GovernorGetAvailableNotionalByChain(ctx context.Context, in *GovernorGetAvailableNotionalByChainRequest, opts ...grpc.CallOption) (*GovernorGetAvailableNotionalByChainResponse, error)
GovernorGetEnqueuedVAAs(ctx context.Context, in *GovernorGetEnqueuedVAAsRequest, opts ...grpc.CallOption) (*GovernorGetEnqueuedVAAsResponse, error)
GovernorIsVAAEnqueued(ctx context.Context, in *GovernorIsVAAEnqueuedRequest, opts ...grpc.CallOption) (*GovernorIsVAAEnqueuedResponse, error)
GovernorGetTokenList(ctx context.Context, in *GovernorGetTokenListRequest, opts ...grpc.CallOption) (*GovernorGetTokenListResponse, error)
}
type publicRPCServiceClient struct {
cc grpc.ClientConnInterface
}
func NewPublicRPCServiceClient(cc grpc.ClientConnInterface) PublicRPCServiceClient {
return &publicRPCServiceClient{cc}
}
func (c *publicRPCServiceClient) GetLastHeartbeats(ctx context.Context, in *GetLastHeartbeatsRequest, opts ...grpc.CallOption) (*GetLastHeartbeatsResponse, error) {
out := new(GetLastHeartbeatsResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetLastHeartbeats", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GetSignedVAA(ctx context.Context, in *GetSignedVAARequest, opts ...grpc.CallOption) (*GetSignedVAAResponse, error) {
out := new(GetSignedVAAResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetSignedVAA", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GetSignedBatchVAA(ctx context.Context, in *GetSignedBatchVAARequest, opts ...grpc.CallOption) (*GetSignedBatchVAAResponse, error) {
out := new(GetSignedBatchVAAResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GetCurrentGuardianSet(ctx context.Context, in *GetCurrentGuardianSetRequest, opts ...grpc.CallOption) (*GetCurrentGuardianSetResponse, error) {
out := new(GetCurrentGuardianSetResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GovernorGetAvailableNotionalByChain(ctx context.Context, in *GovernorGetAvailableNotionalByChainRequest, opts ...grpc.CallOption) (*GovernorGetAvailableNotionalByChainResponse, error) {
out := new(GovernorGetAvailableNotionalByChainResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GovernorGetEnqueuedVAAs(ctx context.Context, in *GovernorGetEnqueuedVAAsRequest, opts ...grpc.CallOption) (*GovernorGetEnqueuedVAAsResponse, error) {
out := new(GovernorGetEnqueuedVAAsResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GovernorIsVAAEnqueued(ctx context.Context, in *GovernorIsVAAEnqueuedRequest, opts ...grpc.CallOption) (*GovernorIsVAAEnqueuedResponse, error) {
out := new(GovernorIsVAAEnqueuedResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *publicRPCServiceClient) GovernorGetTokenList(ctx context.Context, in *GovernorGetTokenListRequest, opts ...grpc.CallOption) (*GovernorGetTokenListResponse, error) {
out := new(GovernorGetTokenListResponse)
err := c.cc.Invoke(ctx, "/publicrpc.v1.PublicRPCService/GovernorGetTokenList", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// PublicRPCServiceServer is the server API for PublicRPCService service.
// All implementations must embed UnimplementedPublicRPCServiceServer
// for forward compatibility
type PublicRPCServiceServer interface {
// GetLastHeartbeats returns the last heartbeat received for each guardian node in the
// node's active guardian set. Heartbeats received by nodes not in the guardian set are ignored.
// The heartbeat value is null if no heartbeat has yet been received.
GetLastHeartbeats(context.Context, *GetLastHeartbeatsRequest) (*GetLastHeartbeatsResponse, error)
GetSignedVAA(context.Context, *GetSignedVAARequest) (*GetSignedVAAResponse, error)
GetSignedBatchVAA(context.Context, *GetSignedBatchVAARequest) (*GetSignedBatchVAAResponse, error)
GetCurrentGuardianSet(context.Context, *GetCurrentGuardianSetRequest) (*GetCurrentGuardianSetResponse, error)
GovernorGetAvailableNotionalByChain(context.Context, *GovernorGetAvailableNotionalByChainRequest) (*GovernorGetAvailableNotionalByChainResponse, error)
GovernorGetEnqueuedVAAs(context.Context, *GovernorGetEnqueuedVAAsRequest) (*GovernorGetEnqueuedVAAsResponse, error)
GovernorIsVAAEnqueued(context.Context, *GovernorIsVAAEnqueuedRequest) (*GovernorIsVAAEnqueuedResponse, error)
GovernorGetTokenList(context.Context, *GovernorGetTokenListRequest) (*GovernorGetTokenListResponse, error)
mustEmbedUnimplementedPublicRPCServiceServer()
}
// UnimplementedPublicRPCServiceServer must be embedded to have forward compatible implementations.
type UnimplementedPublicRPCServiceServer struct {
}
func (UnimplementedPublicRPCServiceServer) GetLastHeartbeats(context.Context, *GetLastHeartbeatsRequest) (*GetLastHeartbeatsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetLastHeartbeats not implemented")
}
func (UnimplementedPublicRPCServiceServer) GetSignedVAA(context.Context, *GetSignedVAARequest) (*GetSignedVAAResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSignedVAA not implemented")
}
func (UnimplementedPublicRPCServiceServer) GetSignedBatchVAA(context.Context, *GetSignedBatchVAARequest) (*GetSignedBatchVAAResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSignedBatchVAA not implemented")
}
func (UnimplementedPublicRPCServiceServer) GetCurrentGuardianSet(context.Context, *GetCurrentGuardianSetRequest) (*GetCurrentGuardianSetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCurrentGuardianSet not implemented")
}
func (UnimplementedPublicRPCServiceServer) GovernorGetAvailableNotionalByChain(context.Context, *GovernorGetAvailableNotionalByChainRequest) (*GovernorGetAvailableNotionalByChainResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GovernorGetAvailableNotionalByChain not implemented")
}
func (UnimplementedPublicRPCServiceServer) GovernorGetEnqueuedVAAs(context.Context, *GovernorGetEnqueuedVAAsRequest) (*GovernorGetEnqueuedVAAsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GovernorGetEnqueuedVAAs not implemented")
}
func (UnimplementedPublicRPCServiceServer) GovernorIsVAAEnqueued(context.Context, *GovernorIsVAAEnqueuedRequest) (*GovernorIsVAAEnqueuedResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GovernorIsVAAEnqueued not implemented")
}
func (UnimplementedPublicRPCServiceServer) GovernorGetTokenList(context.Context, *GovernorGetTokenListRequest) (*GovernorGetTokenListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GovernorGetTokenList not implemented")
}
func (UnimplementedPublicRPCServiceServer) mustEmbedUnimplementedPublicRPCServiceServer() {}
// UnsafePublicRPCServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to PublicRPCServiceServer will
// result in compilation errors.
type UnsafePublicRPCServiceServer interface {
mustEmbedUnimplementedPublicRPCServiceServer()
}
func RegisterPublicRPCServiceServer(s grpc.ServiceRegistrar, srv PublicRPCServiceServer) {
s.RegisterService(&PublicRPCService_ServiceDesc, srv)
}
func _PublicRPCService_GetLastHeartbeats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetLastHeartbeatsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GetLastHeartbeats(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GetLastHeartbeats",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GetLastHeartbeats(ctx, req.(*GetLastHeartbeatsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GetSignedVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetSignedVAARequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GetSignedVAA(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GetSignedVAA",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GetSignedVAA(ctx, req.(*GetSignedVAARequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GetSignedBatchVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetSignedBatchVAARequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GetSignedBatchVAA(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GetSignedBatchVAA",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GetSignedBatchVAA(ctx, req.(*GetSignedBatchVAARequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GetCurrentGuardianSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetCurrentGuardianSetRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GetCurrentGuardianSet(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GetCurrentGuardianSet",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GetCurrentGuardianSet(ctx, req.(*GetCurrentGuardianSetRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GovernorGetAvailableNotionalByChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GovernorGetAvailableNotionalByChainRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GovernorGetAvailableNotionalByChain(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GovernorGetAvailableNotionalByChain",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GovernorGetAvailableNotionalByChain(ctx, req.(*GovernorGetAvailableNotionalByChainRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GovernorGetEnqueuedVAAs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GovernorGetEnqueuedVAAsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GovernorGetEnqueuedVAAs(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GovernorGetEnqueuedVAAs",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GovernorGetEnqueuedVAAs(ctx, req.(*GovernorGetEnqueuedVAAsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GovernorIsVAAEnqueued_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GovernorIsVAAEnqueuedRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GovernorIsVAAEnqueued(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GovernorIsVAAEnqueued",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GovernorIsVAAEnqueued(ctx, req.(*GovernorIsVAAEnqueuedRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PublicRPCService_GovernorGetTokenList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GovernorGetTokenListRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PublicRPCServiceServer).GovernorGetTokenList(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/publicrpc.v1.PublicRPCService/GovernorGetTokenList",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PublicRPCServiceServer).GovernorGetTokenList(ctx, req.(*GovernorGetTokenListRequest))
}
return interceptor(ctx, in, info, handler)
}
// PublicRPCService_ServiceDesc is the grpc.ServiceDesc for PublicRPCService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var PublicRPCService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "publicrpc.v1.PublicRPCService",
HandlerType: (*PublicRPCServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetLastHeartbeats",
Handler: _PublicRPCService_GetLastHeartbeats_Handler,
},
{
MethodName: "GetSignedVAA",
Handler: _PublicRPCService_GetSignedVAA_Handler,
},
{
MethodName: "GetSignedBatchVAA",
Handler: _PublicRPCService_GetSignedBatchVAA_Handler,
},
{
MethodName: "GetCurrentGuardianSet",
Handler: _PublicRPCService_GetCurrentGuardianSet_Handler,
},
{
MethodName: "GovernorGetAvailableNotionalByChain",
Handler: _PublicRPCService_GovernorGetAvailableNotionalByChain_Handler,
},
{
MethodName: "GovernorGetEnqueuedVAAs",
Handler: _PublicRPCService_GovernorGetEnqueuedVAAs_Handler,
},
{
MethodName: "GovernorIsVAAEnqueued",
Handler: _PublicRPCService_GovernorIsVAAEnqueued_Handler,
},
{
MethodName: "GovernorGetTokenList",
Handler: _PublicRPCService_GovernorGetTokenList_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "publicrpc/v1/publicrpc.proto",
}

View File

@ -0,0 +1,400 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc (unknown)
// source: spy/v1/spy.proto
package spyv1
import (
v1 "github.com/certusone/generic-relayer/offchain-relayer/relay/proto/publicrpc/v1"
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// A MessageFilter represents an exact match for an emitter.
type EmitterFilter struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Source chain
ChainId v1.ChainID `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3,enum=publicrpc.v1.ChainID" json:"chain_id,omitempty"`
// Hex-encoded (without leading 0x) emitter address.
EmitterAddress string `protobuf:"bytes,2,opt,name=emitter_address,json=emitterAddress,proto3" json:"emitter_address,omitempty"`
}
func (x *EmitterFilter) Reset() {
*x = EmitterFilter{}
if protoimpl.UnsafeEnabled {
mi := &file_spy_v1_spy_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *EmitterFilter) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*EmitterFilter) ProtoMessage() {}
func (x *EmitterFilter) ProtoReflect() protoreflect.Message {
mi := &file_spy_v1_spy_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use EmitterFilter.ProtoReflect.Descriptor instead.
func (*EmitterFilter) Descriptor() ([]byte, []int) {
return file_spy_v1_spy_proto_rawDescGZIP(), []int{0}
}
func (x *EmitterFilter) GetChainId() v1.ChainID {
if x != nil {
return x.ChainId
}
return v1.ChainID(0)
}
func (x *EmitterFilter) GetEmitterAddress() string {
if x != nil {
return x.EmitterAddress
}
return ""
}
type FilterEntry struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to Filter:
// *FilterEntry_EmitterFilter
Filter isFilterEntry_Filter `protobuf_oneof:"filter"`
}
func (x *FilterEntry) Reset() {
*x = FilterEntry{}
if protoimpl.UnsafeEnabled {
mi := &file_spy_v1_spy_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FilterEntry) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FilterEntry) ProtoMessage() {}
func (x *FilterEntry) ProtoReflect() protoreflect.Message {
mi := &file_spy_v1_spy_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FilterEntry.ProtoReflect.Descriptor instead.
func (*FilterEntry) Descriptor() ([]byte, []int) {
return file_spy_v1_spy_proto_rawDescGZIP(), []int{1}
}
func (m *FilterEntry) GetFilter() isFilterEntry_Filter {
if m != nil {
return m.Filter
}
return nil
}
func (x *FilterEntry) GetEmitterFilter() *EmitterFilter {
if x, ok := x.GetFilter().(*FilterEntry_EmitterFilter); ok {
return x.EmitterFilter
}
return nil
}
type isFilterEntry_Filter interface {
isFilterEntry_Filter()
}
type FilterEntry_EmitterFilter struct {
EmitterFilter *EmitterFilter `protobuf:"bytes,1,opt,name=emitter_filter,json=emitterFilter,proto3,oneof"`
}
func (*FilterEntry_EmitterFilter) isFilterEntry_Filter() {}
type SubscribeSignedVAARequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// List of filters to apply to the stream (OR).
// If empty, all messages are streamed.
Filters []*FilterEntry `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`
}
func (x *SubscribeSignedVAARequest) Reset() {
*x = SubscribeSignedVAARequest{}
if protoimpl.UnsafeEnabled {
mi := &file_spy_v1_spy_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SubscribeSignedVAARequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubscribeSignedVAARequest) ProtoMessage() {}
func (x *SubscribeSignedVAARequest) ProtoReflect() protoreflect.Message {
mi := &file_spy_v1_spy_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubscribeSignedVAARequest.ProtoReflect.Descriptor instead.
func (*SubscribeSignedVAARequest) Descriptor() ([]byte, []int) {
return file_spy_v1_spy_proto_rawDescGZIP(), []int{2}
}
func (x *SubscribeSignedVAARequest) GetFilters() []*FilterEntry {
if x != nil {
return x.Filters
}
return nil
}
type SubscribeSignedVAAResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Raw VAA bytes
VaaBytes []byte `protobuf:"bytes,1,opt,name=vaa_bytes,json=vaaBytes,proto3" json:"vaa_bytes,omitempty"`
}
func (x *SubscribeSignedVAAResponse) Reset() {
*x = SubscribeSignedVAAResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_spy_v1_spy_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SubscribeSignedVAAResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubscribeSignedVAAResponse) ProtoMessage() {}
func (x *SubscribeSignedVAAResponse) ProtoReflect() protoreflect.Message {
mi := &file_spy_v1_spy_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubscribeSignedVAAResponse.ProtoReflect.Descriptor instead.
func (*SubscribeSignedVAAResponse) Descriptor() ([]byte, []int) {
return file_spy_v1_spy_proto_rawDescGZIP(), []int{3}
}
func (x *SubscribeSignedVAAResponse) GetVaaBytes() []byte {
if x != nil {
return x.VaaBytes
}
return nil
}
var File_spy_v1_spy_proto protoreflect.FileDescriptor
var file_spy_v1_spy_proto_rawDesc = []byte{
0x0a, 0x10, 0x73, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x70, 0x79, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x06, 0x73, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6a, 0x0a, 0x0d, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65,
0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44,
0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6d, 0x69,
0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x22, 0x57, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x3e, 0x0a, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x6c,
0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x70, 0x79, 0x2e,
0x76, 0x31, 0x2e, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72,
0x48, 0x00, 0x52, 0x0d, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65,
0x72, 0x42, 0x08, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x19, 0x53,
0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41,
0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74,
0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x70, 0x79, 0x2e,
0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x39, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x73, 0x63,
0x72, 0x69, 0x62, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x61, 0x61, 0x5f, 0x62, 0x79, 0x74,
0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x76, 0x61, 0x61, 0x42, 0x79, 0x74,
0x65, 0x73, 0x32, 0x94, 0x01, 0x0a, 0x0d, 0x53, 0x70, 0x79, 0x52, 0x50, 0x43, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
0x62, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x12, 0x21, 0x2e, 0x73, 0x70,
0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x69,
0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
0x2e, 0x73, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x3a,
0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64,
0x5f, 0x76, 0x61, 0x61, 0x3a, 0x01, 0x2a, 0x30, 0x01, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e,
0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f,
0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x70, 0x79, 0x2f, 0x76, 0x31,
0x3b, 0x73, 0x70, 0x79, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_spy_v1_spy_proto_rawDescOnce sync.Once
file_spy_v1_spy_proto_rawDescData = file_spy_v1_spy_proto_rawDesc
)
func file_spy_v1_spy_proto_rawDescGZIP() []byte {
file_spy_v1_spy_proto_rawDescOnce.Do(func() {
file_spy_v1_spy_proto_rawDescData = protoimpl.X.CompressGZIP(file_spy_v1_spy_proto_rawDescData)
})
return file_spy_v1_spy_proto_rawDescData
}
var file_spy_v1_spy_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_spy_v1_spy_proto_goTypes = []interface{}{
(*EmitterFilter)(nil), // 0: spy.v1.EmitterFilter
(*FilterEntry)(nil), // 1: spy.v1.FilterEntry
(*SubscribeSignedVAARequest)(nil), // 2: spy.v1.SubscribeSignedVAARequest
(*SubscribeSignedVAAResponse)(nil), // 3: spy.v1.SubscribeSignedVAAResponse
(v1.ChainID)(0), // 4: publicrpc.v1.ChainID
}
var file_spy_v1_spy_proto_depIdxs = []int32{
4, // 0: spy.v1.EmitterFilter.chain_id:type_name -> publicrpc.v1.ChainID
0, // 1: spy.v1.FilterEntry.emitter_filter:type_name -> spy.v1.EmitterFilter
1, // 2: spy.v1.SubscribeSignedVAARequest.filters:type_name -> spy.v1.FilterEntry
2, // 3: spy.v1.SpyRPCService.SubscribeSignedVAA:input_type -> spy.v1.SubscribeSignedVAARequest
3, // 4: spy.v1.SpyRPCService.SubscribeSignedVAA:output_type -> spy.v1.SubscribeSignedVAAResponse
4, // [4:5] is the sub-list for method output_type
3, // [3:4] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_spy_v1_spy_proto_init() }
func file_spy_v1_spy_proto_init() {
if File_spy_v1_spy_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_spy_v1_spy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*EmitterFilter); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_spy_v1_spy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FilterEntry); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_spy_v1_spy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SubscribeSignedVAARequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_spy_v1_spy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SubscribeSignedVAAResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_spy_v1_spy_proto_msgTypes[1].OneofWrappers = []interface{}{
(*FilterEntry_EmitterFilter)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_spy_v1_spy_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_spy_v1_spy_proto_goTypes,
DependencyIndexes: file_spy_v1_spy_proto_depIdxs,
MessageInfos: file_spy_v1_spy_proto_msgTypes,
}.Build()
File_spy_v1_spy_proto = out.File
file_spy_v1_spy_proto_rawDesc = nil
file_spy_v1_spy_proto_goTypes = nil
file_spy_v1_spy_proto_depIdxs = nil
}

View File

@ -0,0 +1,142 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: spy/v1/spy.proto
/*
Package spyv1 is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package spyv1
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
func request_SpyRPCService_SubscribeSignedVAA_0(ctx context.Context, marshaler runtime.Marshaler, client SpyRPCServiceClient, req *http.Request, pathParams map[string]string) (SpyRPCService_SubscribeSignedVAAClient, runtime.ServerMetadata, error) {
var protoReq SubscribeSignedVAARequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
stream, err := client.SubscribeSignedVAA(ctx, &protoReq)
if err != nil {
return nil, metadata, err
}
header, err := stream.Header()
if err != nil {
return nil, metadata, err
}
metadata.HeaderMD = header
return stream, metadata, nil
}
// RegisterSpyRPCServiceHandlerServer registers the http handlers for service SpyRPCService to "mux".
// UnaryRPC :call SpyRPCServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterSpyRPCServiceHandlerFromEndpoint instead.
func RegisterSpyRPCServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server SpyRPCServiceServer) error {
mux.Handle("POST", pattern_SpyRPCService_SubscribeSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport")
_, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
})
return nil
}
// RegisterSpyRPCServiceHandlerFromEndpoint is same as RegisterSpyRPCServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterSpyRPCServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterSpyRPCServiceHandler(ctx, mux, conn)
}
// RegisterSpyRPCServiceHandler registers the http handlers for service SpyRPCService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterSpyRPCServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterSpyRPCServiceHandlerClient(ctx, mux, NewSpyRPCServiceClient(conn))
}
// RegisterSpyRPCServiceHandlerClient registers the http handlers for service SpyRPCService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "SpyRPCServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SpyRPCServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "SpyRPCServiceClient" to call the correct interceptors.
func RegisterSpyRPCServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SpyRPCServiceClient) error {
mux.Handle("POST", pattern_SpyRPCService_SubscribeSignedVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/spy.v1.SpyRPCService/SubscribeSignedVAA", runtime.WithHTTPPathPattern("/v1:subscribe_signed_vaa"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_SpyRPCService_SubscribeSignedVAA_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_SpyRPCService_SubscribeSignedVAA_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_SpyRPCService_SubscribeSignedVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"v1"}, "subscribe_signed_vaa"))
)
var (
forward_SpyRPCService_SubscribeSignedVAA_0 = runtime.ForwardResponseStream
)

View File

@ -0,0 +1,130 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package spyv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// SpyRPCServiceClient is the client API for SpyRPCService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type SpyRPCServiceClient interface {
// SubscribeSignedVAA returns a stream of signed VAA messages received on the network.
SubscribeSignedVAA(ctx context.Context, in *SubscribeSignedVAARequest, opts ...grpc.CallOption) (SpyRPCService_SubscribeSignedVAAClient, error)
}
type spyRPCServiceClient struct {
cc grpc.ClientConnInterface
}
func NewSpyRPCServiceClient(cc grpc.ClientConnInterface) SpyRPCServiceClient {
return &spyRPCServiceClient{cc}
}
func (c *spyRPCServiceClient) SubscribeSignedVAA(ctx context.Context, in *SubscribeSignedVAARequest, opts ...grpc.CallOption) (SpyRPCService_SubscribeSignedVAAClient, error) {
stream, err := c.cc.NewStream(ctx, &SpyRPCService_ServiceDesc.Streams[0], "/spy.v1.SpyRPCService/SubscribeSignedVAA", opts...)
if err != nil {
return nil, err
}
x := &spyRPCServiceSubscribeSignedVAAClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type SpyRPCService_SubscribeSignedVAAClient interface {
Recv() (*SubscribeSignedVAAResponse, error)
grpc.ClientStream
}
type spyRPCServiceSubscribeSignedVAAClient struct {
grpc.ClientStream
}
func (x *spyRPCServiceSubscribeSignedVAAClient) Recv() (*SubscribeSignedVAAResponse, error) {
m := new(SubscribeSignedVAAResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// SpyRPCServiceServer is the server API for SpyRPCService service.
// All implementations must embed UnimplementedSpyRPCServiceServer
// for forward compatibility
type SpyRPCServiceServer interface {
// SubscribeSignedVAA returns a stream of signed VAA messages received on the network.
SubscribeSignedVAA(*SubscribeSignedVAARequest, SpyRPCService_SubscribeSignedVAAServer) error
mustEmbedUnimplementedSpyRPCServiceServer()
}
// UnimplementedSpyRPCServiceServer must be embedded to have forward compatible implementations.
type UnimplementedSpyRPCServiceServer struct {
}
func (UnimplementedSpyRPCServiceServer) SubscribeSignedVAA(*SubscribeSignedVAARequest, SpyRPCService_SubscribeSignedVAAServer) error {
return status.Errorf(codes.Unimplemented, "method SubscribeSignedVAA not implemented")
}
func (UnimplementedSpyRPCServiceServer) mustEmbedUnimplementedSpyRPCServiceServer() {}
// UnsafeSpyRPCServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to SpyRPCServiceServer will
// result in compilation errors.
type UnsafeSpyRPCServiceServer interface {
mustEmbedUnimplementedSpyRPCServiceServer()
}
func RegisterSpyRPCServiceServer(s grpc.ServiceRegistrar, srv SpyRPCServiceServer) {
s.RegisterService(&SpyRPCService_ServiceDesc, srv)
}
func _SpyRPCService_SubscribeSignedVAA_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeSignedVAARequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(SpyRPCServiceServer).SubscribeSignedVAA(m, &spyRPCServiceSubscribeSignedVAAServer{stream})
}
type SpyRPCService_SubscribeSignedVAAServer interface {
Send(*SubscribeSignedVAAResponse) error
grpc.ServerStream
}
type spyRPCServiceSubscribeSignedVAAServer struct {
grpc.ServerStream
}
func (x *spyRPCServiceSubscribeSignedVAAServer) Send(m *SubscribeSignedVAAResponse) error {
return x.ServerStream.SendMsg(m)
}
// SpyRPCService_ServiceDesc is the grpc.ServiceDesc for SpyRPCService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var SpyRPCService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "spy.v1.SpyRPCService",
HandlerType: (*SpyRPCServiceServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "SubscribeSignedVAA",
Handler: _SpyRPCService_SubscribeSignedVAA_Handler,
ServerStreams: true,
},
},
Metadata: "spy/v1/spy.proto",
}

View File

@ -0,0 +1,708 @@
package relay
import (
"context"
"crypto/ecdsa"
"fmt"
"io"
"log"
"math/big"
"net/http"
_ "net/http/pprof" // #nosec G108 we are using a custom router (`router := mux.NewRouter()`) and thus not automatically expose pprof.
"os"
"strconv"
"strings"
"go.uber.org/zap/zapcore"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus/promhttp"
spyv1 "github.com/certusone/generic-relayer/offchain-relayer/relay/proto/spy/v1"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
eth_common "github.com/ethereum/go-ethereum/common"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
ipfslog "github.com/ipfs/go-log/v2"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/certusone/wormhole/node/pkg/common"
"github.com/certusone/wormhole/node/pkg/devnet"
"github.com/certusone/wormhole/node/pkg/readiness"
"github.com/certusone/wormhole/node/pkg/supervisor"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/certusone/generic-relayer/offchain-relayer/relay/ethereum/core_relayer"
)
const TARGET_GAS_LIMIT = 500000
// keep the data for each chain together in a struct
type ChainDef struct {
RPCAddr *string
ContractAddr eth_common.Address
WormholeChainID vaa.ChainID
NetworkID *string
}
// a map of chains supplied as args, so we can lookup an iterate through
type Chains map[vaa.ChainID]*ChainDef
var (
dataDir *string
statusAddr *string
senderKeyPath *string
// senderKeyMnemonic *string
senderKeyHex *string
evmRPC *string
evmContract *string
evmWormholeChainID *uint16
evmNetworkID *string
evm2RPC *string
evm2Contract *string
evm2WormholeChainID *uint16
evm2NetworkID *string
logLevel *string
unsafeDevMode *bool
testnetMode *bool
nodeName *string
spyRPC *string
guardianRPC *string
)
func init() {
statusAddr = RelayCmd.Flags().String("statusAddr", viper.GetString("statusAddr"), "Listen address for status server (disabled if blank)")
dataDir = RelayCmd.Flags().String("dataDir", viper.GetString("dataDir"), "Data directory")
senderKeyPath = RelayCmd.Flags().String("senderKeyPath", viper.GetString("senderKeyPath"), "Path to sender key (required)")
// senderKeyMnemonic = RelayCmd.Flags().String("senderKeyMnemonic", "", "Path to sender key (required)")
senderKeyHex = RelayCmd.Flags().String("senderKeyHex", viper.GetString("senderKeyHex"), "Sender private key hex (required)")
evmRPC = RelayCmd.Flags().String("evmRPC", viper.GetString("evmRPC"), "EVM RPC URL")
evmContract = RelayCmd.Flags().String("evmContract", viper.GetString("evmContract"), "EVM contract address")
evmWormholeChainID = RelayCmd.Flags().Uint16("evmWormholeChainID", viper.GetUint16("evmWormholeChainID"), "Wormhole ChainID")
evmNetworkID = RelayCmd.Flags().String("evmNetworkID", viper.GetString("evmNetworkID"), "The network's ChainID")
evm2RPC = RelayCmd.Flags().String("evm2RPC", viper.GetString("evm2RPC"), "EVM RPC URL")
evm2Contract = RelayCmd.Flags().String("evm2Contract", viper.GetString("evm2Contract"), "EVM contract address")
evm2WormholeChainID = RelayCmd.Flags().Uint16("evm2WormholeChainID", viper.GetUint16("evm2WormholeChainID"), "Wormhole ChainID")
evm2NetworkID = RelayCmd.Flags().String("evm2NetworkID", viper.GetString("evm2NetworkID"), "The network's ChainID")
logLevel = RelayCmd.Flags().String("logLevel", viper.GetString("logLevel"), "Logging level (debug, info, warn, error, dpanic, panic, fatal)")
unsafeDevMode = RelayCmd.Flags().Bool("unsafeDevMode", viper.GetBool("unsafeDevMode"), "Launch node in unsafe, deterministic devnet mode")
testnetMode = RelayCmd.Flags().Bool("testnetMode", viper.GetBool("testnetMode"), "Launch node in testnet mode (enables testnet-only features like Ropsten)")
nodeName = RelayCmd.Flags().String("nodeName", viper.GetString("nodeName"), "Node name to announce in gossip heartbeats")
spyRPC = RelayCmd.Flags().String("spyRPC", viper.GetString("spyRPC"), "Listen address of public spy gRPC interface")
guardianRPC = RelayCmd.Flags().String("guardianRPC", viper.GetString("guardianRPC"), "Adress of public guardian gRPC interface")
}
var (
rootCtx context.Context
rootCtxCancel context.CancelFunc
)
const (
spyReadiness readiness.Component = "spyReadiness"
)
const devwarning = `
+++++++++++++++++++++++++++++++++++++++++++++++++++
| NODE IS RUNNING IN INSECURE DEVELOPMENT MODE |
| |
| Do not use --unsafeDevMode in prod. |
+++++++++++++++++++++++++++++++++++++++++++++++++++
`
var RelayCmd = &cobra.Command{
Use: "relay",
Short: "Run the relayer",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// You can bind cobra and viper in a few locations, but PersistencePreRunE on the root command works well
bindFlags(cmd, viper.GetViper())
return nil
},
Run: runRelay,
}
// Take the values read by viper from the config file ".relay.yaml" and apply them to cmd.
// Bind each cobra flag to its associated viper configuration (config file and environment variable).
func bindFlags(cmd *cobra.Command, v *viper.Viper) {
envPrefix := "RELAY"
cmd.Flags().VisitAll(func(f *pflag.Flag) {
// Environment variables can't have dashes in them, so bind them to their equivalent
// keys with underscores, e.g. --favorite-color to STING_FAVORITE_COLOR
if strings.Contains(f.Name, "-") {
envVarSuffix := strings.ToUpper(strings.ReplaceAll(f.Name, "-", "_"))
v.BindEnv(f.Name, fmt.Sprintf("%s_%s", envPrefix, envVarSuffix))
}
// Apply the viper config value to the flag when the flag is not set and viper has a value
if !f.Changed && v.IsSet(f.Name) {
val := v.Get(f.Name)
cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val))
}
})
}
// 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"
func runRelay(cmd *cobra.Command, args []string) {
if Build == "dev" && !*unsafeDevMode {
fmt.Println("This is a development build. --unsafeDevMode must be enabled.")
os.Exit(1)
}
if *unsafeDevMode {
fmt.Print(devwarning)
}
if *testnetMode {
common.LockMemory()
common.SetRestrictiveUmask()
}
// Refuse to run as root in production mode.
if !*unsafeDevMode && os.Geteuid() == 0 {
fmt.Println("can't run as uid 0")
os.Exit(1)
}
// 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)
}
logger := zap.New(zapcore.NewCore(
consoleEncoder{zapcore.NewConsoleEncoder(
zap.NewDevelopmentEncoderConfig())},
zapcore.AddSync(zapcore.Lock(os.Stderr)),
zap.NewAtomicLevelAt(zapcore.Level(lvl))))
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)
}
// Override the default go-log config, which uses a magic environment variable.
ipfslog.SetAllLoggers(lvl)
// Register components for readiness checks.
readiness.RegisterComponent(spyReadiness)
if *statusAddr != "" {
// Use a custom routing instead of using http.DefaultServeMux directly to avoid accidentally exposing packages
// that register themselves with it by default (like pprof).
router := mux.NewRouter()
// pprof server. NOT necessarily safe to expose publicly - only enable it in dev mode to avoid exposing it by
// accident. There's benefit to having pprof enabled on production nodes, but we would likely want to expose it
// via a dedicated port listening on localhost, or via the admin UNIX socket.
if *unsafeDevMode {
// Pass requests to http.DefaultServeMux, which pprof automatically registers with as an import side-effect.
router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
}
// Simple endpoint exposing node readiness (safe to expose to untrusted clients)
router.HandleFunc("/readyz", readiness.Handler)
// Prometheus metrics (safe to expose to untrusted clients)
router.Handle("/metrics", promhttp.Handler())
go func() {
logger.Info(fmt.Sprintf("status server listening on [::]:%s", *statusAddr))
// SECURITY: If making changes, ensure that we always do `router := mux.NewRouter()` before this to avoid accidentally exposing pprof
logger.Error("status server crashed", zap.Error(http.ListenAndServe(*statusAddr, router)))
}()
}
if *senderKeyPath == "" && !*unsafeDevMode {
logger.Fatal("Please specify --senderKeyPath")
}
if *dataDir == "" && !*unsafeDevMode {
logger.Fatal("Please specify --dataDir")
}
// first chain
if *evmRPC == "" {
logger.Fatal("Please specify --evmRPC")
}
if *evmContract == "" {
logger.Fatal("Please specify --evmContract")
}
if evmWormholeChainID == nil || *evm2WormholeChainID == 0 {
logger.Fatal("Please specify --evmWormholeChainID")
}
if *evmNetworkID == "" {
logger.Fatal("Please specify --evmNetworkID")
}
// second
if *evm2RPC == "" {
logger.Fatal("Please specify --evm2RPC")
}
if *evm2Contract == "" {
logger.Fatal("Please specify --evm2Contract")
}
if evm2WormholeChainID == nil || *evm2WormholeChainID == 0 {
logger.Fatal("Please specify --evm2WormholeChainID")
}
if *evm2NetworkID == "" {
logger.Fatal("Please specify --evm2NetworkID")
}
if *nodeName == "" {
logger.Fatal("Please specify --nodeName")
}
if *spyRPC == "" {
logger.Fatal("Please specify --spyRPC")
}
if *guardianRPC == "" {
logger.Fatal("Please specify --guardianRPC")
}
// collect the networks into a map indexed by chainID.
// make a map of the chains that we can relay to.
// key by the ChainID so we can check this map with values from VAAs.
var connectedChains Chains = Chains{}
// could do this better by making the Cobra args accept an iterable with this info.
// first chain
var evmChainID vaa.ChainID = vaa.ChainID(*evmWormholeChainID)
connectedChains[evmChainID] = &ChainDef{
RPCAddr: evmRPC,
ContractAddr: eth_common.HexToAddress(strings.TrimPrefix(*evmContract, "0x")),
WormholeChainID: evmChainID,
NetworkID: evmNetworkID,
}
// second chain
var evm2ChainID vaa.ChainID = vaa.ChainID(*evm2WormholeChainID)
connectedChains[evm2ChainID] = &ChainDef{
RPCAddr: evm2RPC,
ContractAddr: eth_common.HexToAddress(strings.TrimPrefix(*evm2Contract, "0x")),
WormholeChainID: evm2ChainID,
NetworkID: evm2NetworkID,
}
// read the private key passed in.
// start with the deterministic devent key, override it if the user passes one in.
var sk *ecdsa.PrivateKey
if *unsafeDevMode {
acct := devnet.DeriveAccount(uint(2))
sk, err = devnet.Wallet().PrivateKey(acct)
if err != nil {
logger.Fatal("failed to derive devnet sender key", zap.Error(err))
}
}
if *senderKeyHex != "" {
sk, err = ethcrypto.HexToECDSA(*senderKeyHex)
if err != nil {
logger.Fatal("failed transform senderKeyHex to ECDSA", zap.Error(err))
}
}
if *senderKeyPath != "" {
sk, err = ethcrypto.LoadECDSA(*senderKeyPath)
if err != nil {
logger.Fatal("failed load senderKeyPath.",
zap.String("senderKeyPath", *senderKeyPath),
zap.Error(err))
}
}
if sk == nil {
logger.Fatal("no sender key supplied, exiting.")
}
guardianAddr := ethcrypto.PubkeyToAddress(sk.PublicKey).String()
logger.Info("Loaded guardian key", zap.String(
"address", guardianAddr))
// Relay's main lifecycle context.
rootCtx, rootCtxCancel = context.WithCancel(context.Background())
defer rootCtxCancel()
// setup channels for passing VAAs around
// Inbound VAA observations
obsvC := make(chan []byte, 50)
// Outbound VAA queue
sendC := make(chan []byte)
// Redirect ipfs logs to plain zap
ipfslog.SetPrimaryCore(logger.Core())
// setup the supervisor that will start/watch/reboot the individual parts of the application.
supervisor.New(rootCtx, logger, func(ctx context.Context) error {
if err := supervisor.Run(ctx, "spywatch",
spyWatcherRunnable(spyRPC, spyReadiness, obsvC)); err != nil {
return err
}
if err := supervisor.Run(ctx, "inspectVAA",
inspectVAA(obsvC, sendC, connectedChains)); err != nil {
return err
}
if err := supervisor.Run(ctx, "relayVAA",
relayVAA(sendC, connectedChains, sk)); err != nil {
return err
}
logger.Info("Started internal services")
<-ctx.Done()
return nil
},
// It's safer to crash and restart the process in case we encounter a panic,
// rather than attempting to reschedule the runnable.
supervisor.WithPropagatePanic)
<-rootCtx.Done()
logger.Info("root context cancelled, exiting...")
}
// relayVAA sends the batchVAAs it recieves to the deliver function of the target chain
func relayVAA(sendC chan []byte, networks Chains, senderKey *ecdsa.PrivateKey) supervisor.Runnable {
return func(ctx context.Context) error {
logger := supervisor.Logger(ctx)
logger.Debug("inspectVAA going to fire off the supervisor.SignalHealthy")
supervisor.Signal(ctx, supervisor.SignalHealthy)
for {
select {
case <-ctx.Done():
logger.Debug(("inspectVAA recieved cts.Done(), going to return nil"))
return nil
case b := <-sendC:
// ultimatly calls deliver on the relayer contract
batchVAA, err := UnmarshalBatch(b)
if err != nil {
// not a batchVAA, continue, break?
logger.Info("failed to UnmarshalBatch, must not be a batchVAA.", zap.Error(err))
continue
}
src := batchVAA.Observations[0].Observation.EmitterChain
srcChain := vaa.ChainID(src)
if _, ok := networks[srcChain]; !ok {
logger.Info("no network config for this source.", zap.String("src_chain", src.String()))
continue
}
srcNetwork := networks[srcChain]
relayerAddr := srcNetwork.ContractAddr
logger.Info("relayerAddr", zap.String("relayer_addr_hex", relayerAddr.String()))
// find the deliveryVAA among the observations in the batch
var deliveryVAAIndex int = -1
for i, o := range batchVAA.Observations {
logger.Info("observation ",
zap.Int("index", i),
zap.String("emitter_address_hex", eth_common.BytesToAddress(o.Observation.EmitterAddress[:]).Hex()))
if eth_common.BytesToAddress(o.Observation.EmitterAddress[:]) == relayerAddr {
// this is a batch with a relay VAA
deliveryVAAIndex = i
}
}
logger.Info("deliveryVAAIndex", zap.Int("deliveryVAAIndex", deliveryVAAIndex))
if deliveryVAAIndex < 0 {
logger.Info("could not find the deliveryVAAIndex, continuing.")
continue
} else {
logger.Info("found deliveryVAA among the observations", zap.Int("deliveryVAAIndex", deliveryVAAIndex))
}
// construct the delivery params
deliveryParams := core_relayer.CoreRelayerStructsTargetDeliveryParameters{
EncodedVM: b,
DeliveryIndex: uint8(deliveryVAAIndex),
TargetCallGasOverride: uint32(TARGET_GAS_LIMIT),
}
relayRequestVAA := batchVAA.Observations[deliveryVAAIndex]
// create the client of the source chain
conn, err := ethclient.Dial(*srcNetwork.RPCAddr)
if err != nil {
logger.Fatal("Failed to connect to the srcNetwork with ethclient: %", zap.Error(err))
}
// instantiate the CoreRelayer of the source chain
srcRelayer, err := core_relayer.NewCoreRelayer(srcNetwork.ContractAddr, conn)
if err != nil {
logger.Error("failed getting NewCoreRelayer for source", zap.Error(err))
continue
}
// create delivery instructions from the source chain's contract
deliveryInstructions, err := srcRelayer.DecodeDeliveryInstructions(nil, relayRequestVAA.Observation.Payload)
if err != nil {
logger.Error("failed to decode delivery instructions", zap.Error(err))
}
logger.Debug("Decoded DeliveryInstructions!",
zap.String("from_chain", vaa.ChainID(deliveryInstructions.FromChain).String()),
zap.String("from_address", eth_common.BytesToHash(deliveryInstructions.FromAddress[:]).Hex()),
zap.String("target_chain", vaa.ChainID(deliveryInstructions.TargetChain).String()),
zap.String("target_address", eth_common.BytesToHash(deliveryInstructions.TargetAddress[:]).Hex()),
)
destChain := vaa.ChainID(deliveryInstructions.TargetChain)
if _, ok := networks[destChain]; !ok {
// we do not have the network to relay this message
logger.Info("recieved relay request for unsuppported chain, doing nothing",
zap.String("dest_chain", destChain.String()))
continue
}
// create the client connection to the target chain
destNetwork := networks[destChain]
destConn, err := ethclient.Dial(*destNetwork.RPCAddr)
if err != nil {
logger.Error("failed to connect to target RPC",
zap.String("target_chain", destNetwork.WormholeChainID.String()),
zap.Error(err))
}
networkID, err := strconv.Atoi(*destNetwork.NetworkID)
if err != nil {
logger.Fatal("failed to convert destNetwork.NetworkID to int.", zap.Error(err))
}
networkID64 := int64(networkID)
// create a transactor for the target chain
auth, err := bind.NewKeyedTransactorWithChainID(senderKey, big.NewInt(networkID64))
if err != nil {
logger.Fatal("failed to create NewKeyedTransactorWithChainID", zap.Error(err))
}
// create the contract instance of the target chain
destRelayer, err := core_relayer.NewCoreRelayerTransactor(destNetwork.ContractAddr, destConn)
if err != nil {
logger.Error("failed getting NewCoreRelayer for target",
zap.String("contract_addr", destNetwork.ContractAddr.Hex()),
zap.Error(err))
continue
}
// send the transaction to the target chain
tx, err := destRelayer.Deliver(auth, deliveryParams)
if err != nil {
logger.Error("failed delivering to destination",
zap.Error(err))
continue
}
logger.Info("successfully relayed VAA!", zap.String("tx_hash", tx.Hash().String()))
}
}
}
}
// inpects SignedVAAs and determines if they should be relayed.
func inspectVAA(obsvC chan []byte, sendC chan []byte, networks Chains) supervisor.Runnable {
return func(ctx context.Context) error {
logger := supervisor.Logger(ctx)
logger.Debug("inspectVAA going to fire off the supervisor.SignalHealthy")
supervisor.Signal(ctx, supervisor.SignalHealthy)
for {
select {
case <-ctx.Done():
logger.Debug(("inspectVAA recieved cts.Done(), going to return nil"))
return nil
case b := <-obsvC:
batchVAA, err := UnmarshalBatch(b)
if err != nil {
// this log is too noisy.
// logger.Debug("failed to UnmarshalBatch, must not be a batchVAA.", zap.Error(err))
continue
}
logger.Info("successfully unmarshaled BatchVAA!")
src := batchVAA.Observations[0].Observation.EmitterChain
srcChain := vaa.ChainID(src)
if _, ok := networks[srcChain]; !ok {
logger.Info("no network config for this source.", zap.String("src_chain", src.String()))
continue
} else {
logger.Info("found network config for source", zap.String("src_chain", src.String()))
}
srcNetwork := networks[srcChain]
relayerAddr := srcNetwork.ContractAddr
logger.Info("relayerAddr", zap.String("relayer_addr_hex", relayerAddr.String()))
// find the deliveryVAA among the observations in the batch
var deliveryVAAIndex int = -1
for i, o := range batchVAA.Observations {
logger.Info("observation ",
zap.Int("index", i),
zap.String("emitter_address_hex", eth_common.BytesToAddress(o.Observation.EmitterAddress[:]).Hex()))
if eth_common.BytesToAddress(o.Observation.EmitterAddress[:]) == relayerAddr {
// this is a batch with a relay VAA
deliveryVAAIndex = i
}
}
logger.Info("deliveryVAAIndex", zap.Int("deliveryVAAIndex", deliveryVAAIndex))
if deliveryVAAIndex < 0 {
logger.Info("could not find the deliveryVAAIndex, continuing.")
continue
} else {
logger.Info("found deliveryVAA among the observations", zap.Int("deliveryVAAIndex", deliveryVAAIndex))
}
relayRequestVAA := batchVAA.Observations[deliveryVAAIndex]
// create the network client for the source chain
conn, err := ethclient.Dial(*srcNetwork.RPCAddr)
if err != nil {
logger.Fatal("Failed to connect to the srcNetwork with ethclient: %", zap.Error(err))
}
// instantiate the CoreRelayer contract that produced the VAA
srcRelayer, err := core_relayer.NewCoreRelayer(srcNetwork.ContractAddr, conn)
if err != nil {
logger.Error("failed getting NewCoreRelayer for source", zap.Error(err))
continue
}
// create the delivery instructions from the source chain contract
deliveryInstructions, err := srcRelayer.DecodeDeliveryInstructions(nil, relayRequestVAA.Observation.Payload)
if err != nil {
logger.Error("failed to decode delivery instructions", zap.Error(err))
}
logger.Debug("Decoded DeliveryInstructions!",
zap.String("from_chain", vaa.ChainID(deliveryInstructions.FromChain).String()),
zap.String("from_address", eth_common.BytesToHash(deliveryInstructions.FromAddress[:]).Hex()),
zap.String("target_chain", vaa.ChainID(deliveryInstructions.TargetChain).String()),
zap.String("target_address", eth_common.BytesToHash(deliveryInstructions.TargetAddress[:]).Hex()),
)
// check that we have the network connection info for the target chain of this relay request
destChain := vaa.ChainID(deliveryInstructions.TargetChain)
if _, ok := networks[destChain]; !ok {
// we do not have the network to relay this message
logger.Info("recieved relay request for unsuppported chain, doing nothing",
zap.String("dest_chain", destChain.String()))
continue
}
// the relay VAA looks good, and we verified we have everything we need to relay this VAA,
// send it!
sendC <- b
logger.Info("sent the VAA to sendC.")
}
}
}
}
// connects to the guardian's spy and recieves a stream of SignedVAAs, pass them
// along to the obsvC channel.
func spyWatcherRunnable(
spyAddr *string,
readyHandle readiness.Component,
obsvC chan []byte,
) supervisor.Runnable {
return func(ctx context.Context) error {
logger := supervisor.Logger(ctx)
_, client, err := getSpyRPCServiceClient(ctx, *spyAddr)
if err != nil {
logger.Fatal("failed to getSpyRPCServiceClient", zap.Error(err))
}
req := &spyv1.SubscribeSignedVAARequest{Filters: []*spyv1.FilterEntry{}}
stream, err := client.SubscribeSignedVAA(ctx, req)
if err != nil {
logger.Fatal("failed subscribing to SpyRPCClient", zap.Error(err))
}
logger.Debug("spyWatcherRunnable going to fire off the supervisor.SignalHealthy")
supervisor.Signal(ctx, supervisor.SignalHealthy)
logger.Debug("spyWatchRunnable going to fire off 'ready' to the readiness component")
readiness.SetReady(readyHandle)
for {
// recieve is a blocking call, it will keep recieving/looping until the pipe breaks.
signedVAA, err := stream.Recv()
if err == io.EOF {
// connection has closed.
// probably want to kill the thread so the supervisor will start a new one?
// or does this break do enough (exits the for loop, so nil is returned?)
logger.Info("the SignedVAA stream has closed, err == io.EOF. going to break.")
break
}
if err != nil {
logger.Fatal("SubscribeSignedVAA returned an error", zap.Error(err))
}
logger.Debug("going to push signedVaa bytes onto the obsvC")
b := signedVAA.VaaBytes
obsvC <- b
}
logger.Debug("spyWatcherRunnable is going to return a value to the supervisor")
return nil
}
}
func getSpyRPCServiceClient(ctx context.Context, addr string) (*grpc.ClientConn, spyv1.SpyRPCServiceClient, error) {
conn, err := grpc.DialContext(ctx, addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("failed to connect to %s: %v", addr, err)
}
c := spyv1.NewSpyRPCServiceClient(conn)
return conn, c, err
}

View File

@ -0,0 +1,954 @@
package relay
//
// NOTE:
// this file is structs.go, formally from the guardian codebase,
// now from /sdk/. This file is duplicated here temporarily
// untill the batchVAA changes land on dev.v2. Once the changes land,
// this file can be deleted and replaced with an import.
//
//
import (
"bytes"
"crypto/ecdsa"
"encoding/binary"
"encoding/hex"
"fmt"
"io"
"math/big"
"strings"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
type (
// VAA is a verifiable action approval of the Wormhole protocol
VAA struct {
// Version of the VAA schema
Version uint8
// GuardianSetIndex is the index of the guardian set that signed this VAA
GuardianSetIndex uint32
// SignatureData is the signature of the guardian set
Signatures []*Signature
// Timestamp when the VAA was created
Timestamp time.Time
// Nonce of the VAA
Nonce uint32
// Sequence of the VAA
Sequence uint64
/// ConsistencyLevel of the VAA
ConsistencyLevel uint8
// EmitterChain the VAA was emitted on
EmitterChain ChainID
// EmitterAddress of the contract that emitted the Message
EmitterAddress Address
// Payload of the message
Payload []byte
}
BatchVAA struct {
// Version of the VAA schema
Version uint8
// GuardianSetIndex is the index of the guardian set that signed this VAA
GuardianSetIndex uint32
// SignatureData is the signature of the guardian set
Signatures []*Signature
// EmitterChain the VAAs were emitted on
EmitterChain ChainID
// The chain-native identifier of the transaction that created the batch VAA.
TransactionID common.Hash
// array of Observation VAA hashes
Hashes []common.Hash
// Observations in the batch
Observations []*Observation
}
// ChainID of a Wormhole chain
ChainID uint16
// Action of a VAA
Action uint8
// Address is a Wormhole protocol address, it contains the native chain's address. If the address data type of a
// chain is < 32bytes the value is zero-padded on the left.
Address [32]byte
// Signature of a single guardian
Signature struct {
// Index of the validator
Index uint8
// Signature data
Signature SignatureData
}
SignatureData [65]byte
Observation struct {
// Index of the observation in a Batch array
Index uint8
// Signed Observation data
Observation *VAA
}
TransferPayloadHdr struct {
Type uint8
Amount *big.Int
OriginAddress Address
OriginChain ChainID
TargetAddress Address
TargetChain ChainID
}
)
func (a Address) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, a)), nil
}
func (a Address) String() string {
return hex.EncodeToString(a[:])
}
func (a Address) Bytes() []byte {
return a[:]
}
func (a SignatureData) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, a)), nil
}
func (a SignatureData) String() string {
return hex.EncodeToString(a[:])
}
func (c ChainID) String() string {
switch c {
case ChainIDUnset:
return "unset"
case ChainIDSolana:
return "solana"
case ChainIDEthereum:
return "ethereum"
case ChainIDTerra:
return "terra"
case ChainIDBSC:
return "bsc"
case ChainIDPolygon:
return "polygon"
case ChainIDAvalanche:
return "avalanche"
case ChainIDOasis:
return "oasis"
case ChainIDAurora:
return "aurora"
case ChainIDFantom:
return "fantom"
case ChainIDAlgorand:
return "algorand"
case ChainIDNear:
return "near"
case ChainIDEthereumRopsten:
return "ethereum-ropsten"
case ChainIDKarura:
return "karura"
case ChainIDAcala:
return "acala"
case ChainIDKlaytn:
return "klaytn"
case ChainIDCelo:
return "celo"
case ChainIDMoonbeam:
return "moonbeam"
case ChainIDNeon:
return "neon"
case ChainIDTerra2:
return "terra2"
case ChainIDInjective:
return "injective"
case ChainIDPythNet:
return "pythnet"
default:
return fmt.Sprintf("unknown chain ID: %d", c)
}
}
func ChainIDFromString(s string) (ChainID, error) {
s = strings.ToLower(s)
switch s {
case "solana":
return ChainIDSolana, nil
case "ethereum":
return ChainIDEthereum, nil
case "terra":
return ChainIDTerra, nil
case "bsc":
return ChainIDBSC, nil
case "polygon":
return ChainIDPolygon, nil
case "avalanche":
return ChainIDAvalanche, nil
case "oasis":
return ChainIDOasis, nil
case "aurora":
return ChainIDAurora, nil
case "fantom":
return ChainIDFantom, nil
case "algorand":
return ChainIDAlgorand, nil
case "near":
return ChainIDNear, nil
case "ethereum-ropsten":
return ChainIDEthereumRopsten, nil
case "karura":
return ChainIDKarura, nil
case "acala":
return ChainIDAcala, nil
case "klaytn":
return ChainIDKlaytn, nil
case "celo":
return ChainIDCelo, nil
case "moonbeam":
return ChainIDMoonbeam, nil
case "neon":
return ChainIDNeon, nil
case "terra2":
return ChainIDTerra2, nil
case "injective":
return ChainIDInjective, nil
case "pythnet":
return ChainIDPythNet, nil
default:
return ChainIDUnset, fmt.Errorf("unknown chain ID: %s", s)
}
}
const (
ChainIDUnset ChainID = 0
// ChainIDSolana is the ChainID of Solana
ChainIDSolana ChainID = 1
// ChainIDEthereum is the ChainID of Ethereum
ChainIDEthereum ChainID = 2
// ChainIDTerra is the ChainID of Terra
ChainIDTerra ChainID = 3
// ChainIDBSC is the ChainID of Binance Smart Chain
ChainIDBSC ChainID = 4
// ChainIDPolygon is the ChainID of Polygon
ChainIDPolygon ChainID = 5
// ChainIDAvalanche is the ChainID of Avalanche
ChainIDAvalanche ChainID = 6
// ChainIDOasis is the ChainID of Oasis
ChainIDOasis ChainID = 7
// ChainIDAlgorand is the ChainID of Algorand
ChainIDAlgorand ChainID = 8
// ChainIDAurora is the ChainID of Aurora
ChainIDAurora ChainID = 9
// ChainIDFantom is the ChainID of Fantom
ChainIDFantom ChainID = 10
// ChainIDKarura is the ChainID of Karura
ChainIDKarura ChainID = 11
// ChainIDAcala is the ChainID of Acala
ChainIDAcala ChainID = 12
// ChainIDKlaytn is the ChainID of Klaytn
ChainIDKlaytn ChainID = 13
// ChainIDCelo is the ChainID of Celo
ChainIDCelo ChainID = 14
// ChainIDNear is the ChainID of Near
ChainIDNear ChainID = 15
// ChainIDMoonbeam is the ChainID of Moonbeam
ChainIDMoonbeam ChainID = 16
// ChainIDNeon is the ChainID of Neon
ChainIDNeon ChainID = 17
// ChainIDTerra2 is the ChainID of Terra 2
ChainIDTerra2 ChainID = 18
// ChainIDInjective is the ChainID of Injective
ChainIDInjective ChainID = 19
// ChainIDPythNet is the ChainID of PythNet
ChainIDPythNet ChainID = 26
// ChainIDEthereumRopsten is the ChainID of Ethereum Ropsten
ChainIDEthereumRopsten ChainID = 10001
// Minimum VAA size is derrived from the following assumptions:
// HEADER
// - Supported VAA Version (1 byte)
// - Guardian Set Index (4 bytes)
// - Length of Signatures (1 byte) <== assume no signatures
// - Actual Signatures (0 bytes)
// BODY
// - timestamp (4 bytes)
// - nonce (4 bytes)
// - emitter chain (2 bytes)
// - emitter address (32 bytes)
// - sequence (8 bytes)
// - consistency level (1 byte)
// - payload (0 bytes)
// BATCH
// - Length of Observation Hashes (1 byte) <== minimum one
// - Observation Hash (32 bytes)
// - Length of Observations (1 byte) <== minimum one
// - Observation Index (1 byte)
// - Observation Length (1 byte)
// - Observation, aka BODY, aka Headless (51 bytes)
// From Above:
// HEADER: 1 + 4 + 1 + 0 = 6
// BODY: 4 + 4 + 2 + 32 + 8 + 1 + 0 = 51
// BATCH: 1 + 32 + 1 + 1 + 1 + 51 = 88
//
// More details here: https://docs.wormholenetwork.com/wormhole/vaas
minHeadlessVAALength = 51 // HEADER
minVAALength = 57 // HEADER + BODY
minBatchVAALength = 94 // HEADER + BATCH
SupportedVAAVersion = 0x01
BatchVAAVersion = 0x02
InternalTruncatedPayloadSafetyLimit = 1000
)
// Unmarshal deserializes the binary representation of a VAA
//
// WARNING: Unmarshall will truncate payloads at 1000 bytes, this is done mainly to avoid denial of service
// - If you need to access the full payload, consider parsing VAA from Bytes instead of Unmarshal
func Unmarshal(data []byte) (*VAA, error) {
if len(data) < minVAALength {
return nil, fmt.Errorf("VAA is too short")
}
v := &VAA{}
v.Version = data[0]
if v.Version != SupportedVAAVersion {
return nil, fmt.Errorf("unsupported VAA version: %d", v.Version)
}
reader := bytes.NewReader(data[1:])
if err := binary.Read(reader, binary.BigEndian, &v.GuardianSetIndex); err != nil {
return nil, fmt.Errorf("failed to read guardian set index: %w", err)
}
lenSignatures, er := reader.ReadByte()
if er != nil {
return nil, fmt.Errorf("failed to read signature length")
}
v.Signatures = make([]*Signature, lenSignatures)
for i := 0; i < int(lenSignatures); i++ {
index, err := reader.ReadByte()
if err != nil {
return nil, fmt.Errorf("failed to read validator index [%d]", i)
}
signature := [65]byte{}
if n, err := reader.Read(signature[:]); err != nil || n != 65 {
return nil, fmt.Errorf("failed to read signature [%d]: %w", i, err)
}
v.Signatures[i] = &Signature{
Index: index,
Signature: signature,
}
}
unixSeconds := uint32(0)
if err := binary.Read(reader, binary.BigEndian, &unixSeconds); err != nil {
return nil, fmt.Errorf("failed to read timestamp: %w", err)
}
v.Timestamp = time.Unix(int64(unixSeconds), 0)
if err := binary.Read(reader, binary.BigEndian, &v.Nonce); err != nil {
return nil, fmt.Errorf("failed to read nonce: %w", err)
}
if err := binary.Read(reader, binary.BigEndian, &v.EmitterChain); err != nil {
return nil, fmt.Errorf("failed to read emitter chain: %w", err)
}
emitterAddress := Address{}
if n, err := reader.Read(emitterAddress[:]); err != nil || n != 32 {
return nil, fmt.Errorf("failed to read emitter address [%d]: %w", n, err)
}
v.EmitterAddress = emitterAddress
if err := binary.Read(reader, binary.BigEndian, &v.Sequence); err != nil {
return nil, fmt.Errorf("failed to read sequence: %w", err)
}
if err := binary.Read(reader, binary.BigEndian, &v.ConsistencyLevel); err != nil {
return nil, fmt.Errorf("failed to read commitment: %w", err)
}
payload := make([]byte, InternalTruncatedPayloadSafetyLimit)
n, err := reader.Read(payload)
if err != nil || n == 0 {
return nil, fmt.Errorf("failed to read payload [%d]: %w", n, err)
}
v.Payload = payload[:n]
return v, nil
}
func UnmarshalBatch(data []byte) (*BatchVAA, error) {
if len(data) < minBatchVAALength {
return nil, fmt.Errorf("BatchVAA.Observation is too short")
}
v := &BatchVAA{}
v.Version = data[0]
if v.Version != BatchVAAVersion {
return nil, fmt.Errorf("unsupported VAA version: %d", v.Version)
}
reader := bytes.NewReader(data[1:])
if err := binary.Read(reader, binary.BigEndian, &v.GuardianSetIndex); err != nil {
return nil, fmt.Errorf("failed to read guardian set index: %w", err)
}
lenSignatures, er := reader.ReadByte()
if er != nil {
return nil, fmt.Errorf("failed to read signature length")
}
v.Signatures = make([]*Signature, int(lenSignatures))
for i := 0; i < int(lenSignatures); i++ {
index, err := reader.ReadByte()
if err != nil {
return nil, fmt.Errorf("failed to read validator index [%d]", i)
}
signature := [65]byte{}
if n, err := reader.Read(signature[:]); err != nil || n != 65 {
return nil, fmt.Errorf("failed to read signature [%d]: %w", i, err)
}
v.Signatures[i] = &Signature{
Index: uint8(index),
Signature: signature,
}
}
lenHashes, err := reader.ReadByte()
if err != nil {
return nil, fmt.Errorf("failed to read hashes length [%w]", err)
}
v.Hashes = make([]common.Hash, int(lenHashes))
for i := 0; i < int(lenHashes); i++ {
hash := [32]byte{}
if n, err := reader.Read(hash[:]); err != nil || n != 32 {
return nil, fmt.Errorf("failed to read hash [%d]: %w", i, err)
}
v.Hashes[i] = common.BytesToHash(hash[:])
}
lenObservations, err := reader.ReadByte()
if err != nil {
return nil, fmt.Errorf("failed to read observations length: %w", err)
}
v.Observations = make([]*Observation, int(lenObservations))
for i := 0; i < int(lenObservations); i++ {
obsvIndex, err := reader.ReadByte()
if err != nil {
return nil, fmt.Errorf("failed to read Observation index [%d]: %w", i, err)
}
obsvLength := uint32(0)
if err := binary.Read(reader, binary.BigEndian, &obsvLength); err != nil {
return nil, fmt.Errorf("failed to read Observation length: %w", err)
}
obs := make([]byte, int(obsvLength))
if n, err := reader.Read(obs[:]); err != nil || n == 0 {
return nil, fmt.Errorf("failed to read Observation bytes [%d]: %w", n, err)
}
msgPub, err := UnmarshalBatchObservation(obs)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal Observation VAA. %w", err)
}
v.Observations[i] = &Observation{
Index: uint8(obsvIndex),
Observation: msgPub,
}
}
return v, nil
}
// Unmarshal deserializes the binary representation of an Observation (VAA)
// within a BatchVAA. Different from VAA unmarshaling - no header fields.
func UnmarshalBatchObservation(data []byte) (*VAA, error) {
if len(data) < minHeadlessVAALength {
return nil, fmt.Errorf("BatchVAA.Observation is too short")
}
v := &VAA{}
reader := bytes.NewReader(data[:])
unixSeconds := uint32(0)
if err := binary.Read(reader, binary.BigEndian, &unixSeconds); err != nil {
return nil, fmt.Errorf("failed to read timestamp: %w", err)
}
v.Timestamp = time.Unix(int64(unixSeconds), 0)
if err := binary.Read(reader, binary.BigEndian, &v.Nonce); err != nil {
return nil, fmt.Errorf("failed to read nonce: %w", err)
}
if err := binary.Read(reader, binary.BigEndian, &v.EmitterChain); err != nil {
return nil, fmt.Errorf("failed to read emitter chain: %w", err)
}
emitterAddress := Address{}
if n, err := reader.Read(emitterAddress[:]); err != nil || n != 32 {
return nil, fmt.Errorf("failed to read emitter address [%d]: %w", n, err)
}
v.EmitterAddress = emitterAddress
if err := binary.Read(reader, binary.BigEndian, &v.Sequence); err != nil {
return nil, fmt.Errorf("failed to read sequence: %w", err)
}
if err := binary.Read(reader, binary.BigEndian, &v.ConsistencyLevel); err != nil {
return nil, fmt.Errorf("failed to read commitment: %w", err)
}
payload := make([]byte, InternalTruncatedPayloadSafetyLimit)
n, err := reader.Read(payload)
if err != nil || n == 0 {
return nil, fmt.Errorf("failed to read payload [%d]: %w", n, err)
}
v.Payload = payload[:n]
return v, nil
}
// signingBody returns the binary representation of the data that is relevant for signing and verifying the VAA
func (v *VAA) signingBody() []byte {
return v.serializeBody()
}
// signingBatchBody returns the binary representation of the data that is relevant for signing and verifying the VAA
func (v *BatchVAA) signingBatchBody() []byte {
buf := new(bytes.Buffer)
// create the hash array from the Observations of the BatchVAA
hashes := v.ObsvHashArray()
MustWrite(buf, binary.BigEndian, hashes)
return buf.Bytes()
}
// SigningMsg returns the hash of the signing body. This is used for signature generation and verification
func (v *VAA) SigningMsg() common.Hash {
// In order to save space in the solana signature verification instruction, we hash twice so we only need to pass in
// the first hash (32 bytes) vs the full body data.
hash := crypto.Keccak256Hash(crypto.Keccak256Hash(v.signingBody()).Bytes())
return hash
}
// SigningBatchMsg returns the hash of the signing body. This is used for signature generation and verification
// this is batchHatch from wormhole.js - already bytes signed again
func (v *BatchVAA) SigningBatchMsg() common.Hash {
// In order to save space in the solana signature verification instruction, we hash twice so we only need to pass in
// the first hash (32 bytes) vs the full body data.
hash := crypto.Keccak256Hash(crypto.Keccak256Hash(v.signingBatchBody()).Bytes())
return hash
}
// ObsvHashArray creates an array of hashes of Observation.
// hashes in the array have the index position of their Observation.Index.
func (v *BatchVAA) ObsvHashArray() []common.Hash {
hashes := make([]common.Hash, len(v.Observations))
for _, msg := range v.Observations {
obsIndex := msg.Index
hashes[obsIndex] = msg.Observation.SigningMsg()
}
return hashes
}
// VerifySignatures verifies the signature of the VAA given the signer addresses.
// Returns true if the signatures were verified successfully.
func (v *VAA) VerifySignatures(addresses []common.Address) bool {
if len(addresses) < len(v.Signatures) {
return false
}
h := v.SigningMsg()
last_index := -1
signing_addresses := []common.Address{}
for _, sig := range v.Signatures {
if int(sig.Index) >= len(addresses) {
return false
}
// Ensure increasing indexes
if int(sig.Index) <= last_index {
return false
}
last_index = int(sig.Index)
// Get pubKey to determine who signers address
pubKey, err := crypto.Ecrecover(h.Bytes(), sig.Signature[:])
if err != nil {
return false
}
addr := common.BytesToAddress(crypto.Keccak256(pubKey[1:])[12:])
// Ensure this signer is at the correct positional index
if addr != addresses[sig.Index] {
return false
}
// Ensure we never see the same signer twice
for _, signing_address := range signing_addresses {
if signing_address == addr {
return false
}
}
signing_addresses = append(signing_addresses, addr)
}
return true
}
// VerifyBatchSignatures verifies the signature of the BatchVAA given the signer addresses.
// Returns true if the signatures were verified successfully.
func (v *BatchVAA) VerifyBatchSignatures(addresses []common.Address) bool {
if len(addresses) < len(v.Signatures) {
return false
}
h := v.SigningBatchMsg()
last_index := -1
signing_addresses := []common.Address{}
for _, sig := range v.Signatures {
if int(sig.Index) >= len(addresses) {
return false
}
// Ensure increasing indexes
if int(sig.Index) <= last_index {
return false
}
last_index = int(sig.Index)
// Get pubKey to determine who signers address
pubKey, err := crypto.Ecrecover(h.Bytes(), sig.Signature[:])
if err != nil {
return false
}
addr := common.BytesToAddress(crypto.Keccak256(pubKey[1:])[12:])
// Ensure this signer is at the correct positional index
if addr != addresses[sig.Index] {
return false
}
// Ensure we never see the same signer twice
for _, signing_address := range signing_addresses {
if signing_address == addr {
return false
}
}
signing_addresses = append(signing_addresses, addr)
}
return true
}
// Marshal returns the binary representation of the BatchVAA
func (v *BatchVAA) Marshal() ([]byte, error) {
buf := new(bytes.Buffer)
MustWrite(buf, binary.BigEndian, v.Version)
MustWrite(buf, binary.BigEndian, v.GuardianSetIndex)
// Write signatures
MustWrite(buf, binary.BigEndian, uint8(len(v.Signatures)))
for _, sig := range v.Signatures {
MustWrite(buf, binary.BigEndian, sig.Index)
buf.Write(sig.Signature[:])
}
// Write Body
buf.Write(v.serializeBatchBody())
return buf.Bytes(), nil
}
// Serializes the body of the BatchVAA.
func (v *BatchVAA) serializeBatchBody() []byte {
buf := new(bytes.Buffer)
hashes := v.ObsvHashArray()
MustWrite(buf, binary.BigEndian, uint8(len(hashes)))
MustWrite(buf, binary.BigEndian, hashes)
MustWrite(buf, binary.BigEndian, uint8(len(v.Observations)))
for _, obsv := range v.Observations {
MustWrite(buf, binary.BigEndian, uint8(obsv.Index))
obsvBytes := obsv.Observation.serializeBatchObservationBody()
lenBytes := len(obsvBytes)
MustWrite(buf, binary.BigEndian, uint32(lenBytes))
buf.Write(obsvBytes)
}
return buf.Bytes()
}
// Marshal returns the binary representation of the VAA
func (v *VAA) Marshal() ([]byte, error) {
buf := new(bytes.Buffer)
MustWrite(buf, binary.BigEndian, v.Version)
MustWrite(buf, binary.BigEndian, v.GuardianSetIndex)
// Write signatures
MustWrite(buf, binary.BigEndian, uint8(len(v.Signatures)))
for _, sig := range v.Signatures {
MustWrite(buf, binary.BigEndian, sig.Index)
buf.Write(sig.Signature[:])
}
// Write Body
buf.Write(v.serializeBody())
return buf.Bytes(), nil
}
// MessageID returns a human-readable emitter_chain/emitter_address/sequence tuple.
func (v *VAA) MessageID() string {
return fmt.Sprintf("%d/%s/%d", v.EmitterChain, v.EmitterAddress, v.Sequence)
}
// BatchID returns a human-readable emitter_chain/transaction_hex
func (v *BatchVAA) BatchID() string {
return fmt.Sprintf("%d/%s", v.EmitterChain, hex.EncodeToString(v.TransactionID.Bytes()))
}
// GetTransactionID implements the processor.Batch interface for *BatchVAA.
func (v *BatchVAA) GetTransactionID() common.Hash {
return v.TransactionID
}
// HexDigest returns the hex-encoded digest.
func (v *VAA) HexDigest() string {
return hex.EncodeToString(v.SigningMsg().Bytes())
}
// HexDigest returns the hex-encoded digest.
func (b *BatchVAA) HexDigest() string {
return hex.EncodeToString(b.SigningBatchMsg().Bytes())
}
// serializeBatchObservationBody marshals the body of BatchVAA.Observations
func (v *VAA) serializeBatchObservationBody() []byte {
// Marshaling BatchVAA.Observations is the same
// as VAAs, but unmarshaling is different.
// This wrapper function serves as the delebrate entry point.
return v.serializeBody()
}
/*
SECURITY: Do not change this code! Changing it could result in two different hashes for
the same observation. But xDapps rely on the hash of an observation for replay protection.
*/
func (v *VAA) serializeBody() []byte {
buf := new(bytes.Buffer)
MustWrite(buf, binary.BigEndian, uint32(v.Timestamp.Unix()))
MustWrite(buf, binary.BigEndian, v.Nonce)
MustWrite(buf, binary.BigEndian, v.EmitterChain)
buf.Write(v.EmitterAddress[:])
MustWrite(buf, binary.BigEndian, v.Sequence)
MustWrite(buf, binary.BigEndian, v.ConsistencyLevel)
buf.Write(v.Payload)
return buf.Bytes()
}
func (v *VAA) AddSignature(key *ecdsa.PrivateKey, index uint8) {
sig, err := crypto.Sign(v.SigningMsg().Bytes(), key)
if err != nil {
panic(err)
}
sigData := [65]byte{}
copy(sigData[:], sig)
v.Signatures = append(v.Signatures, &Signature{
Index: index,
Signature: sigData,
})
}
// creates signature of BatchVAA.Hashes and adds it to BatchVAA.Signatures.
func (v *BatchVAA) AddSignature(key *ecdsa.PrivateKey, index uint8) {
sig, err := crypto.Sign(v.SigningBatchMsg().Bytes(), key)
if err != nil {
panic(err)
}
sigData := [65]byte{}
copy(sigData[:], sig)
v.Signatures = append(v.Signatures, &Signature{
Index: index,
Signature: sigData,
})
}
// NOTE: This function assumes that the caller has verified that the VAA is from the token bridge.
func IsTransfer(payload []byte) bool {
return (len(payload) > 0) && ((payload[0] == 1) || (payload[0] == 3))
}
func DecodeTransferPayloadHdr(payload []byte) (*TransferPayloadHdr, error) {
if !IsTransfer(payload) {
return nil, fmt.Errorf("unsupported payload type")
}
if len(payload) < 101 {
return nil, fmt.Errorf("buffer too short")
}
p := &TransferPayloadHdr{}
// Payload type: payload[0]
p.Type = uint8(payload[0])
// Amount: payload[1] for 32
p.Amount = new(big.Int)
p.Amount.SetBytes(payload[1:33])
reader := bytes.NewReader(payload[33:])
// Origin address: payload[33] for 32
err := binary.Read(reader, binary.BigEndian, &p.OriginAddress)
if err != nil {
return nil, err
}
// Origin chain ID: payload[65] for 2
err = binary.Read(reader, binary.BigEndian, &p.OriginChain)
if err != nil {
return nil, err
}
// Target address: payload[67] for 32
err = binary.Read(reader, binary.BigEndian, &p.TargetAddress)
if err != nil {
return nil, err
}
// Target chain ID: payload[99] for 2
err = binary.Read(reader, binary.BigEndian, &p.TargetChain)
if err != nil {
return nil, err
}
return p, nil
}
// GetEmitterChain implements the processor.Observation interface for *VAA.
func (v *VAA) GetEmitterChain() ChainID {
return v.EmitterChain
}
// GetEmitterChain implements the processor.Batch interface for *BatchVAA.
func (v *BatchVAA) GetEmitterChain() ChainID {
return v.EmitterChain
}
// MustWrite calls binary.Write and panics on errors
func MustWrite(w io.Writer, order binary.ByteOrder, data interface{}) {
if err := binary.Write(w, order, data); err != nil {
panic(fmt.Errorf("failed to write binary data: %v", data).Error())
}
}
// StringToAddress converts a hex-encoded address into a vaa.Address
func StringToAddress(value string) (Address, error) {
var address Address
// Make sure we have enough to decode
if len(value) < 2 {
return address, fmt.Errorf("value must be at least 1 byte")
}
// Trim any preceding "0x" to the address
value = strings.TrimPrefix(value, "0x")
// Decode the string from hex to binary
res, err := hex.DecodeString(value)
if err != nil {
return address, err
}
// Make sure we don't have too many bytes
if len(res) > 32 {
return address, fmt.Errorf("value must be no more than 32 bytes")
}
copy(address[32-len(res):], res)
return address, nil
}
func BytesToAddress(b []byte) (Address, error) {
var address Address
if len(b) > 32 {
return address, fmt.Errorf("value must be no more than 32 bytes")
}
copy(address[32-len(b):], b)
return address, nil
}
// StringToHash converts a hex-encoded string into a common.Hash
func StringToHash(value string) (common.Hash, error) {
var tx common.Hash
// Make sure we have enough to decode
if len(value) < 2 {
return tx, fmt.Errorf("value must be at least 1 byte")
}
// Trim any preceding "0x" to the address
value = strings.TrimPrefix(value, "0x")
res, err := hex.DecodeString(value)
if err != nil {
return tx, err
}
tx = common.BytesToHash(res)
return tx, nil
}
func BytesToHash(b []byte) (common.Hash, error) {
var hash common.Hash
if len(b) > 32 {
return hash, fmt.Errorf("value must be no more than 32 bytes")
}
hash = common.BytesToHash(b)
return hash, nil
}

View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -exuo pipefail
./get-addresses.sh
go run main.go relay

View File

@ -22,6 +22,7 @@ import {
CHAIN_ID_ETH,
getSignedBatchVAAWithRetry,
tryNativeToUint8Array,
tryNativeToHexString
} from "@certusone/wormhole-sdk";
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
@ -214,18 +215,18 @@ describe("ETH <> BSC Generic Relayer Integration Test", () => {
const storedPayload = await bscRelayerIntegrator.getPayload(targetVm3.hash);
if (storedPayload == targetVm3.payload) {
isBatchDelivered = true;
// clear the payload from the mock integration contract
await bscRelayerIntegrator.clearPayload(targetVm3.hash);
const emptyStoredPayload = await bscRelayerIntegrator.getPayload(targetVm3.hash);
expect(emptyStoredPayload).to.equal("0x");
}
}
// confirm that the remaining payloads are stored in the contract
for (const indexedObservation of parsedBatch.indexedObservations.slice(1)) {
for (const indexedObservation of parsedBatch.indexedObservations) {
const vm3 = indexedObservation.vm3;
// skip delivery instructions VM
if (vm3.emitterAddress == "0x"+tryNativeToHexString(ethCoreRelayer.address, CHAIN_ID_ETH)) {
continue;
}
// query the contract to see if the batch was delivered
const storedPayload = await bscRelayerIntegrator.getPayload(vm3.hash);
expect(storedPayload).to.equal(vm3.payload);