Skip to content

Commit 71f1645

Browse files
authored
Merge pull request #1570 from AntelopeIO/GH-1492-late-block-test
Test: Late blocks to producer
2 parents 4c144dc + 6b7cf03 commit 71f1645

File tree

5 files changed

+239
-3
lines changed

5 files changed

+239
-3
lines changed

plugins/net_plugin/net_plugin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2708,7 +2708,7 @@ namespace eosio {
27082708

27092709
// thread safe
27102710
void dispatch_manager::bcast_block(const signed_block_ptr& b, const block_id_type& id) {
2711-
fc_dlog( p2p_blk_log, "bcast block ${b}", ("b", b->block_num()) );
2711+
fc_dlog( p2p_blk_log, "bcast block ${b}:${id}", ("b", b->block_num())("id", id.str().substr(8,16)) );
27122712

27132713
if(my_impl->sync_master->syncing_from_peer() ) return;
27142714

tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_chainbase_allocation_test.py $
4343
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_protocol_feature_test.py ${CMAKE_CURRENT_BINARY_DIR}/nodeos_protocol_feature_test.py COPYONLY)
4444
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_multiple_version_protocol_feature_test.py ${CMAKE_CURRENT_BINARY_DIR}/nodeos_multiple_version_protocol_feature_test.py COPYONLY)
4545
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_extra_packed_data_test.py ${CMAKE_CURRENT_BINARY_DIR}/nodeos_extra_packed_data_test.py COPYONLY)
46+
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_late_block_test.py ${CMAKE_CURRENT_BINARY_DIR}/nodeos_late_block_test.py COPYONLY)
47+
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nodeos_late_block_test_shape.json ${CMAKE_CURRENT_BINARY_DIR}/nodeos_late_block_test_shape.json COPYONLY)
4648
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/validate-dirty-db.py ${CMAKE_CURRENT_BINARY_DIR}/validate-dirty-db.py COPYONLY)
4749
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/keosd_auto_launch_test.py ${CMAKE_CURRENT_BINARY_DIR}/keosd_auto_launch_test.py COPYONLY)
4850
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/db_modes_test.sh ${CMAKE_CURRENT_BINARY_DIR}/db_modes_test.sh COPYONLY)
@@ -206,6 +208,7 @@ add_np_test(NAME nodeos_snapshot_diff_test COMMAND tests/nodeos_snapshot_diff_te
206208
add_np_test(NAME nodeos_snapshot_diff_if_test COMMAND tests/nodeos_snapshot_diff_test.py -v --activate-if ${UNSHARE})
207209
add_np_test(NAME nodeos_snapshot_forked_test COMMAND tests/nodeos_snapshot_forked_test.py -v ${UNSHARE})
208210
add_np_test(NAME nodeos_snapshot_forked_if_test COMMAND tests/nodeos_snapshot_forked_test.py -v --activate-if ${UNSHARE})
211+
add_np_test(NAME nodeos_late_block_test COMMAND tests/nodeos_late_block_test.py -v ${UNSHARE})
209212

210213
add_np_test(NAME trx_finality_status_test COMMAND tests/trx_finality_status_test.py -v ${UNSHARE})
211214
add_np_test(NAME trx_finality_status_if_test COMMAND tests/trx_finality_status_test.py -v --activate-if ${UNSHARE})

tests/TestHarness/Node.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,21 +676,23 @@ def findStderrFiles(path):
676676
def findInLog(self, searchStr):
677677
dataDir=Utils.getNodeDataDir(self.nodeId)
678678
files=Node.findStderrFiles(dataDir)
679+
pattern = re.compile(searchStr)
679680
for file in files:
680681
with open(file, 'r') as f:
681682
for line in f:
682-
if searchStr in line:
683+
if pattern.search(line):
683684
return True
684685
return False
685686

686687
def linesInLog(self, searchStr):
687688
dataDir=Utils.getNodeDataDir(self.nodeId)
688689
files=Node.findStderrFiles(dataDir)
690+
pattern = re.compile(searchStr)
689691
lines=[]
690692
for file in files:
691693
with open(file, 'r') as f:
692694
for line in f:
693-
if searchStr in line:
695+
if pattern.search(line):
694696
lines.append(line)
695697
return lines
696698

tests/nodeos_late_block_test.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import shutil
4+
import signal
5+
import time
6+
from TestHarness import Cluster, TestHelper, Utils, WalletMgr
7+
from TestHarness.Node import BlockType
8+
9+
###############################################################
10+
# nodeos_late_block_test
11+
#
12+
# Set up a cluster of 4 producer nodes so that 3 can reach consensus.
13+
# Node_00 - defproducera,b,c
14+
# Node_01 - defproducerd,e,f
15+
# Node_02 - defproducerg,h,i
16+
# Node_04 - bridge between 2 & 3
17+
# Node_03 - defproducerj,k,l
18+
#
19+
# When Node_02 is producing shutdown Node_04 and bring it back up when Node_03 is producing.
20+
# Verify that Node_03 realizes it should switch over to fork other nodes have chosen.
21+
###############################################################
22+
23+
Print=Utils.Print
24+
errorExit=Utils.errorExit
25+
26+
args=TestHelper.parse_args({"-d","--keep-logs","--dump-error-details","-v","--leave-running","--unshared"})
27+
pnodes=4
28+
total_nodes=pnodes + 1
29+
delay=args.d
30+
debug=args.v
31+
dumpErrorDetails=args.dump_error_details
32+
33+
Utils.Debug=debug
34+
testSuccessful=False
35+
36+
cluster=Cluster(unshared=args.unshared, keepRunning=args.leave_running, keepLogs=args.keep_logs)
37+
walletMgr=WalletMgr(True, keepRunning=args.leave_running, keepLogs=args.keep_logs)
38+
39+
try:
40+
TestHelper.printSystemInfo("BEGIN")
41+
cluster.setWalletMgr(walletMgr)
42+
43+
Print(f'producing nodes: {pnodes}, delay between nodes launch: {delay} second{"s" if delay != 1 else ""}')
44+
45+
Print("Stand up cluster")
46+
# do not allow pause production to interfere with late block test
47+
extraNodeosArgs=" --production-pause-vote-timeout-ms 0 "
48+
49+
if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, extraNodeosArgs=extraNodeosArgs,
50+
topo="./tests/nodeos_late_block_test_shape.json", delay=delay, loadSystemContract=False,
51+
activateIF=True, signatureProviderForNonProducer=True) is False:
52+
errorExit("Failed to stand up eos cluster.")
53+
54+
assert cluster.biosNode.getInfo(exitOnError=True)["head_block_producer"] != "eosio", "launch should have waited for production to change"
55+
cluster.biosNode.kill(signal.SIGTERM)
56+
cluster.waitOnClusterSync(blockAdvancing=5)
57+
58+
node3 = cluster.getNode(3)
59+
node4 = cluster.getNode(4) # bridge between 2 & 3
60+
61+
Print("Wait for producer before j")
62+
node3.waitForAnyProducer("defproducerh", exitOnError=True)
63+
node3.waitForAnyProducer("defproduceri", exitOnError=True)
64+
iProdBlockNum = node3.getHeadBlockNum()
65+
66+
node4.kill(signal.SIGTERM)
67+
assert not node4.verifyAlive(), "Node4 did not shutdown"
68+
69+
Print("Wait until Node_03 starts to produce its second round ")
70+
node3.waitForProducer("defproducerk", exitOnError=True)
71+
72+
Print("Relaunch bridge to connection Node_02 and Node_03")
73+
node4.relaunch()
74+
75+
Print("Verify Node_03 fork switches even though it is producing")
76+
node3.waitForProducer("defproduceri", exitOnError=True)
77+
Print("Verify fork switch")
78+
assert node3.findInLog("switching forks .* defproducerk"), "Expected to find 'switching forks' in node_03 log"
79+
80+
Print("Wait until Node_00 to produce")
81+
node3.waitForProducer("defproducera")
82+
83+
# verify the LIB blocks of defproduceri made it into the canonical chain
84+
# defproducerk has produced at least one block, but possibly more by time of relaunch, so verify only some of the round
85+
for i in range(9):
86+
defprod=node3.getBlockProducerByNum(iProdBlockNum + i)
87+
assert defprod == "defproduceri", f"expected defproduceri for block {iProdBlockNum + i}, instead: {defprod}"
88+
89+
# verify that defproducerk blocks made it into the canonical chain as well
90+
# It can take a while to resolve the fork, but should have at least one defproducerk block unless defproducerl
91+
# wins the fork in which case there will be another fork switch
92+
expectedProd = "defproducerk"
93+
if node3.findInLog("switching forks .* defproducerl"):
94+
expectedProd = "defproducera"
95+
iProdBlockNum += 12 # into the next set of blocks
96+
found_defproducer = False
97+
for i in range(12):
98+
defprod=node3.getBlockProducerByNum(iProdBlockNum + i)
99+
if defprod == expectedProd:
100+
found_defproducer = True
101+
102+
assert found_defproducer, f"expected {expectedProd} in blocks {iProdBlockNum}-{iProdBlockNum+12}"
103+
104+
testSuccessful=True
105+
finally:
106+
TestHelper.shutdown(cluster, walletMgr, testSuccessful=testSuccessful, dumpErrorDetails=dumpErrorDetails)
107+
108+
exitCode = 0 if testSuccessful else 1
109+
exit(exitCode)
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{
2+
"name": "testnet_",
3+
"nodes": {
4+
"bios":{
5+
"name": "bios",
6+
"keys": [
7+
{
8+
"privkey":"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3",
9+
"pubkey":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
10+
}
11+
],
12+
"peers": [
13+
"testnet_01",
14+
"testnet_02"
15+
],
16+
"producers": [
17+
"eosio"
18+
],
19+
"dont_start": false
20+
},
21+
"testnet_00":{
22+
"name": "testnet_00",
23+
"keys": [
24+
{
25+
"privkey":"5K3h9XiAmrx9EuqD8CRxHgQwEVDaWpqrhrnpdvwHtVzwJFMhNmE",
26+
"pubkey":"EOS7K5pQCk22ojetRdyumrqp6nJX6eiQiTWWcGkZAMGhoBxgcsxhK",
27+
"blspubkey":"PUB_BLS_kGOCEX1MM5Xl928OOvGLyNo3_GpV8av1HnoaCEGOD8bAu3MDvazu0gCZGA1G7msTh1ZTPMEMVdXMuRVS0tv_9bW9Ohz9XvgtjgbPpxxc_NaeENkGg4uDBOro0Rk8DCEW4ToLKA",
28+
"blsprivkey":"PVT_BLS_EnQXObGKvYqfubrKjxpCqNkHeLlkQg7LERjDGm1RKjgyFZnk",
29+
"blspop":"SIG_BLS_bXrzPVc-ahxOCWrcl-iWIMuS8ego54iz7vi38A8h_ViqtxklH9O3A2z0eiw5j40M08ejiTm7JbCY_GOwulv1oXb9SaLYQkCTZjzCVssDkghLBRTVCZW2oJmU9WbZXikNw6nkygTs5sUTtCda2a_M5jqY_Rw92_NWmbolgBNkFvMcAgSHexdETA-b7QgJX_oYBWkyP0Pt8LzO6bJueZSjH8wZ8VuPc9o8taY85mt_qgdOTbXVBG2m5ud0eAUps2UHAHt-Ig"
30+
}
31+
],
32+
"peers": [
33+
"testnet_01",
34+
"testnet_02"
35+
],
36+
"producers": [
37+
"defproducera",
38+
"defproducerb",
39+
"defproducerc"
40+
],
41+
"dont_start": false
42+
},
43+
"testnet_01":{
44+
"name": "testnet_01",
45+
"keys": [
46+
{
47+
"privkey":"5HviUPkTEtvF2B1nm8aZUnjma2TzgpKRjuXjwHyy3FME4xDbkZF",
48+
"pubkey":"EOS5CbcTDgbks2ptTxvyCbT9HFbzX7PDHUY2wN4DDnVBhhQr2ZNDE",
49+
"blspubkey":"PUB_BLS_Y8ndNvnrEpnzJcNUg49ncWDiDGRgR7WUmRRDR9yMURoS6zF14sPnbb-DsTGp0cEM628a4CmG6KXMhPJMqGZvb7RM_MGIwgbEhVaENL8rXeYLOuFDS375KHFgXxs2P5sZuaN7aA",
50+
"blsprivkey":"PVT_BLS_A1Mifu5xyaxiveyjnZ-qN2zOt-5_KLMpjTrDI9udcQNV1NBR",
51+
"blspop":"SIG_BLS_7D0OUU1h7E0AKkAmqV4v3Ot9oSPWJBOss4yDejr2x1g5G31cSSAYIAtqZOYC-ioNzddY7zkvTcbhKgBzv5a-G1HmV1pOCXXPJ5TL0iqU8Ks5abeEWCdhArGATmRQiSMYNcj9rMQcm3H6Z0pOlOdbDdt8Cg-SY_H4jEGmAY2ZqudAH_U8gS19aydJU-2uQq0SPIr2Okl-WNbc-q3NVQw6Y0sAHAwN4BOIHup2MJyDDDIbpSEkBchRp3zna1XJf6oBuUzpqQ"
52+
}
53+
],
54+
"peers": [
55+
"testnet_00",
56+
"testnet_01"
57+
],
58+
"producers": [
59+
"defproducerd",
60+
"defproducere",
61+
"defproducerf"
62+
],
63+
"dont_start": false
64+
},
65+
"testnet_02":{
66+
"name": "testnet_02",
67+
"keys": [
68+
{
69+
"privkey":"5KkQbdxFHr8Pg1N3DEMDdU7emFgUTwQvh99FDJrodFhUbbsAtQT",
70+
"pubkey":"EOS6Tkpf8kcDfa32WA9B4nTcEJ64ZdDMSNioDcaL6rzdMwnpzaWJB",
71+
"blspubkey":"PUB_BLS_Wf_O_QeyVhekDXS5q3qBxTyj_qxSrX_uiCY4z8ClpW0X2jrAVgAVHOQ9IR2H40QTWveD8QIGhhSbmSFPa0zFbs5k3yfnjfuuwpA7T1O13_LSdtxT19ehYiE4chZX6SUMJ09JFA",
72+
"blsprivkey":"PVT_BLS_1ZLWim0k80ssXswSZp1T3ydHO9U3gLnKKlEBIDy8927XDLLj",
73+
"blspop":"SIG_BLS_EL09aI3w-qCgarLM2Z5-T6sisSHBN0J4vMZxtGQklkOcAxgnCaPPXe0roxY4W0gVe2y6T01YrklmT_qZu2tAwqiNrVJcScY8QKvRSeczGBBab1MgnHvaAOuf6bA4JPAELIu2iPWfsS6-oLyLbNP5xtZpMXPHu3yaSJssXNOb5rcVs1KXaIUEagJeAlBBQEcKmFWfeAsJ_R8JDw4i9gSNmROzUjm6LVBpvB7vrnPDPFRA0BQ19H4FED6PtuFPShwJGVz4dg"
74+
}
75+
],
76+
"peers": [
77+
"testnet_00",
78+
"testnet_01",
79+
"testnet_04"
80+
],
81+
"producers": [
82+
"defproducerg",
83+
"defproducerh",
84+
"defproduceri"
85+
],
86+
"dont_start": false
87+
},
88+
"testnet_03":{
89+
"name": "testnet_03",
90+
"keys": [
91+
{
92+
"privkey":"5JxTJJegQBpEL1p77TzkN1ompMB9gDwAfjM9chPzFCB4chxmwrE",
93+
"pubkey":"EOS52ntDHqA2qj4xVo7KmxdezMRhvvBqpZBuKYJCsgihisxmywpAx",
94+
"blspubkey":"PUB_BLS_C-FprIiry6X-8dlLYH7xUAhIuKXBQv56zJPgtcdmKeHf8AAy750eRrOYBtKG0-QEIN5l_yl9dTLvAYmOios6Q5t3ybWBUVVQ2WWcbZLVxzwBftLwYvo1zPXH7LHEE_sAgP1i7g",
95+
"blsprivkey":"PVT_BLS_ubElmjajfsYP_9HRSpmV-Fi_IPWKTyJS4XFSWrU8ezMZ_mL_",
96+
"blspop":"SIG_BLS_k3wrhVl2GUG_lGsPr9io-zoamPw7eiaxMDExk-yOqcpXtu0zALHoUWJRh0WOerAS1-_RQNhbi4q-BWO9IbiNWRKP9CYIhNIL6ochGHHy4aBmZ-IzEjfBrDt7inDtFTYY0Gl372e5OqPXAwi6J3GeHipXuzAiw7SV8XdWFefthxId4meKX6vw5_RWx4XQ4ScRYoCG7UQtIZkQPEsu1SfJGL6z-cfTTSq-naKbzp0QQYfqtQkFfmL7qQUH1iohnb0HbTbRbQ"
97+
}
98+
],
99+
"peers": [
100+
"testnet_04"
101+
],
102+
"producers": [
103+
"defproducerj",
104+
"defproducerk",
105+
"defproducerl"
106+
],
107+
"dont_start": false
108+
},
109+
"testnet_04":{
110+
"name": "testnet_04",
111+
"keys": [
112+
],
113+
"peers": [
114+
"testnet_02",
115+
"testnet_03"
116+
],
117+
"producers": [
118+
],
119+
"dont_start": false
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)