/
sentry.go
158 lines (133 loc) · 4.81 KB
/
sentry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package oasis
import (
"fmt"
"github.com/oasisprotocol/oasis-core/go/common/crypto/signature"
fileSigner "github.com/oasisprotocol/oasis-core/go/common/crypto/signature/signers/file"
"github.com/oasisprotocol/oasis-core/go/common/identity"
"github.com/oasisprotocol/oasis-core/go/consensus/tendermint/crypto"
)
// Sentry is an Oasis sentry node.
type Sentry struct {
*Node
validatorIndices []int
computeIndices []int
keymanagerIndices []int
p2pPublicKey signature.PublicKey
tlsPublicKey signature.PublicKey
tmAddress string
consensusPort uint16
controlPort uint16
sentryPort uint16
}
// SentryCfg is the Oasis sentry node configuration.
type SentryCfg struct {
NodeCfg
ValidatorIndices []int
ComputeIndices []int
KeymanagerIndices []int
}
// TLSCertPath returns the path to the node's TLS certificate.
func (sentry *Sentry) TLSCertPath() string {
return nodeTLSCertPath(sentry.dir)
}
// GetTLSPubKey returns the sentry TLS public key.
func (sentry *Sentry) GetTLSPubKey() signature.PublicKey {
return sentry.tlsPublicKey
}
// GetSentryAddress returns the sentry grpc endpoint address.
func (sentry *Sentry) GetSentryAddress() string {
return fmt.Sprintf("127.0.0.1:%d", sentry.sentryPort)
}
// GetSentryControlAddress returns the sentry control endpoint address.
func (sentry *Sentry) GetSentryControlAddress() string {
return fmt.Sprintf("127.0.0.1:%d", sentry.controlPort)
}
func (sentry *Sentry) AddArgs(args *argBuilder) error {
validators, err := resolveValidators(sentry.net, sentry.validatorIndices)
if err != nil {
return err
}
computeWorkers, err := resolveComputeWorkers(sentry.net, sentry.computeIndices)
if err != nil {
return err
}
keymanagerWorkers, err := resolveKeymanagerWorkers(sentry.net, sentry.keymanagerIndices)
if err != nil {
return err
}
args.debugDontBlameOasis().
debugAllowRoot().
debugAllowTestKeys().
debugSetRlimit().
debugEnableProfiling(sentry.Node.pprofPort).
workerCertificateRotation(false).
workerSentryEnabled().
workerSentryControlPort(sentry.controlPort).
tendermintCoreAddress(sentry.consensusPort).
tendermintPrune(sentry.consensus.PruneNumKept, sentry.consensus.PruneInterval).
tendermintRecoverCorruptedWAL(sentry.consensus.TendermintRecoverCorruptedWAL).
configureDebugCrashPoints(sentry.crashPointsProbability).
tendermintSupplementarySanity(sentry.supplementarySanityInterval).
appendNetwork(sentry.net).
appendSeedNodes(sentry.net.seeds).
internalSocketAddress(sentry.net.validators[0].SocketPath())
if len(validators) > 0 {
args.addValidatorsAsSentryUpstreams(validators)
}
if len(computeWorkers) > 0 || len(keymanagerWorkers) > 0 {
args.workerGrpcSentryEnabled().
workerSentryGrpcClientAddress([]string{fmt.Sprintf("127.0.0.1:%d", sentry.sentryPort)}).
workerSentryGrpcClientPort(sentry.sentryPort)
}
if len(computeWorkers) > 0 {
args.addSentryComputeWorkers(computeWorkers)
}
if len(keymanagerWorkers) > 0 {
args.addSentryKeymanagerWorkers(keymanagerWorkers)
}
return nil
}
// NewSentry provisions a new sentry node and adds it to the network.
func (net *Network) NewSentry(cfg *SentryCfg) (*Sentry, error) {
sentryName := fmt.Sprintf("sentry-%d", len(net.sentries))
host, err := net.GetNamedNode(sentryName, &cfg.NodeCfg)
if err != nil {
return nil, err
}
// Pre-provision node's identity to pass the sentry node's consensus
// address to the validator so it can configure the sentry node's consensus
// address as its consensus address.
signerFactory, err := fileSigner.NewFactory(host.dir.String(), identity.RequiredSignerRoles...)
if err != nil {
net.logger.Error("failed to create sentry signer factory",
"err", err,
"sentry_name", sentryName,
)
return nil, fmt.Errorf("oasis/sentry: failed to create sentry file signer: %w", err)
}
sentryIdentity, err := identity.LoadOrGenerate(host.dir.String(), signerFactory, true)
if err != nil {
net.logger.Error("failed to provision sentry identity",
"err", err,
"sentry_name", sentryName,
)
return nil, fmt.Errorf("oasis/sentry: failed to provision sentry identity: %w", err)
}
sentryP2PPublicKey := sentryIdentity.P2PSigner.Public()
sentryTLSPublicKey := sentryIdentity.GetTLSSigner().Public()
sentry := &Sentry{
Node: host,
validatorIndices: cfg.ValidatorIndices,
computeIndices: cfg.ComputeIndices,
keymanagerIndices: cfg.KeymanagerIndices,
p2pPublicKey: sentryP2PPublicKey,
tlsPublicKey: sentryTLSPublicKey,
tmAddress: crypto.PublicKeyToTendermint(&sentryP2PPublicKey).Address().String(),
consensusPort: host.getProvisionedPort(nodePortConsensus),
controlPort: host.getProvisionedPort("sentry-control"),
sentryPort: host.getProvisionedPort("sentry-client"),
}
net.sentries = append(net.sentries, sentry)
host.features = append(host.features, sentry)
return sentry, nil
}