You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
5.7 KiB

  1. package privval
  2. import (
  3. "fmt"
  4. "net"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. "github.com/tendermint/tendermint/crypto"
  10. cmn "github.com/tendermint/tmlibs/common"
  11. "github.com/tendermint/tmlibs/log"
  12. p2pconn "github.com/tendermint/tendermint/p2p/conn"
  13. "github.com/tendermint/tendermint/types"
  14. )
  15. func TestSocketPVAddress(t *testing.T) {
  16. var (
  17. chainID = cmn.RandStr(12)
  18. sc, rs = testSetupSocketPair(t, chainID)
  19. )
  20. defer sc.Stop()
  21. defer rs.Stop()
  22. serverAddr := rs.privVal.GetAddress()
  23. clientAddr, err := sc.getAddress()
  24. require.NoError(t, err)
  25. assert.Equal(t, serverAddr, clientAddr)
  26. // TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
  27. assert.Equal(t, serverAddr, sc.GetAddress())
  28. }
  29. func TestSocketPVPubKey(t *testing.T) {
  30. var (
  31. chainID = cmn.RandStr(12)
  32. sc, rs = testSetupSocketPair(t, chainID)
  33. )
  34. defer sc.Stop()
  35. defer rs.Stop()
  36. clientKey, err := sc.getPubKey()
  37. require.NoError(t, err)
  38. privKey := rs.privVal.GetPubKey()
  39. assert.Equal(t, privKey, clientKey)
  40. // TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
  41. assert.Equal(t, privKey, sc.GetPubKey())
  42. }
  43. func TestSocketPVProposal(t *testing.T) {
  44. var (
  45. chainID = cmn.RandStr(12)
  46. sc, rs = testSetupSocketPair(t, chainID)
  47. ts = time.Now()
  48. privProposal = &types.Proposal{Timestamp: ts}
  49. clientProposal = &types.Proposal{Timestamp: ts}
  50. )
  51. defer sc.Stop()
  52. defer rs.Stop()
  53. require.NoError(t, rs.privVal.SignProposal(chainID, privProposal))
  54. require.NoError(t, sc.SignProposal(chainID, clientProposal))
  55. assert.Equal(t, privProposal.Signature, clientProposal.Signature)
  56. }
  57. func TestSocketPVVote(t *testing.T) {
  58. var (
  59. chainID = cmn.RandStr(12)
  60. sc, rs = testSetupSocketPair(t, chainID)
  61. ts = time.Now()
  62. vType = types.VoteTypePrecommit
  63. want = &types.Vote{Timestamp: ts, Type: vType}
  64. have = &types.Vote{Timestamp: ts, Type: vType}
  65. )
  66. defer sc.Stop()
  67. defer rs.Stop()
  68. require.NoError(t, rs.privVal.SignVote(chainID, want))
  69. require.NoError(t, sc.SignVote(chainID, have))
  70. assert.Equal(t, want.Signature, have.Signature)
  71. }
  72. func TestSocketPVHeartbeat(t *testing.T) {
  73. var (
  74. chainID = cmn.RandStr(12)
  75. sc, rs = testSetupSocketPair(t, chainID)
  76. want = &types.Heartbeat{}
  77. have = &types.Heartbeat{}
  78. )
  79. defer sc.Stop()
  80. defer rs.Stop()
  81. require.NoError(t, rs.privVal.SignHeartbeat(chainID, want))
  82. require.NoError(t, sc.SignHeartbeat(chainID, have))
  83. assert.Equal(t, want.Signature, have.Signature)
  84. }
  85. func TestSocketPVAcceptDeadline(t *testing.T) {
  86. var (
  87. sc = NewSocketPV(
  88. log.TestingLogger(),
  89. "127.0.0.1:0",
  90. crypto.GenPrivKeyEd25519(),
  91. )
  92. )
  93. defer sc.Stop()
  94. SocketPVAcceptDeadline(time.Millisecond)(sc)
  95. assert.Equal(t, sc.Start().(cmn.Error).Data(), ErrConnWaitTimeout)
  96. }
  97. func TestSocketPVDeadline(t *testing.T) {
  98. var (
  99. addr = testFreeAddr(t)
  100. listenc = make(chan struct{})
  101. sc = NewSocketPV(
  102. log.TestingLogger(),
  103. addr,
  104. crypto.GenPrivKeyEd25519(),
  105. )
  106. )
  107. SocketPVConnDeadline(100 * time.Millisecond)(sc)
  108. SocketPVConnWait(500 * time.Millisecond)(sc)
  109. go func(sc *SocketPV) {
  110. defer close(listenc)
  111. require.NoError(t, sc.Start())
  112. assert.True(t, sc.IsRunning())
  113. }(sc)
  114. for {
  115. conn, err := cmn.Connect(addr)
  116. if err != nil {
  117. continue
  118. }
  119. _, err = p2pconn.MakeSecretConnection(
  120. conn,
  121. crypto.GenPrivKeyEd25519(),
  122. )
  123. if err == nil {
  124. break
  125. }
  126. }
  127. <-listenc
  128. // Sleep to guarantee deadline has been hit.
  129. time.Sleep(20 * time.Microsecond)
  130. _, err := sc.getPubKey()
  131. assert.Equal(t, err.(cmn.Error).Data(), ErrConnTimeout)
  132. }
  133. func TestSocketPVWait(t *testing.T) {
  134. sc := NewSocketPV(
  135. log.TestingLogger(),
  136. "127.0.0.1:0",
  137. crypto.GenPrivKeyEd25519(),
  138. )
  139. defer sc.Stop()
  140. SocketPVConnWait(time.Millisecond)(sc)
  141. assert.Equal(t, sc.Start().(cmn.Error).Data(), ErrConnWaitTimeout)
  142. }
  143. func TestRemoteSignerRetry(t *testing.T) {
  144. var (
  145. attemptc = make(chan int)
  146. retries = 2
  147. )
  148. ln, err := net.Listen("tcp", "127.0.0.1:0")
  149. require.NoError(t, err)
  150. go func(ln net.Listener, attemptc chan<- int) {
  151. attempts := 0
  152. for {
  153. conn, err := ln.Accept()
  154. require.NoError(t, err)
  155. err = conn.Close()
  156. require.NoError(t, err)
  157. attempts++
  158. if attempts == retries {
  159. attemptc <- attempts
  160. break
  161. }
  162. }
  163. }(ln, attemptc)
  164. rs := NewRemoteSigner(
  165. log.TestingLogger(),
  166. cmn.RandStr(12),
  167. ln.Addr().String(),
  168. types.NewMockPV(),
  169. crypto.GenPrivKeyEd25519(),
  170. )
  171. defer rs.Stop()
  172. RemoteSignerConnDeadline(time.Millisecond)(rs)
  173. RemoteSignerConnRetries(retries)(rs)
  174. assert.Equal(t, rs.Start().(cmn.Error).Data(), ErrDialRetryMax)
  175. select {
  176. case attempts := <-attemptc:
  177. assert.Equal(t, retries, attempts)
  178. case <-time.After(100 * time.Millisecond):
  179. t.Error("expected remote to observe connection attempts")
  180. }
  181. }
  182. func testSetupSocketPair(
  183. t *testing.T,
  184. chainID string,
  185. ) (*SocketPV, *RemoteSigner) {
  186. var (
  187. addr = testFreeAddr(t)
  188. logger = log.TestingLogger()
  189. privVal = types.NewMockPV()
  190. readyc = make(chan struct{})
  191. rs = NewRemoteSigner(
  192. logger,
  193. chainID,
  194. addr,
  195. privVal,
  196. crypto.GenPrivKeyEd25519(),
  197. )
  198. sc = NewSocketPV(
  199. logger,
  200. addr,
  201. crypto.GenPrivKeyEd25519(),
  202. )
  203. )
  204. go func(sc *SocketPV) {
  205. require.NoError(t, sc.Start())
  206. assert.True(t, sc.IsRunning())
  207. readyc <- struct{}{}
  208. }(sc)
  209. RemoteSignerConnDeadline(time.Millisecond)(rs)
  210. RemoteSignerConnRetries(1e6)(rs)
  211. require.NoError(t, rs.Start())
  212. assert.True(t, rs.IsRunning())
  213. <-readyc
  214. return sc, rs
  215. }
  216. // testFreeAddr claims a free port so we don't block on listener being ready.
  217. func testFreeAddr(t *testing.T) string {
  218. ln, err := net.Listen("tcp", "127.0.0.1:0")
  219. require.NoError(t, err)
  220. defer ln.Close()
  221. return fmt.Sprintf("127.0.0.1:%d", ln.Addr().(*net.TCPAddr).Port)
  222. }