Skip to content

Commit 64cfb62

Browse files
author
Yehonatan Buchnik
authored
Fix Preprepare sizing issues (#2649)
* **Problem Overview** MessageBase considers the span size outside of the regular "size" parameter. Hence, in some cases, we may end up letting a message be larger than the allowed size. For example, if a prePrepare message span size is smaller than the max span size, we may end up with a message that exceeds a bit from the maximal size. This change is for fixing this issue * **Testing Done** CI tests
1 parent 9c2e6eb commit 64cfb62

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

bftengine/src/bftengine/messages/PrePrepareMsg.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,13 @@ PrePrepareMsg::PrePrepareMsg(ReplicaId sender,
151151
const concordUtils::SpanContext& spanContext,
152152
const std::string& batchCid,
153153
size_t size)
154-
: MessageBase(sender,
155-
MsgCode::PrePrepare,
156-
spanContext.data().size(),
157-
(((size + sizeof(Header) + batchCid.size()) < maxMessageSize<PrePrepareMsg>())
158-
? (size + sizeof(Header) + batchCid.size())
159-
: maxMessageSize<PrePrepareMsg>() - spanContext.data().size())) {
154+
: MessageBase(
155+
sender,
156+
MsgCode::PrePrepare,
157+
spanContext.data().size(),
158+
(((size + sizeof(Header) + batchCid.size()) + spanContext.data().size() < maxMessageSize<PrePrepareMsg>())
159+
? (size + sizeof(Header) + batchCid.size())
160+
: maxMessageSize<PrePrepareMsg>() - spanContext.data().size())) {
160161
bool ready = size == 0; // if null, then message is ready
161162
if (!ready) {
162163
b()->digestOfRequests.makeZero();

bftengine/src/bftengine/messages/PrePrepareMsg.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class RequestsIterator {
155155

156156
template <>
157157
inline MsgSize maxMessageSize<PrePrepareMsg>() {
158-
return ReplicaConfig::instance().getmaxExternalMessageSize() + MessageBase::SPAN_CONTEXT_MAX_SIZE;
158+
return ReplicaConfig::instance().getmaxExternalMessageSize();
159159
}
160160

161161
} // namespace impl

bftengine/tests/messages/PrePrepareMsg_test.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,35 @@ TEST_F(PrePrepareMsgTestFixture, base_methods) {
229229
testMessageBaseMethods(msg, MsgCode::PrePrepare, senderId, spanContext);
230230
}
231231

232+
TEST_F(PrePrepareMsgTestFixture, test_prePrepare_size) {
233+
bftEngine::ReservedPagesClientBase::setReservedPages(&res_pages_mock_);
234+
ReplicasInfo replicaInfo(createReplicaConfig(), false, false);
235+
ReplicaId senderId = 1u;
236+
ViewNum viewNum = 2u;
237+
SeqNum seqNum = 3u;
238+
CommitPath commitPath = CommitPath::OPTIMISTIC_FAST;
239+
// Create random span
240+
uint span_size = rand() % 1024;
241+
const std::string spanContext = getRandomStringOfLength(span_size);
242+
PrePrepareMsg msg(senderId,
243+
viewNum,
244+
seqNum,
245+
commitPath,
246+
concordUtils::SpanContext{spanContext},
247+
config.getmaxExternalMessageSize());
248+
std::vector<std::shared_ptr<ClientRequestMsg>> client_request;
249+
250+
while (true) {
251+
client_request.clear();
252+
create_random_client_requests(client_request, 1u);
253+
if (client_request.front()->size() > msg.remainingSizeForRequests()) break;
254+
msg.addRequest(client_request.front()->body(), client_request.front()->size());
255+
}
256+
msg.finishAddingRequests();
257+
EXPECT_NO_THROW(msg.validate(replicaInfo));
258+
ASSERT_TRUE(msg.size() <= config.getmaxExternalMessageSize());
259+
}
260+
232261
int main(int argc, char** argv) {
233262
::testing::InitGoogleTest(&argc, argv);
234263
return RUN_ALL_TESTS();

0 commit comments

Comments
 (0)