Skip to content

Commit 7e98ef2

Browse files
committed
Merge branch 'bite-2' into feature/985-move-block-finalization-to-zmq
2 parents 4e44aad + 24380a6 commit 7e98ef2

8 files changed

Lines changed: 554 additions & 45 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ file(GLOB_RECURSE COMMON_TEST_SOURCES
341341
"tests/unit/db/*.cpp"
342342
"tests/consensus_tests.cpp"
343343
"tests/sgx_tests.cpp"
344+
"tests/e2e/RestartBootstrapTests.cpp"
344345
)
345346

346347
set(TEST_SOURCES ${COMMON_TEST_SOURCES})
@@ -349,7 +350,7 @@ set(TEST_SOURCES ${COMMON_TEST_SOURCES})
349350
if (DEFINED BITE)
350351
file(GLOB_RECURSE BITE_TEST_SOURCES
351352
"tests/unit/bite/*.cpp"
352-
"tests/e2e/ReencryptionRandomConsensusTests.cpp"
353+
"tests/e2e/bite/*.cpp"
353354
)
354355
list(APPEND TEST_SOURCES ${BITE_TEST_SOURCES} libBLS/test/utils.cpp)
355356

Consensust.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ class Consensust {
5353
class StartFromScratch {
5454
public:
5555
StartFromScratch() {
56-
int i = system( "rm -rf /tmp/*.db.*" );
57-
i = system( "rm -rf /tmp/*.db" );
58-
i++; // make compiler happy
56+
system( "rm -rf /tmp/*.db" );
5957
Consensust::setConfigDirPath( boost::filesystem::system_complete( "." ) );
6058

6159
#ifdef GOOGLE_PROFILE

chains/Schain.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,7 @@ void Schain::bootstrap(block_id _lastCommittedBlockID, uint64_t _lastCommittedBl
12741274
try {
12751275
bool isBite2PatchEnabledForBlock = false;
12761276
#ifdef BITE
1277-
isBite2PatchEnabledForBlock = bite2Patch( getLastCommittedBlockTimeStamp().getS() );
1277+
isBite2PatchEnabledForBlock = bite2Patch( _lastCommittedBlockTimeStamp );
12781278
#endif
12791279
auto block = getNode()->getBlockDB()->getBlock(
12801280
_lastCommittedBlockID + 1, getCryptoManager() );
@@ -1304,9 +1304,20 @@ void Schain::bootstrap(block_id _lastCommittedBlockID, uint64_t _lastCommittedBl
13041304
_lastCommittedBlockTimeStamp = block->getTimeStampS();
13051305
_lastCommittedBlockTimeStampMs = block->getTimeStampMs();
13061306
CONS_LOG(info, "Pushed block to skaled:" << _lastCommittedBlockID);
1307+
} catch ( exception& e ) {
1308+
// Cant read the block from db, may be it is corrupt in the snapshot
1309+
CONS_LOG(err,
1310+
"Bootstrap could not read block "
1311+
<< (uint64_t) ( _lastCommittedBlockID + 1 )
1312+
<< " from db. Repair. Exception: " << e.what());
1313+
SkaleException::logNested(e);
1314+
// The block will be hopefully pulled by catchup
13071315
} catch (...) {
13081316
// Cant read the block from db, may be it is corrupt in the snapshot
1309-
CONS_LOG(err, "Bootstrap could not read block from db. Repair.");
1317+
CONS_LOG(err,
1318+
"Bootstrap could not read block "
1319+
<< (uint64_t) ( _lastCommittedBlockID + 1 )
1320+
<< " from db. Repair. Exception: unknown");
13101321
// The block will be hopefully pulled by catchup
13111322
}
13121323
}

datastructures/TransactionList.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,11 @@ ptr< ConsensusExtFace::Transactions > TransactionList::createTransactionVector(
165165
// TODO - refactor to simply call biteManager->parseBITETransactions
166166
if (biteManager) {
167167
auto epochId = biteManager->getSchain()->getNode()->getCurrentEpochId();
168+
bool isBite2PatchEnabled = biteManager->getSchain()->bite2Patch(
169+
biteManager->getSchain()->getLastCommittedBlockTimeStamp().getS() );
168170
for (size_t i = 0; i < transactions->size(); i++) {
169171
auto tx = transactions->at(i);
170-
if (BiteEngine::tryGetEncryptedCTXArgs(tx, epochId)) {
172+
if (isBite2PatchEnabled && BiteEngine::tryGetEncryptedCTXArgs(tx, epochId)) {
171173
tv->pushBackCTX(*(tx->getData()));
172174
}
173175
else {

scripts/tests.py

Lines changed: 102 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,63 +26,133 @@
2626
import subprocess
2727

2828

29-
def run_without_check(_command):
29+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
30+
REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
31+
32+
33+
def print_separator(_label, _char="="):
34+
line = _char * 80
35+
print("\n" + line)
36+
print(_label)
37+
print(line)
38+
39+
40+
def normalize_catch_expression(_testType):
41+
if len(_testType) >= 2 and _testType[0] == _testType[-1] and _testType[0] in ("'", '"'):
42+
return _testType[1:-1]
43+
return _testType
44+
45+
46+
def list_catch_test_names(_consensustExecutive, _testType):
47+
result = subprocess.run(
48+
[_consensustExecutive, normalize_catch_expression(_testType), "--list-test-names-only"],
49+
check=False,
50+
stdout=subprocess.PIPE,
51+
stderr=subprocess.PIPE,
52+
universal_newlines=True,
53+
)
54+
test_names = [line.strip() for line in result.stdout.splitlines() if line.strip()]
55+
if len(test_names) == 0:
56+
error_output = result.stderr.strip()
57+
raise RuntimeError(
58+
"Could not list Catch tests for {} (exit code {}): {}".format(
59+
_testType,
60+
result.returncode,
61+
error_output or "no tests matched",
62+
)
63+
)
64+
return test_names
65+
66+
67+
def run(_command, _label=None):
68+
if _label:
69+
print_separator(_label)
3070
print(">" + _command)
31-
subprocess.call(_command, shell=True)
71+
subprocess.check_call(_command, shell=True)
3272

3373

34-
def run(_command):
35-
print(">" + _command)
36-
subprocess.check_call(_command, shell=True)
74+
def run_args(_command, _label=None):
75+
if _label:
76+
print_separator(_label)
77+
print(">" + " ".join(_command))
78+
subprocess.check_call(_command)
79+
80+
81+
def run_catch_tests(_consensustExecutive, _testType, _label):
82+
# By default, split catch tests into separate runs
83+
# There are currently static variables that bleed state between tests
84+
# if we try running all under the same catch session, causing tests to fail
85+
86+
test_names = list_catch_test_names(_consensustExecutive, _testType)
87+
if len(test_names) == 0:
88+
raise RuntimeError("No Catch tests matched: " + _testType)
89+
print_separator(_label + " (" + str(len(test_names)) + " cases)")
3790

91+
for index, test_name in enumerate(test_names, 1):
92+
run_args(
93+
# use '"' delimiters to ensure test names with commas are treated as a single argument
94+
[_consensustExecutive, '"' + test_name + '"'],
95+
"[{}/{}] {}".format(index, len(test_names), test_name),
96+
)
3897

39-
def unitTest(_consensustExecutive, _testType):
40-
run("rm -f ./core")
41-
run(_consensustExecutive + " " + _testType)
98+
99+
def unitTest(_consensustExecutive, _testType, _label=None):
100+
label = _label or _testType
101+
run("rm -f ./core", "Cleanup for " + label)
102+
run_catch_tests(_consensustExecutive, _testType, "Catch tests: " + label)
42103

43104

44105
def fullConsensusTest(_test, _consensustExecutive, _testType):
45-
testDir = "test/" + _test
106+
testDir = os.path.join(REPO_ROOT, "test", _test)
46107
os.chdir(testDir)
47-
run("pwd")
48-
run("rm -rf " + testDir + "/core")
49-
run("rm -rf /tmp/*.db*")
50-
run(_consensustExecutive + " " + _testType)
51-
os.chdir("../..")
108+
run("pwd", "Entering " + testDir)
109+
run("rm -rf ./core", "Cleanup core files for " + _test)
110+
run("rm -rf /tmp/*.db*", "Cleanup db files for " + _test)
111+
run_catch_tests(
112+
_consensustExecutive,
113+
_testType,
114+
"Consensus test: " + _test + " " + _testType,
115+
)
116+
os.chdir(REPO_ROOT)
52117

53118

54119
def getConsensustExecutive():
55-
run_without_check("cp -f cmake-build-debug/consensust /tmp/consensust")
56-
run_without_check("cp -f build/consensust /tmp/consensust")
57-
consensustExecutive = "/tmp/consensust"
58-
return consensustExecutive
120+
candidates = [
121+
os.path.join(REPO_ROOT, "cmake-build-debug", "consensust"),
122+
os.path.join(REPO_ROOT, "build", "consensust"),
123+
]
124+
125+
for candidate in candidates:
126+
if os.path.isfile(candidate):
127+
return candidate
128+
129+
raise RuntimeError(
130+
"Could not find consensust binary. Looked in: {}".format(", ".join(candidates))
131+
)
59132

60133

61134
print("Starting tests.")
62135

63-
os.chdir("..")
136+
os.chdir(REPO_ROOT)
64137

65138
run("ccache -M 20G")
66139

67140
consensustExecutive = getConsensustExecutive()
68141

69142
# Run all non-end-to-end and non-performance unit tests
70-
unitTest(consensustExecutive, "~[end-to-end]~[performance]")
71-
unitTest(consensustExecutive, "'[end-to-end][db]'")
143+
unitTest(
144+
consensustExecutive,
145+
"~[end-to-end]~[performance]",
146+
"Non-end-to-end non-performance",
147+
)
72148

73-
74-
# fullConsensusTest("sixteennodes", consensustExecutive, "[consensus-finalization-download]")
75-
76-
# try:
77-
# fullConsensusTest("two_out_of_four", consensustExecutive, "[consensus-stuck]")
78-
# except:
79-
# print("Success")
149+
unitTest(
150+
consensustExecutive,
151+
"'[end-to-end][db]'",
152+
"End-to-end db tests",
153+
)
80154

81155

82156
fullConsensusTest("onenode", consensustExecutive, "[consensus-basic]")
83157
fullConsensusTest("twonodes", consensustExecutive, "[consensus-basic]")
84158
fullConsensusTest("fournodes", consensustExecutive, "[consensus-basic]")
85-
#fullConsensusTest("sixteennodes", consensustExecutive, "[consensus-basic]")
86-
#fullConsensusTest("fournodes_catchup", consensustExecutive, "[consensus-basic]")
87-
#fullConsensusTest("three_out_of_four", consensustExecutive, "[consensus-basic]")
88-

tests/e2e/ConsensusEngineTestAccess.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66

77
class ConsensusEngineTestAccess {
88
public:
9+
static node_id getFirstNodeId( const ConsensusEngine& e ) {
10+
CHECK_STATE( e.nodes.size() > 0 );
11+
auto it = e.nodes.begin();
12+
CHECK_STATE( it != e.nodes.end() );
13+
CHECK_STATE( it->second );
14+
return it->first;
15+
}
16+
917
static ptr<CommittedBlock> getCommittedBlockForBlockId(
1018
const ConsensusEngine& e, uint64_t id) {
1119

@@ -42,4 +50,44 @@ class ConsensusEngineTestAccess {
4250
return block;
4351

4452
}
53+
54+
static uint64_t getBootstrapBlockIDForNode( const ConsensusEngine& e, node_id node ) {
55+
auto it = e.nodes.find( node );
56+
CHECK_STATE2( it != e.nodes.end(), "Node with id " + to_string( node ) + " not found" );
57+
CHECK_STATE( it->second );
58+
auto schain = it->second->getSchain();
59+
CHECK_STATE( schain );
60+
return (uint64_t) schain->getBootstrapBlockID();
61+
}
62+
63+
static uint64_t getBootstrapBlockID( const ConsensusEngine& e ) {
64+
return getBootstrapBlockIDForNode( e, getFirstNodeId( e ) );
65+
}
66+
67+
static block_id getCurrentLastCommittedBlockIDForNode( const ConsensusEngine& e, node_id node ) {
68+
auto it = e.nodes.find( node );
69+
CHECK_STATE2( it != e.nodes.end(), "Node with id " + to_string( node ) + " not found" );
70+
CHECK_STATE( it->second );
71+
auto schain = it->second->getSchain();
72+
CHECK_STATE( schain );
73+
return schain->getLastCommittedBlockID();
74+
}
75+
76+
static block_id getCurrentLastCommittedBlockID( const ConsensusEngine& e ) {
77+
return getCurrentLastCommittedBlockIDForNode( e, getFirstNodeId( e ) );
78+
}
79+
80+
static TimeStamp getCurrentLastCommittedBlockTimeStampForNode(
81+
const ConsensusEngine& e, node_id node ) {
82+
auto it = e.nodes.find( node );
83+
CHECK_STATE2( it != e.nodes.end(), "Node with id " + to_string( node ) + " not found" );
84+
CHECK_STATE( it->second );
85+
auto schain = it->second->getSchain();
86+
CHECK_STATE( schain );
87+
return schain->getLastCommittedBlockTimeStamp();
88+
}
89+
90+
static TimeStamp getCurrentLastCommittedBlockTimeStamp( const ConsensusEngine& e ) {
91+
return getCurrentLastCommittedBlockTimeStampForNode( e, getFirstNodeId( e ) );
92+
}
4593
};

tests/e2e/E2ETestHelper.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class E2ETestHelper {
3838
inline static const string TWO_NODE_TEST_DATA_DIR = TEST_DATA_ROOT_DIR + "/twonodes_sameip";
3939
static constexpr uint64_t DEFAULT_RUN_TIME_S = 4;
4040
static constexpr uint64_t CROSS_NODE_RUN_TIME_S = 20;
41+
static constexpr uint64_t DEFAULT_STORAGE_LIMIT_BYTES = 1000000000;
4142

4243
static void configureTestEnvironment(
4344
bool _cleanDataDir,
@@ -64,6 +65,38 @@ class E2ETestHelper {
6465
setTestEnvVar( "TEST_TIME_S", "4", 0 );
6566
}
6667

68+
static void startEngine(
69+
ConsensusEngine*& _engine,
70+
int64_t _lastId,
71+
const std::map< string, uint64_t >& _patchTimestamps = {
72+
#ifdef BITE
73+
{ "bite2PatchTimestamp", 0 }
74+
#endif
75+
},
76+
ConsensusExtFace* _extFace = nullptr,
77+
uint64_t _lastCommittedBlockTimeStamp = 0,
78+
uint64_t _lastCommittedBlockTimeStampMs = 0,
79+
bool _useBlockIDFromConsensus = false ) {
80+
CATCH_REQUIRE( _engine == nullptr );
81+
82+
if ( _extFace != nullptr ) {
83+
CATCH_REQUIRE( _lastId >= 0 );
84+
_engine = new ConsensusEngine( *_extFace, (uint64_t) _lastId,
85+
_lastCommittedBlockTimeStamp, _lastCommittedBlockTimeStampMs, _patchTimestamps,
86+
DEFAULT_STORAGE_LIMIT_BYTES );
87+
} else {
88+
_engine = new ConsensusEngine( _lastId, DEFAULT_STORAGE_LIMIT_BYTES );
89+
if ( !_patchTimestamps.empty() ) {
90+
_engine->setTestPatchTimestamps( _patchTimestamps );
91+
}
92+
}
93+
94+
auto useBlockIdFromConsensus = _useBlockIDFromConsensus || ( _extFace == nullptr && _lastId == -1 );
95+
_engine->parseTestConfigsAndCreateAllNodes(
96+
Consensust::getConfigDirPath(), useBlockIdFromConsensus );
97+
_engine->slowStartBootStrapTest();
98+
}
99+
67100
static block_id startEngineAndWait(
68101
ConsensusEngine*& _engine,
69102
int64_t _lastId,
@@ -73,12 +106,7 @@ class E2ETestHelper {
73106
{ "bite2PatchTimestamp", 0 }
74107
#endif
75108
} ) {
76-
_engine = new ConsensusEngine( _lastId, 1000000000 );
77-
if ( !_patchTimestamps.empty() ) {
78-
_engine->setTestPatchTimestamps( _patchTimestamps );
79-
}
80-
_engine->parseTestConfigsAndCreateAllNodes( Consensust::getConfigDirPath(), _lastId == -1 );
81-
_engine->slowStartBootStrapTest();
109+
startEngine( _engine, _lastId, _patchTimestamps );
82110

83111
usleep( 1000 * 1000 * _runTimeS );
84112

0 commit comments

Comments
 (0)