node/cmd: add public telemetry for logs

commit-id:582fc943
This commit is contained in:
Leo 2022-01-09 21:56:59 +01:00 committed by Leopold Schabel
parent 870afc5193
commit af2bd5be36
8 changed files with 354 additions and 22 deletions

View File

@ -2,9 +2,12 @@ package guardiand
import (
"context"
"encoding/base64"
"fmt"
"github.com/certusone/wormhole/node/pkg/db"
"github.com/certusone/wormhole/node/pkg/notify/discord"
"github.com/certusone/wormhole/node/pkg/telemetry"
"github.com/certusone/wormhole/node/pkg/version"
"github.com/gagliardetto/solana-go/rpc"
"go.uber.org/zap/zapcore"
"log"
@ -102,6 +105,9 @@ var (
tlsProdEnv *bool
disableHeartbeatVerify *bool
disableTelemetry *bool
telemetryKey *string
discordToken *string
discordChannel *string
@ -175,6 +181,11 @@ func init() {
disableHeartbeatVerify = NodeCmd.Flags().Bool("disableHeartbeatVerify", false,
"Disable heartbeat signature verification (useful during network startup)")
disableTelemetry = NodeCmd.Flags().Bool("disableTelemetry", false,
"Disable telemetry")
telemetryKey = NodeCmd.Flags().String("telemetryKey", "",
"Telemetry write key")
discordToken = NodeCmd.Flags().String("discordToken", "", "Discord bot token (optional)")
discordChannel = NodeCmd.Flags().String("discordChannel", "", "Discord channel name (optional)")
@ -257,9 +268,6 @@ func runNode(cmd *cobra.Command, args []string) {
// Override the default go-log config, which uses a magic environment variable.
ipfslog.SetAllLoggers(lvl)
// Redirect ipfs logs to plain zap
ipfslog.SetPrimaryCore(logger.Core())
// Register components for readiness checks.
readiness.RegisterComponent(common.ReadinessEthSyncing)
readiness.RegisterComponent(common.ReadinessSolanaSyncing)
@ -543,6 +551,45 @@ func runNode(cmd *cobra.Command, args []string) {
}
}
// Enable unless it is disabled. For devnet, only when --telemetryKey is set.
if !*disableTelemetry && (!*unsafeDevMode || *unsafeDevMode && *telemetryKey != "") {
logger.Info("Telemetry enabled")
if *telemetryKey == "" {
logger.Fatal("Please specify --telemetryKey")
}
creds, err := decryptTelemetryServiceAccount()
if err != nil {
logger.Fatal("Failed to decrypt telemetry service account", zap.Error(err))
}
// Get libp2p peer ID from private key
pk := priv.GetPublic()
peerID, err := peer.IDFromPublicKey(pk)
if err != nil {
logger.Fatal("Failed to get peer ID from private key", zap.Error(err))
}
tm, err := telemetry.New(context.Background(), telemetryProject, creds, map[string]string{
"node_name": *nodeName,
"node_key": peerID.Pretty(),
"guardian_addr": guardianAddr,
"network": *p2pNetworkID,
"version": version.Version(),
})
if err != nil {
logger.Fatal("Failed to initialize telemetry", zap.Error(err))
}
defer tm.Close()
logger = tm.WrapLogger(logger)
} else {
logger.Info("Telemetry disabled")
}
// Redirect ipfs logs to plain zap
ipfslog.SetPrimaryCore(logger.Core())
// provides methods for reporting progress toward message attestation, and channels for receiving attestation lifecyclye events.
attestationEvents := reporter.EventListener(logger)
@ -694,3 +741,23 @@ func runNode(cmd *cobra.Command, args []string) {
logger.Info("root context cancelled, exiting...")
// TODO: wait for things to shut down gracefully
}
func decryptTelemetryServiceAccount() ([]byte, error) {
// Decrypt service account credentials
key, err := base64.StdEncoding.DecodeString(*telemetryKey)
if err != nil {
return nil, fmt.Errorf("failed to decode: %w", err)
}
ciphertext, err := base64.StdEncoding.DecodeString(telemetryServiceAccount)
if err != nil {
panic(err)
}
creds, err := common.DecryptAESGCM(ciphertext, key)
if err != nil {
return nil, fmt.Errorf("failed to decrypt: %w", err)
}
return creds, err
}

View File

@ -0,0 +1,57 @@
package guardiand
// Hardcoded telemetry GCP service account. Does not grant any access except for writing logs.
//
// Network operators can opt to send their logs to a shared Cloud Logging project for debugging.
// Logs are available to all network operators. There is no secret data logged anywhere.
//
// We encrypt the service account using a hardcoded symmetric key shared with guardians to
// prevent GitHub credential checkers from freaking out and to stop people from sending gigabytes of "gm".
//
// By using a separate key, we can keep the configuration decoupled from the telemetry backend,
// allowing the key to be replaced or even a different provider to be used without changing the config.
const telemetryProject = "projects/wormhole-logging"
const telemetryServiceAccount = `
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
3SWVv2wizHdu
`

View File

@ -51,9 +51,16 @@ require (
nhooyr.io/websocket v1.8.7 // indirect
)
require (
cloud.google.com/go/logging v1.4.2
cloud.google.com/go/pubsub v1.17.1
github.com/blendle/zapdriver v1.3.1
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/google/uuid v1.2.0
)
require (
cloud.google.com/go v0.97.0 // indirect
cloud.google.com/go/pubsub v1.17.1 // indirect
contrib.go.opencensus.io/exporter/stackdriver v0.13.4 // indirect
github.com/99designs/keyring v1.1.3 // indirect
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
@ -63,9 +70,7 @@ require (
github.com/benbjohnson/clock v1.0.3 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
github.com/btcsuite/btcd v0.21.0-beta // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/cheekybits/genny v1.0.0 // indirect
@ -101,7 +106,6 @@ require (
github.com/google/flatbuffers v1.12.0 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
github.com/gorilla/schema v1.2.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
@ -125,7 +129,6 @@ require (
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/jstemmer/go-junit-report v0.9.1 // indirect
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 // indirect
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect
github.com/klauspost/compress v1.13.1 // indirect
@ -236,8 +239,6 @@ require (
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect

View File

@ -22,7 +22,6 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go v0.82.0 h1:FZ4B2YAzCzkwzGEOp1dqG8sAa3zNIvro1fHRTrB81RU=
cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA=
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
@ -44,7 +43,10 @@ cloud.google.com/go/bigtable v1.10.1/go.mod h1:cyHeKlx6dcZCO0oSQucYdauseD8kIENGu
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/kms v1.0.0 h1:YkIeqPXqTAlwXk3Z2/WG0d6h1tqJQjU354WftjEoP9E=
cloud.google.com/go/kms v1.0.0/go.mod h1:nhUehi+w7zht2XrUfvTRNpxrfayBHqP4lu2NSywui/0=
cloud.google.com/go/logging v1.4.2 h1:Mu2Q75VBDQlW1HlBMjTX4X84UFR73G1TiLlRYc/b7tA=
cloud.google.com/go/logging v1.4.2/go.mod h1:jco9QZSx8HiVVqLJReq7z7bVdj0P1Jb9PDFs63T+axo=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@ -492,7 +494,6 @@ github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=
@ -523,8 +524,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 h1:ajue7SzQMywqRjg2fK7dcpc0QhFGpTR2plWfV4EZWR4=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0/go.mod h1:r1hZAcvfFXuYmcKyCJI9wlyOPIZUJl6FCB8Cpca/NLE=
@ -676,7 +677,6 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@ -1611,7 +1611,6 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1 h1:x622Z2o4hgCr/4CiKWc51jHVKaWdtVpBNmEI8wI9Qns=
golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@ -1718,7 +1717,6 @@ golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b h1:qh4f65QIVFjq9eBURLEYWqaEXmOyqdUyiBSgaXWccWk=
golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1746,7 +1744,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1818,9 +1815,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1860,7 +1857,6 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I=
google.golang.org/api v0.47.0 h1:sQLWZQvP6jPGIP4JGPkJu4zHswrv81iobiyszr3b/0I=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
@ -1937,7 +1933,6 @@ google.golang.org/genproto v0.0.0-20210601144548-a796c710e9b6/go.mod h1:P3QM42oQ
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced h1:c5geK1iMU3cDKtFrCVQIcjR3W+JOZMuhIyICMCTbtus=
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
@ -1984,7 +1979,6 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
@ -2002,7 +1996,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=

View File

@ -0,0 +1,46 @@
package main
import (
"encoding/base64"
"fmt"
"io"
"log"
"math/rand"
"os"
"github.com/certusone/wormhole/node/pkg/common"
)
func main() {
in, err := io.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("failed to read stdin: %v", err)
}
// Generate 128-bit key
key := make([]byte, 16)
if _, err := rand.Read(key); err != nil {
log.Fatalf("failed to generate key: %v", err)
}
// Log key as base64 string
log.Printf("key: %s", base64.StdEncoding.EncodeToString(key))
// Encrypt
ciphertext, err := common.EncryptAESGCM(in, key)
if err != nil {
log.Fatalf("failed to encrypt: %v", err)
}
// Convert ciphertext as base64 string.
b64 := base64.StdEncoding.EncodeToString(ciphertext)
// Hard-wrap to 80 characters per line.
for i := 0; i < len(b64); i += 80 {
j := i + 80
if j > len(b64) {
j = len(b64)
}
fmt.Println(b64[i:j])
}
}

View File

@ -0,0 +1,46 @@
package common
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
)
func DecryptAESGCM(data, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("failed to create cipher: %v", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("failed to create gcm: %v", err)
}
nonceSize := gcm.NonceSize()
if len(data) < nonceSize {
return nil, fmt.Errorf("data is too short")
}
nonce, data := data[:nonceSize], data[nonceSize:]
out, err := gcm.Open(nil, nonce, data, nil)
if err != nil {
return nil, fmt.Errorf("failed to decrypt: %v", err)
}
return out, nil
}
func EncryptAESGCM(plaintext, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("failed to create cipher: %v", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("failed to create gcm: %v", err)
}
nonce := make([]byte, gcm.NonceSize())
if _, err = rand.Read(nonce); err != nil {
return nil, fmt.Errorf("failed to read random data: %v", err)
}
out := gcm.Seal(nil, nonce, plaintext, nil)
return append(nonce, out...), nil
}

View File

@ -0,0 +1,24 @@
package common
import (
"testing"
)
func TestAESGCM(t *testing.T) {
data := []byte("cat")
key := []byte("01234567890123456789012345678901")
enc, err := EncryptAESGCM(data, key)
if err != nil {
t.Fatal(err)
}
dec, err := DecryptAESGCM(enc, key)
if err != nil {
t.Fatal(err)
}
if string(dec) != string(data) {
t.Fatalf("expected %s got %s", string(data), string(dec))
}
}

View File

@ -0,0 +1,98 @@
package telemetry
import (
"cloud.google.com/go/logging"
"context"
"encoding/json"
"fmt"
"github.com/blendle/zapdriver"
"go.uber.org/zap"
"go.uber.org/zap/buffer"
"go.uber.org/zap/zapcore"
"google.golang.org/api/option"
"io/ioutil"
)
type Telemetry struct {
encoder *encoder
serviceAccountJSON []byte
}
type encoder struct {
zapcore.Encoder
logger *logging.Logger
labels map[string]string
}
// Mirrors the conversion done by zapdriver. We need to convert this
// to proto severity for usage with the SDK client library
// (the JSON value encoded by zapdriver is ignored).
var logLevelSeverity = map[zapcore.Level]logging.Severity{
zapcore.DebugLevel: logging.Debug,
zapcore.InfoLevel: logging.Info,
zapcore.WarnLevel: logging.Warning,
zapcore.ErrorLevel: logging.Error,
zapcore.DPanicLevel: logging.Critical,
zapcore.PanicLevel: logging.Alert,
zapcore.FatalLevel: logging.Emergency,
}
func (enc *encoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
buf, err := enc.Encoder.EncodeEntry(entry, fields)
if err != nil {
return nil, err
}
// Create a copy of buf (zap will reuse the same buffer otherwise)
bufCopy := make([]byte, len(buf.Bytes()))
copy(bufCopy, buf.Bytes())
// Convert the zapcore.Level to a logging.Severity
severity := logLevelSeverity[entry.Level]
// Write raw message to log
enc.logger.Log(logging.Entry{
Timestamp: entry.Time,
Payload: json.RawMessage(bufCopy),
Severity: severity,
Labels: enc.labels,
})
return buf, nil
}
func New(ctx context.Context, project string, serviceAccountJSON []byte, labels map[string]string) (*Telemetry, error) {
gc, err := logging.NewClient(ctx, project, option.WithCredentialsJSON(serviceAccountJSON))
if err != nil {
return nil, fmt.Errorf("unable to create logging client: %v", err)
}
gc.OnError = func(err error) {
fmt.Printf("telemetry: logging client error: %v\n", err)
}
return &Telemetry{
serviceAccountJSON: serviceAccountJSON,
encoder: &encoder{
Encoder: zapcore.NewJSONEncoder(zapdriver.NewProductionEncoderConfig()),
logger: gc.Logger("wormhole"),
labels: labels,
},
}, nil
}
func (s *Telemetry) WrapLogger(logger *zap.Logger) *zap.Logger {
tc := zapcore.NewCore(
s.encoder,
zapcore.AddSync(ioutil.Discard),
zap.DebugLevel,
)
return logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
return zapcore.NewTee(core, tc)
}))
}
func (s *Telemetry) Close() error {
return s.encoder.logger.Flush()
}