in platform/consensus/ordering/pbft/commitment.cpp [159:235]
int Commitment::ProcessProposeMsg(std::unique_ptr<Context> context,
std::unique_ptr<Request> request) {
if (global_stats_->IsFaulty() || context == nullptr ||
context->signature.signature().empty()) {
LOG(ERROR) << "user request doesn't contain signature, reject";
return -2;
}
if (request->is_recovery()) {
if (message_manager_->GetNextSeq() == 0 ||
request->seq() == message_manager_->GetNextSeq()) {
message_manager_->SetNextSeq(request->seq() + 1);
} else {
LOG(ERROR) << " recovery request not valid:"
<< " current seq:" << message_manager_->GetNextSeq()
<< " data seq:" << request->seq();
return 0;
}
return message_manager_->AddConsensusMsg(context->signature,
std::move(request));
}
if (request->sender_id() != message_manager_->GetCurrentPrimary()) {
LOG(ERROR) << "the request is not from primary. sender:"
<< request->sender_id() << " seq:" << request->seq();
return -2;
}
/*
if(request->hash() != "null" + std::to_string(request->seq())
&& SignatureVerifier::CalculateHash(request->data()) != request->hash())
{ LOG(ERROR) << "the hash and data of the request don't match, reject";
return -2;
}
*/
if (request->sender_id() != config_.GetSelfInfo().id()) {
if (pre_verify_func_ && !pre_verify_func_(*request)) {
LOG(ERROR) << " check by the user func fail";
return -2;
}
// global_stats_->GetTransactionDetails(std::move(request));
BatchUserRequest batch_request;
batch_request.ParseFromString(request->data());
batch_request.clear_createtime();
std::string data;
batch_request.SerializeToString(&data);
// check signatures
bool valid =
verifier_->VerifyMessage(request->data(), request->data_signature());
if (!valid) {
LOG(ERROR) << "request is not valid:"
<< request->data_signature().DebugString();
LOG(ERROR) << " msg:" << request->data().size();
return -2;
}
if (duplicate_manager_->CheckAndAddProposed(request->hash())) {
LOG(INFO) << "The request is already proposed, reject";
return -2;
}
}
global_stats_->IncPropose();
global_stats_->RecordStateTime("pre-prepare");
std::unique_ptr<Request> prepare_request = resdb::NewRequest(
Request::TYPE_PREPARE, *request, config_.GetSelfInfo().id());
prepare_request->clear_data();
// Add request to message_manager.
// If it has received enough same requests(2f+1), broadcast the prepare
// message.
CollectorResultCode ret =
message_manager_->AddConsensusMsg(context->signature, std::move(request));
if (ret == CollectorResultCode::STATE_CHANGED) {
replica_communicator_->BroadCast(*prepare_request);
}
return ret == CollectorResultCode::INVALID ? -2 : 0;
}