github.com/evdatsion/aphelion-dpos-bft@v0.32.1/node/node_test.go (about) 1 package node 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "os" 8 "syscall" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 15 "github.com/evdatsion/aphelion-dpos-bft/abci/example/kvstore" 16 cfg "github.com/evdatsion/aphelion-dpos-bft/config" 17 "github.com/evdatsion/aphelion-dpos-bft/crypto/ed25519" 18 "github.com/evdatsion/aphelion-dpos-bft/evidence" 19 cmn "github.com/evdatsion/aphelion-dpos-bft/libs/common" 20 dbm "github.com/evdatsion/aphelion-dpos-bft/libs/db" 21 "github.com/evdatsion/aphelion-dpos-bft/libs/log" 22 mempl "github.com/evdatsion/aphelion-dpos-bft/mempool" 23 "github.com/evdatsion/aphelion-dpos-bft/p2p" 24 p2pmock "github.com/evdatsion/aphelion-dpos-bft/p2p/mock" 25 "github.com/evdatsion/aphelion-dpos-bft/privval" 26 "github.com/evdatsion/aphelion-dpos-bft/proxy" 27 sm "github.com/evdatsion/aphelion-dpos-bft/state" 28 "github.com/evdatsion/aphelion-dpos-bft/types" 29 tmtime "github.com/evdatsion/aphelion-dpos-bft/types/time" 30 "github.com/evdatsion/aphelion-dpos-bft/version" 31 ) 32 33 func TestNodeStartStop(t *testing.T) { 34 config := cfg.ResetTestRoot("node_node_test") 35 defer os.RemoveAll(config.RootDir) 36 37 // create & start node 38 n, err := DefaultNewNode(config, log.TestingLogger()) 39 require.NoError(t, err) 40 err = n.Start() 41 require.NoError(t, err) 42 43 t.Logf("Started node %v", n.sw.NodeInfo()) 44 45 // wait for the node to produce a block 46 blocksSub, err := n.EventBus().Subscribe(context.Background(), "node_test", types.EventQueryNewBlock) 47 require.NoError(t, err) 48 select { 49 case <-blocksSub.Out(): 50 case <-blocksSub.Cancelled(): 51 t.Fatal("blocksSub was cancelled") 52 case <-time.After(10 * time.Second): 53 t.Fatal("timed out waiting for the node to produce a block") 54 } 55 56 // stop the node 57 go func() { 58 n.Stop() 59 }() 60 61 select { 62 case <-n.Quit(): 63 case <-time.After(5 * time.Second): 64 pid := os.Getpid() 65 p, err := os.FindProcess(pid) 66 if err != nil { 67 panic(err) 68 } 69 err = p.Signal(syscall.SIGABRT) 70 fmt.Println(err) 71 t.Fatal("timed out waiting for shutdown") 72 } 73 } 74 75 func TestSplitAndTrimEmpty(t *testing.T) { 76 testCases := []struct { 77 s string 78 sep string 79 cutset string 80 expected []string 81 }{ 82 {"a,b,c", ",", " ", []string{"a", "b", "c"}}, 83 {" a , b , c ", ",", " ", []string{"a", "b", "c"}}, 84 {" a, b, c ", ",", " ", []string{"a", "b", "c"}}, 85 {" a, ", ",", " ", []string{"a"}}, 86 {" ", ",", " ", []string{}}, 87 } 88 89 for _, tc := range testCases { 90 assert.Equal(t, tc.expected, splitAndTrimEmpty(tc.s, tc.sep, tc.cutset), "%s", tc.s) 91 } 92 } 93 94 func TestNodeDelayedStart(t *testing.T) { 95 config := cfg.ResetTestRoot("node_delayed_start_test") 96 defer os.RemoveAll(config.RootDir) 97 now := tmtime.Now() 98 99 // create & start node 100 n, err := DefaultNewNode(config, log.TestingLogger()) 101 n.GenesisDoc().GenesisTime = now.Add(2 * time.Second) 102 require.NoError(t, err) 103 104 err = n.Start() 105 require.NoError(t, err) 106 defer n.Stop() 107 108 startTime := tmtime.Now() 109 assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime)) 110 } 111 112 func TestNodeSetAppVersion(t *testing.T) { 113 config := cfg.ResetTestRoot("node_app_version_test") 114 defer os.RemoveAll(config.RootDir) 115 116 // create & start node 117 n, err := DefaultNewNode(config, log.TestingLogger()) 118 require.NoError(t, err) 119 120 // default config uses the kvstore app 121 var appVersion version.Protocol = kvstore.ProtocolVersion 122 123 // check version is set in state 124 state := sm.LoadState(n.stateDB) 125 assert.Equal(t, state.Version.Consensus.App, appVersion) 126 127 // check version is set in node info 128 assert.Equal(t, n.nodeInfo.(p2p.DefaultNodeInfo).ProtocolVersion.App, appVersion) 129 } 130 131 func TestNodeSetPrivValTCP(t *testing.T) { 132 addr := "tcp://" + testFreeAddr(t) 133 134 config := cfg.ResetTestRoot("node_priv_val_tcp_test") 135 defer os.RemoveAll(config.RootDir) 136 config.BaseConfig.PrivValidatorListenAddr = addr 137 138 dialer := privval.DialTCPFn(addr, 100*time.Millisecond, ed25519.GenPrivKey()) 139 pvsc := privval.NewSignerServiceEndpoint( 140 log.TestingLogger(), 141 config.ChainID(), 142 types.NewMockPV(), 143 dialer, 144 ) 145 privval.SignerServiceEndpointTimeoutReadWrite(100 * time.Millisecond)(pvsc) 146 147 go func() { 148 err := pvsc.Start() 149 if err != nil { 150 panic(err) 151 } 152 }() 153 defer pvsc.Stop() 154 155 n, err := DefaultNewNode(config, log.TestingLogger()) 156 require.NoError(t, err) 157 assert.IsType(t, &privval.SignerValidatorEndpoint{}, n.PrivValidator()) 158 } 159 160 // address without a protocol must result in error 161 func TestPrivValidatorListenAddrNoProtocol(t *testing.T) { 162 addrNoPrefix := testFreeAddr(t) 163 164 config := cfg.ResetTestRoot("node_priv_val_tcp_test") 165 defer os.RemoveAll(config.RootDir) 166 config.BaseConfig.PrivValidatorListenAddr = addrNoPrefix 167 168 _, err := DefaultNewNode(config, log.TestingLogger()) 169 assert.Error(t, err) 170 } 171 172 func TestNodeSetPrivValIPC(t *testing.T) { 173 tmpfile := "/tmp/kms." + cmn.RandStr(6) + ".sock" 174 defer os.Remove(tmpfile) // clean up 175 176 config := cfg.ResetTestRoot("node_priv_val_tcp_test") 177 defer os.RemoveAll(config.RootDir) 178 config.BaseConfig.PrivValidatorListenAddr = "unix://" + tmpfile 179 180 dialer := privval.DialUnixFn(tmpfile) 181 pvsc := privval.NewSignerServiceEndpoint( 182 log.TestingLogger(), 183 config.ChainID(), 184 types.NewMockPV(), 185 dialer, 186 ) 187 privval.SignerServiceEndpointTimeoutReadWrite(100 * time.Millisecond)(pvsc) 188 189 go func() { 190 err := pvsc.Start() 191 require.NoError(t, err) 192 }() 193 defer pvsc.Stop() 194 195 n, err := DefaultNewNode(config, log.TestingLogger()) 196 require.NoError(t, err) 197 assert.IsType(t, &privval.SignerValidatorEndpoint{}, n.PrivValidator()) 198 199 } 200 201 // testFreeAddr claims a free port so we don't block on listener being ready. 202 func testFreeAddr(t *testing.T) string { 203 ln, err := net.Listen("tcp", "127.0.0.1:0") 204 require.NoError(t, err) 205 defer ln.Close() 206 207 return fmt.Sprintf("127.0.0.1:%d", ln.Addr().(*net.TCPAddr).Port) 208 } 209 210 // create a proposal block using real and full 211 // mempool and evidence pool and validate it. 212 func TestCreateProposalBlock(t *testing.T) { 213 config := cfg.ResetTestRoot("node_create_proposal") 214 defer os.RemoveAll(config.RootDir) 215 cc := proxy.NewLocalClientCreator(kvstore.NewKVStoreApplication()) 216 proxyApp := proxy.NewAppConns(cc) 217 err := proxyApp.Start() 218 require.Nil(t, err) 219 defer proxyApp.Stop() 220 221 logger := log.TestingLogger() 222 223 var height int64 = 1 224 state, stateDB := state(1, height) 225 maxBytes := 16384 226 state.ConsensusParams.Block.MaxBytes = int64(maxBytes) 227 proposerAddr, _ := state.Validators.GetByIndex(0) 228 229 // Make Mempool 230 memplMetrics := mempl.PrometheusMetrics("node_test") 231 mempool := mempl.NewCListMempool( 232 config.Mempool, 233 proxyApp.Mempool(), 234 state.LastBlockHeight, 235 mempl.WithMetrics(memplMetrics), 236 mempl.WithPreCheck(sm.TxPreCheck(state)), 237 mempl.WithPostCheck(sm.TxPostCheck(state)), 238 ) 239 mempool.SetLogger(logger) 240 241 // Make EvidencePool 242 types.RegisterMockEvidencesGlobal() // XXX! 243 evidence.RegisterMockEvidences() 244 evidenceDB := dbm.NewMemDB() 245 evidencePool := evidence.NewEvidencePool(stateDB, evidenceDB) 246 evidencePool.SetLogger(logger) 247 248 // fill the evidence pool with more evidence 249 // than can fit in a block 250 minEvSize := 12 251 numEv := (maxBytes / types.MaxEvidenceBytesDenominator) / minEvSize 252 for i := 0; i < numEv; i++ { 253 ev := types.NewMockRandomGoodEvidence(1, proposerAddr, cmn.RandBytes(minEvSize)) 254 err := evidencePool.AddEvidence(ev) 255 assert.NoError(t, err) 256 } 257 258 // fill the mempool with more txs 259 // than can fit in a block 260 txLength := 1000 261 for i := 0; i < maxBytes/txLength; i++ { 262 tx := cmn.RandBytes(txLength) 263 err := mempool.CheckTx(tx, nil) 264 assert.NoError(t, err) 265 } 266 267 blockExec := sm.NewBlockExecutor( 268 stateDB, 269 logger, 270 proxyApp.Consensus(), 271 mempool, 272 evidencePool, 273 ) 274 275 commit := types.NewCommit(types.BlockID{}, nil) 276 block, _ := blockExec.CreateProposalBlock( 277 height, 278 state, commit, 279 proposerAddr, 280 ) 281 282 err = blockExec.ValidateBlock(state, block) 283 assert.NoError(t, err) 284 } 285 286 func TestNodeNewNodeCustomReactors(t *testing.T) { 287 config := cfg.ResetTestRoot("node_new_node_custom_reactors_test") 288 defer os.RemoveAll(config.RootDir) 289 290 cr := p2pmock.NewReactor() 291 292 nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) 293 require.NoError(t, err) 294 295 n, err := NewNode(config, 296 privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()), 297 nodeKey, 298 proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), 299 DefaultGenesisDocProviderFunc(config), 300 DefaultDBProvider, 301 DefaultMetricsProvider(config.Instrumentation), 302 log.TestingLogger(), 303 CustomReactors(map[string]p2p.Reactor{"FOO": cr}), 304 ) 305 require.NoError(t, err) 306 307 err = n.Start() 308 require.NoError(t, err) 309 defer n.Stop() 310 311 assert.True(t, cr.IsRunning()) 312 } 313 314 func state(nVals int, height int64) (sm.State, dbm.DB) { 315 vals := make([]types.GenesisValidator, nVals) 316 for i := 0; i < nVals; i++ { 317 secret := []byte(fmt.Sprintf("test%d", i)) 318 pk := ed25519.GenPrivKeyFromSecret(secret) 319 vals[i] = types.GenesisValidator{ 320 Address: pk.PubKey().Address(), 321 PubKey: pk.PubKey(), 322 Power: 1000, 323 Name: fmt.Sprintf("test%d", i), 324 } 325 } 326 s, _ := sm.MakeGenesisState(&types.GenesisDoc{ 327 ChainID: "test-chain", 328 Validators: vals, 329 AppHash: nil, 330 }) 331 332 // save validators to db for 2 heights 333 stateDB := dbm.NewMemDB() 334 sm.SaveState(stateDB, s) 335 336 for i := 1; i < int(height); i++ { 337 s.LastBlockHeight++ 338 s.LastValidators = s.Validators.Copy() 339 sm.SaveState(stateDB, s) 340 } 341 return s, stateDB 342 }