Integrate private validator socket client
Following ADDR 008 the node will connect to an external process to handle signing requests. Operation of the external process is left to the user. * introduce alias for PrivValidator interface on socket client * integrate socket client in node * structure tests * remove unnecessary flag
This commit is contained in:
parent
ffd2483e67
commit
74d3f7e1fd
|
@ -16,7 +16,6 @@ func AddNodeFlags(cmd *cobra.Command) {
|
||||||
|
|
||||||
// priv val flags
|
// priv val flags
|
||||||
cmd.Flags().String("priv_validator_addr", config.PrivValidatorAddr, "Socket address for private validator")
|
cmd.Flags().String("priv_validator_addr", config.PrivValidatorAddr, "Socket address for private validator")
|
||||||
cmd.Flags().Int("priv_validator_max_conn", config.PrivValidatorMaxConn, "Limit of concurrent connections to the PrivValidator")
|
|
||||||
|
|
||||||
// node flags
|
// node flags
|
||||||
cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing")
|
cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing")
|
||||||
|
|
|
@ -21,10 +21,9 @@ var (
|
||||||
defaultConfigFileName = "config.toml"
|
defaultConfigFileName = "config.toml"
|
||||||
defaultGenesisJSONName = "genesis.json"
|
defaultGenesisJSONName = "genesis.json"
|
||||||
|
|
||||||
defaultPrivValName = "priv_validator.json"
|
defaultPrivValName = "priv_validator.json"
|
||||||
defaultPrivValMaxConn = 3
|
defaultNodeKeyName = "node_key.json"
|
||||||
defaultNodeKeyName = "node_key.json"
|
defaultAddrBookName = "addrbook.json"
|
||||||
defaultAddrBookName = "addrbook.json"
|
|
||||||
|
|
||||||
defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
|
defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
|
||||||
defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
|
defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
|
||||||
|
@ -108,9 +107,6 @@ type BaseConfig struct {
|
||||||
// TCP or UNIX socket address of the PrivValidator server
|
// TCP or UNIX socket address of the PrivValidator server
|
||||||
PrivValidatorAddr string `mapstructure:"priv_validator_addr"`
|
PrivValidatorAddr string `mapstructure:"priv_validator_addr"`
|
||||||
|
|
||||||
// Limit of concurrent connections to the PrivValidator.
|
|
||||||
PrivValidatorMaxConn int `mapstructure:"priv_validator_max_conn"`
|
|
||||||
|
|
||||||
// TCP or UNIX socket address of the ABCI application,
|
// TCP or UNIX socket address of the ABCI application,
|
||||||
// or the name of an ABCI application compiled in with the Tendermint binary
|
// or the name of an ABCI application compiled in with the Tendermint binary
|
||||||
ProxyApp string `mapstructure:"proxy_app"`
|
ProxyApp string `mapstructure:"proxy_app"`
|
||||||
|
@ -147,19 +143,18 @@ func (c BaseConfig) ChainID() string {
|
||||||
// DefaultBaseConfig returns a default base configuration for a Tendermint node
|
// DefaultBaseConfig returns a default base configuration for a Tendermint node
|
||||||
func DefaultBaseConfig() BaseConfig {
|
func DefaultBaseConfig() BaseConfig {
|
||||||
return BaseConfig{
|
return BaseConfig{
|
||||||
Genesis: defaultGenesisJSONPath,
|
Genesis: defaultGenesisJSONPath,
|
||||||
PrivValidator: defaultPrivValPath,
|
PrivValidator: defaultPrivValPath,
|
||||||
PrivValidatorMaxConn: defaultPrivValMaxConn,
|
NodeKey: defaultNodeKeyPath,
|
||||||
NodeKey: defaultNodeKeyPath,
|
Moniker: defaultMoniker,
|
||||||
Moniker: defaultMoniker,
|
ProxyApp: "tcp://127.0.0.1:46658",
|
||||||
ProxyApp: "tcp://127.0.0.1:46658",
|
ABCI: "socket",
|
||||||
ABCI: "socket",
|
LogLevel: DefaultPackageLogLevels(),
|
||||||
LogLevel: DefaultPackageLogLevels(),
|
ProfListenAddress: "",
|
||||||
ProfListenAddress: "",
|
FastSync: true,
|
||||||
FastSync: true,
|
FilterPeers: false,
|
||||||
FilterPeers: false,
|
DBBackend: "leveldb",
|
||||||
DBBackend: "leveldb",
|
DBPath: "data",
|
||||||
DBPath: "data",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
node/node.go
12
node/node.go
|
@ -173,20 +173,22 @@ func NewNode(config *cfg.Config,
|
||||||
// reload the state (it may have been updated by the handshake)
|
// reload the state (it may have been updated by the handshake)
|
||||||
state = sm.LoadState(stateDB)
|
state = sm.LoadState(stateDB)
|
||||||
|
|
||||||
|
// Connect to external signing process, if an address is provided.
|
||||||
if config.PrivValidatorAddr != "" {
|
if config.PrivValidatorAddr != "" {
|
||||||
var (
|
var (
|
||||||
privKey = crypto.GenPrivKeyEd25519()
|
privKey = crypto.GenPrivKeyEd25519()
|
||||||
pvss = priv_val.NewPrivValidatorSocketServer(
|
pvsc = priv_val.NewSocketClient(
|
||||||
logger.With("module", "priv_val"),
|
logger.With("module", "priv_val"),
|
||||||
config.ChainID(),
|
|
||||||
config.PrivValidatorAddr,
|
config.PrivValidatorAddr,
|
||||||
config.PrivValidatorMaxConn,
|
|
||||||
priv_val.LoadPrivValidatorJSON(config.PrivValidatorFile()),
|
|
||||||
&privKey,
|
&privKey,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
pvss.Start()
|
if err := pvsc.Start(); err != nil {
|
||||||
|
return nil, fmt.Errorf("Error starting private validator client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
privValidator = pvsc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decide whether to fast-sync or not
|
// Decide whether to fast-sync or not
|
||||||
|
|
|
@ -18,9 +18,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
connDeadlineSeconds = 3
|
defaultConnDeadlineSeconds = 3
|
||||||
dialRetryIntervalSeconds = 1
|
defaultDialRetryIntervalSeconds = 1
|
||||||
dialRetryMax = 10
|
defaultDialRetryMax = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
// Socket errors.
|
// Socket errors.
|
||||||
|
@ -29,70 +29,89 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
connDeadline = time.Second * connDeadlineSeconds
|
connDeadline = time.Second * defaultConnDeadlineSeconds
|
||||||
)
|
)
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
// SocketClientOption sets an optional parameter on the SocketClient.
|
||||||
|
type SocketClientOption func(*socketClient)
|
||||||
|
|
||||||
var _ types.PrivValidator2 = (*PrivValidatorSocketClient)(nil)
|
// SocketClientTimeout sets the timeout for connecting to the external socket
|
||||||
|
// address.
|
||||||
|
func SocketClientTimeout(timeout time.Duration) SocketClientOption {
|
||||||
|
return func(sc *socketClient) { sc.connectTimeout = timeout }
|
||||||
|
}
|
||||||
|
|
||||||
// PrivValidatorSocketClient implements PrivValidator.
|
// socketClient implements PrivValidator, it uses a socket to request signatures
|
||||||
// It uses a socket to request signatures.
|
// from an external process.
|
||||||
type PrivValidatorSocketClient struct {
|
type socketClient struct {
|
||||||
cmn.BaseService
|
cmn.BaseService
|
||||||
|
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
privKey *crypto.PrivKeyEd25519
|
privKey *crypto.PrivKeyEd25519
|
||||||
|
|
||||||
ID types.ValidatorID
|
addr string
|
||||||
SocketAddress string
|
connectTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPrivValidatorSocketClient returns an instance of
|
// Check that socketClient implements PrivValidator2.
|
||||||
// PrivValidatorSocketClient.
|
var _ types.PrivValidator2 = (*socketClient)(nil)
|
||||||
func NewPrivValidatorSocketClient(
|
|
||||||
|
// NewsocketClient returns an instance of socketClient.
|
||||||
|
func NewSocketClient(
|
||||||
logger log.Logger,
|
logger log.Logger,
|
||||||
socketAddr string,
|
socketAddr string,
|
||||||
privKey *crypto.PrivKeyEd25519,
|
privKey *crypto.PrivKeyEd25519,
|
||||||
) *PrivValidatorSocketClient {
|
) *socketClient {
|
||||||
pvsc := &PrivValidatorSocketClient{
|
sc := &socketClient{
|
||||||
SocketAddress: socketAddr,
|
addr: socketAddr,
|
||||||
privKey: privKey,
|
connectTimeout: time.Second * defaultConnDeadlineSeconds,
|
||||||
|
privKey: privKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
pvsc.BaseService = *cmn.NewBaseService(logger, "privValidatorSocketClient", pvsc)
|
sc.BaseService = *cmn.NewBaseService(logger, "privValidatorsocketClient", sc)
|
||||||
|
|
||||||
return pvsc
|
return sc
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnStart implements cmn.Service.
|
// OnStart implements cmn.Service.
|
||||||
func (pvsc *PrivValidatorSocketClient) OnStart() error {
|
func (sc *socketClient) OnStart() error {
|
||||||
if err := pvsc.BaseService.OnStart(); err != nil {
|
if err := sc.BaseService.OnStart(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := pvsc.connect()
|
conn, err := sc.connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pvsc.conn = conn
|
sc.conn = conn
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnStop implements cmn.Service.
|
// OnStop implements cmn.Service.
|
||||||
func (pvsc *PrivValidatorSocketClient) OnStop() {
|
func (sc *socketClient) OnStop() {
|
||||||
pvsc.BaseService.OnStop()
|
sc.BaseService.OnStop()
|
||||||
|
|
||||||
if pvsc.conn != nil {
|
if sc.conn != nil {
|
||||||
pvsc.conn.Close()
|
sc.conn.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAddress implements PrivValidator.
|
||||||
|
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
|
||||||
|
func (sc *socketClient) GetAddress() types.Address {
|
||||||
|
addr, err := sc.Address()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
// Address is an alias for PubKey().Address().
|
// Address is an alias for PubKey().Address().
|
||||||
func (pvsc *PrivValidatorSocketClient) Address() (cmn.HexBytes, error) {
|
func (sc *socketClient) Address() (cmn.HexBytes, error) {
|
||||||
p, err := pvsc.PubKey()
|
p, err := sc.PubKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -100,14 +119,25 @@ func (pvsc *PrivValidatorSocketClient) Address() (cmn.HexBytes, error) {
|
||||||
return p.Address(), nil
|
return p.Address(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PubKey implements PrivValidator.
|
// GetPubKey implements PrivValidator.
|
||||||
func (pvsc *PrivValidatorSocketClient) PubKey() (crypto.PubKey, error) {
|
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
|
||||||
err := writeMsg(pvsc.conn, &PubKeyMsg{})
|
func (sc *socketClient) GetPubKey() crypto.PubKey {
|
||||||
|
pubKey, err := sc.PubKey()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// PubKey implements PrivValidator2.
|
||||||
|
func (sc *socketClient) PubKey() (crypto.PubKey, error) {
|
||||||
|
err := writeMsg(sc.conn, &PubKeyMsg{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return crypto.PubKey{}, err
|
return crypto.PubKey{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := readMsg(pvsc.conn)
|
res, err := readMsg(sc.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return crypto.PubKey{}, err
|
return crypto.PubKey{}, err
|
||||||
}
|
}
|
||||||
|
@ -115,14 +145,14 @@ func (pvsc *PrivValidatorSocketClient) PubKey() (crypto.PubKey, error) {
|
||||||
return res.(*PubKeyMsg).PubKey, nil
|
return res.(*PubKeyMsg).PubKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignVote implements PrivValidator.
|
// SignVote implements PrivValidator2.
|
||||||
func (pvsc *PrivValidatorSocketClient) SignVote(chainID string, vote *types.Vote) error {
|
func (sc *socketClient) SignVote(chainID string, vote *types.Vote) error {
|
||||||
err := writeMsg(pvsc.conn, &SignVoteMsg{Vote: vote})
|
err := writeMsg(sc.conn, &SignVoteMsg{Vote: vote})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := readMsg(pvsc.conn)
|
res, err := readMsg(sc.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -132,14 +162,14 @@ func (pvsc *PrivValidatorSocketClient) SignVote(chainID string, vote *types.Vote
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignProposal implements PrivValidator.
|
// SignProposal implements PrivValidator2.
|
||||||
func (pvsc *PrivValidatorSocketClient) SignProposal(chainID string, proposal *types.Proposal) error {
|
func (sc *socketClient) SignProposal(chainID string, proposal *types.Proposal) error {
|
||||||
err := writeMsg(pvsc.conn, &SignProposalMsg{Proposal: proposal})
|
err := writeMsg(sc.conn, &SignProposalMsg{Proposal: proposal})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := readMsg(pvsc.conn)
|
res, err := readMsg(sc.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -149,14 +179,14 @@ func (pvsc *PrivValidatorSocketClient) SignProposal(chainID string, proposal *ty
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignHeartbeat implements PrivValidator.
|
// SignHeartbeat implements PrivValidator2.
|
||||||
func (pvsc *PrivValidatorSocketClient) SignHeartbeat(chainID string, heartbeat *types.Heartbeat) error {
|
func (sc *socketClient) SignHeartbeat(chainID string, heartbeat *types.Heartbeat) error {
|
||||||
err := writeMsg(pvsc.conn, &SignHeartbeatMsg{Heartbeat: heartbeat})
|
err := writeMsg(sc.conn, &SignHeartbeatMsg{Heartbeat: heartbeat})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := readMsg(pvsc.conn)
|
res, err := readMsg(sc.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -166,22 +196,22 @@ func (pvsc *PrivValidatorSocketClient) SignHeartbeat(chainID string, heartbeat *
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pvsc *PrivValidatorSocketClient) connect() (net.Conn, error) {
|
func (sc *socketClient) connect() (net.Conn, error) {
|
||||||
retries := dialRetryMax
|
retries := defaultDialRetryMax
|
||||||
|
|
||||||
RETRY_LOOP:
|
RETRY_LOOP:
|
||||||
for retries > 0 {
|
for retries > 0 {
|
||||||
if retries != dialRetryMax {
|
if retries != defaultDialRetryMax {
|
||||||
time.Sleep(time.Second * dialRetryIntervalSeconds)
|
time.Sleep(sc.connectTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
retries--
|
retries--
|
||||||
|
|
||||||
conn, err := cmn.Connect(pvsc.SocketAddress)
|
conn, err := cmn.Connect(sc.addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pvsc.Logger.Error(
|
sc.Logger.Error(
|
||||||
"pvsc connect",
|
"sc connect",
|
||||||
"addr", pvsc.SocketAddress,
|
"addr", sc.addr,
|
||||||
"err", errors.Wrap(err, "connection failed"),
|
"err", errors.Wrap(err, "connection failed"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -189,18 +219,18 @@ RETRY_LOOP:
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := conn.SetDeadline(time.Now().Add(connDeadline)); err != nil {
|
if err := conn.SetDeadline(time.Now().Add(connDeadline)); err != nil {
|
||||||
pvsc.Logger.Error(
|
sc.Logger.Error(
|
||||||
"pvsc connect",
|
"sc connect",
|
||||||
"err", errors.Wrap(err, "setting connection timeout failed"),
|
"err", errors.Wrap(err, "setting connection timeout failed"),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if pvsc.privKey != nil {
|
if sc.privKey != nil {
|
||||||
conn, err = p2pconn.MakeSecretConnection(conn, pvsc.privKey.Wrap())
|
conn, err = p2pconn.MakeSecretConnection(conn, sc.privKey.Wrap())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pvsc.Logger.Error(
|
sc.Logger.Error(
|
||||||
"pvsc connect",
|
"sc connect",
|
||||||
"err", errors.Wrap(err, "encrypting connection failed"),
|
"err", errors.Wrap(err, "encrypting connection failed"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,124 @@ import (
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPrivValidatorSocketServer(t *testing.T) {
|
func TestSocketClientAddress(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
assert, require = assert.New(t), require.New(t)
|
assert, require = assert.New(t), require.New(t)
|
||||||
chainID = "test-chain-secret"
|
chainID = "test-chain-secret"
|
||||||
|
sc, pvss = testSetupSocketPair(t, chainID)
|
||||||
|
)
|
||||||
|
defer sc.Stop()
|
||||||
|
defer pvss.Stop()
|
||||||
|
|
||||||
|
serverAddr, err := pvss.privVal.Address()
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
clientAddr, err := sc.Address()
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
assert.Equal(serverAddr, clientAddr)
|
||||||
|
|
||||||
|
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
|
||||||
|
assert.Equal(serverAddr, sc.GetAddress())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSocketClientPubKey(t *testing.T) {
|
||||||
|
var (
|
||||||
|
assert, require = assert.New(t), require.New(t)
|
||||||
|
chainID = "test-chain-secret"
|
||||||
|
sc, pvss = testSetupSocketPair(t, chainID)
|
||||||
|
)
|
||||||
|
defer sc.Stop()
|
||||||
|
defer pvss.Stop()
|
||||||
|
|
||||||
|
clientKey, err := sc.PubKey()
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
privKey, err := pvss.privVal.PubKey()
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
assert.Equal(privKey, clientKey)
|
||||||
|
|
||||||
|
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
|
||||||
|
assert.Equal(privKey, sc.GetPubKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSocketClientProposal(t *testing.T) {
|
||||||
|
var (
|
||||||
|
assert, require = assert.New(t), require.New(t)
|
||||||
|
chainID = "test-chain-secret"
|
||||||
|
sc, pvss = testSetupSocketPair(t, chainID)
|
||||||
|
|
||||||
|
ts = time.Now()
|
||||||
|
privProposal = &types.Proposal{Timestamp: ts}
|
||||||
|
clientProposal = &types.Proposal{Timestamp: ts}
|
||||||
|
)
|
||||||
|
defer sc.Stop()
|
||||||
|
defer pvss.Stop()
|
||||||
|
|
||||||
|
require.NoError(pvss.privVal.SignProposal(chainID, privProposal))
|
||||||
|
require.NoError(sc.SignProposal(chainID, clientProposal))
|
||||||
|
assert.Equal(privProposal.Signature, clientProposal.Signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSocketClientVote(t *testing.T) {
|
||||||
|
var (
|
||||||
|
assert, require = assert.New(t), require.New(t)
|
||||||
|
chainID = "test-chain-secret"
|
||||||
|
sc, pvss = testSetupSocketPair(t, chainID)
|
||||||
|
|
||||||
|
ts = time.Now()
|
||||||
|
vType = types.VoteTypePrecommit
|
||||||
|
want = &types.Vote{Timestamp: ts, Type: vType}
|
||||||
|
have = &types.Vote{Timestamp: ts, Type: vType}
|
||||||
|
)
|
||||||
|
defer sc.Stop()
|
||||||
|
defer pvss.Stop()
|
||||||
|
|
||||||
|
require.NoError(pvss.privVal.SignVote(chainID, want))
|
||||||
|
require.NoError(sc.SignVote(chainID, have))
|
||||||
|
assert.Equal(want.Signature, have.Signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSocketClientHeartbeat(t *testing.T) {
|
||||||
|
var (
|
||||||
|
assert, require = assert.New(t), require.New(t)
|
||||||
|
chainID = "test-chain-secret"
|
||||||
|
sc, pvss = testSetupSocketPair(t, chainID)
|
||||||
|
|
||||||
|
want = &types.Heartbeat{}
|
||||||
|
have = &types.Heartbeat{}
|
||||||
|
)
|
||||||
|
defer sc.Stop()
|
||||||
|
defer pvss.Stop()
|
||||||
|
|
||||||
|
require.NoError(pvss.privVal.SignHeartbeat(chainID, want))
|
||||||
|
require.NoError(sc.SignHeartbeat(chainID, have))
|
||||||
|
assert.Equal(want.Signature, have.Signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSocketClientConnectRetryMax(t *testing.T) {
|
||||||
|
var (
|
||||||
|
assert, _ = assert.New(t), require.New(t)
|
||||||
|
logger = log.TestingLogger()
|
||||||
|
clientPrivKey = crypto.GenPrivKeyEd25519()
|
||||||
|
sc = NewSocketClient(
|
||||||
|
logger,
|
||||||
|
"127.0.0.1:0",
|
||||||
|
&clientPrivKey,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
defer sc.Stop()
|
||||||
|
|
||||||
|
SocketClientTimeout(time.Millisecond)(sc)
|
||||||
|
|
||||||
|
assert.EqualError(sc.Start(), ErrDialRetryMax.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSetupSocketPair(t *testing.T, chainID string) (*socketClient, *PrivValidatorSocketServer) {
|
||||||
|
var (
|
||||||
|
assert, require = assert.New(t), require.New(t)
|
||||||
logger = log.TestingLogger()
|
logger = log.TestingLogger()
|
||||||
signer = types.GenSigner()
|
signer = types.GenSigner()
|
||||||
clientPrivKey = crypto.GenPrivKeyEd25519()
|
clientPrivKey = crypto.GenPrivKeyEd25519()
|
||||||
|
@ -33,116 +147,18 @@ func TestPrivValidatorSocketServer(t *testing.T) {
|
||||||
)
|
)
|
||||||
|
|
||||||
err := pvss.Start()
|
err := pvss.Start()
|
||||||
require.Nil(err)
|
require.NoError(err)
|
||||||
defer pvss.Stop()
|
|
||||||
|
|
||||||
assert.True(pvss.IsRunning())
|
assert.True(pvss.IsRunning())
|
||||||
|
|
||||||
pvsc := NewPrivValidatorSocketClient(
|
sc := NewSocketClient(
|
||||||
logger,
|
logger,
|
||||||
pvss.listener.Addr().String(),
|
pvss.listener.Addr().String(),
|
||||||
&clientPrivKey,
|
&clientPrivKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
err = pvsc.Start()
|
err = sc.Start()
|
||||||
require.Nil(err)
|
require.NoError(err)
|
||||||
defer pvsc.Stop()
|
assert.True(sc.IsRunning())
|
||||||
|
|
||||||
assert.True(pvsc.IsRunning())
|
return sc, pvss
|
||||||
|
|
||||||
cAddr, err := pvsc.Address()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
sAddr, err := pvss.privVal.Address()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
assert.Equal(cAddr, sAddr)
|
|
||||||
|
|
||||||
cKey, err := pvsc.PubKey()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
sKey, err := pvss.privVal.PubKey()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
assert.Equal(cKey, sKey)
|
|
||||||
|
|
||||||
err = pvsc.SignProposal(chainID, &types.Proposal{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
})
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
err = pvsc.SignVote(chainID, &types.Vote{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
Type: types.VoteTypePrecommit,
|
|
||||||
})
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
err = pvsc.SignHeartbeat(chainID, &types.Heartbeat{})
|
|
||||||
require.Nil(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPrivValidatorSocketServerWithoutSecret(t *testing.T) {
|
|
||||||
var (
|
|
||||||
assert, require = assert.New(t), require.New(t)
|
|
||||||
chainID = "test-chain-secret"
|
|
||||||
logger = log.TestingLogger()
|
|
||||||
signer = types.GenSigner()
|
|
||||||
privVal = NewTestPrivValidator(signer)
|
|
||||||
pvss = NewPrivValidatorSocketServer(
|
|
||||||
logger,
|
|
||||||
chainID,
|
|
||||||
"127.0.0.1:0",
|
|
||||||
1,
|
|
||||||
privVal,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
err := pvss.Start()
|
|
||||||
require.Nil(err)
|
|
||||||
defer pvss.Stop()
|
|
||||||
|
|
||||||
assert.True(pvss.IsRunning())
|
|
||||||
|
|
||||||
pvsc := NewPrivValidatorSocketClient(
|
|
||||||
logger,
|
|
||||||
pvss.listener.Addr().String(),
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
|
|
||||||
err = pvsc.Start()
|
|
||||||
require.Nil(err)
|
|
||||||
defer pvsc.Stop()
|
|
||||||
|
|
||||||
assert.True(pvsc.IsRunning())
|
|
||||||
|
|
||||||
cAddr, err := pvsc.Address()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
sAddr, err := pvss.privVal.Address()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
assert.Equal(cAddr, sAddr)
|
|
||||||
|
|
||||||
cKey, err := pvsc.PubKey()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
sKey, err := pvss.privVal.PubKey()
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
assert.Equal(cKey, sKey)
|
|
||||||
|
|
||||||
err = pvsc.SignProposal(chainID, &types.Proposal{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
})
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
err = pvsc.SignVote(chainID, &types.Vote{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
Type: types.VoteTypePrecommit,
|
|
||||||
})
|
|
||||||
require.Nil(err)
|
|
||||||
|
|
||||||
err = pvsc.SignHeartbeat(chainID, &types.Heartbeat{})
|
|
||||||
require.Nil(err)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue