Skip to content

Commit 420615c

Browse files
Merge #6635: refactor: reduce ostringstream usage, set UniValue variable to object during construction, reduce GetHash() usage
f292483 refactor: use empty() instead of comparing against empty string literal (Kittywhiskers Van Gogh) d30b9ae refactor: reduce ostringstream usage when constructing strings (Kittywhiskers Van Gogh) 7200505 refactor: stop using ostringstream to construct filter strings (Kittywhiskers Van Gogh) 1c4f441 util: implement string padding function (Kittywhiskers Van Gogh) 5bfc4bc refactor: use `UniValue::VOBJ` instead of `setObject()` when possible (Kittywhiskers Van Gogh) 8b09188 refactor: store `tx_hash` instead of calling `GetHash()` repeatedly (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * Dependency for #6627 * We use `std::ostringstream` in `masternodelist` to pad values using `std::setw` ([source](https://github.com/dashpay/dash/blob/bcd14b05cec7d94986f114ca17bbdadbee701d9b/src/rpc/masternode.cpp#L574-L575)) for consistency, this was fine because we didn't plan on removing anything from the stream after it was added. But in [dash#6627](#6627), we intend to print multiple addresses and need to remove excess padding after the last entry, which can be trivially done with a `pop_back()` ([source](https://github.com/dashpay/dash/blob/bba9c6dd8e2edbbb83a26763a1d64209409b5b82/src/rpc/masternode.cpp#L569-L572)) but that cannot be done with a `std::ostringstream`. The best that can be done is rewinding the cursor but that doesn't change its contents and at most lets you overwrite it ([source](https://stackoverflow.com/a/26492431)), which is fine when you do have something to overwrite it with but this isn't always the case. To get around this, `PadString()` has been implemented and `std::ostringstream` usage has been replaced with constructing a string with `strprintf`. ## Breaking Changes None expected. ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK f292483 PastaPastaPasta: utACK f292483 Tree-SHA512: a3ca9dffc4d13bae80469f669af64d924a9bc6fd02d04832dc1bd07a7016b64973ce41c4dc54dc9c6f580ae92e00edb1cafeeb3b2ee29ae93f2f565ec7f18008
2 parents 1011056 + f292483 commit 420615c

File tree

18 files changed

+199
-227
lines changed

18 files changed

+199
-227
lines changed

src/evo/deterministicmns.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ std::string CDeterministicMN::ToString() const
4444

4545
UniValue CDeterministicMN::ToJson() const
4646
{
47-
UniValue obj;
48-
obj.setObject();
49-
47+
UniValue obj(UniValue::VOBJ);
5048
obj.pushKV("type", std::string(GetMnType(nType).description));
5149
obj.pushKV("proTxHash", proTxHash.ToString());
5250
obj.pushKV("collateralHash", collateralOutpoint.hash.ToString());

src/evo/dmnstate.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ std::string CDeterministicMNState::ToString() const
3737

3838
UniValue CDeterministicMNState::ToJson(MnType nType) const
3939
{
40-
UniValue obj;
41-
obj.setObject();
40+
UniValue obj(UniValue::VOBJ);
4241
obj.pushKV("version", nVersion);
4342
obj.pushKV("service", addr.ToStringAddrPort());
4443
obj.pushKV("registeredHeight", nRegisteredHeight);
@@ -69,8 +68,7 @@ UniValue CDeterministicMNState::ToJson(MnType nType) const
6968

7069
UniValue CDeterministicMNStateDiff::ToJson(MnType nType) const
7170
{
72-
UniValue obj;
73-
obj.setObject();
71+
UniValue obj(UniValue::VOBJ);
7472
if (fields & Field_nVersion) {
7573
obj.pushKV("version", state.nVersion);
7674
}

src/evo/mnhftx.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ class MNHFTx
4949

5050
[[nodiscard]] UniValue ToJson() const
5151
{
52-
UniValue obj;
53-
obj.clear();
54-
obj.setObject();
52+
UniValue obj(UniValue::VOBJ);
5553
obj.pushKV("versionBit", (int)versionBit);
5654
obj.pushKV("quorumHash", quorumHash.ToString());
5755
obj.pushKV("sig", sig.ToString());

src/evo/simplifiedmns.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ std::string CSimplifiedMNListEntry::ToString() const
7272

7373
UniValue CSimplifiedMNListEntry::ToJson(bool extended) const
7474
{
75-
UniValue obj;
76-
obj.setObject();
75+
UniValue obj(UniValue::VOBJ);
7776
obj.pushKV("nVersion", nVersion);
7877
obj.pushKV("nType", ToUnderlying(nType));
7978
obj.pushKV("proRegTxHash", proRegTxHash.ToString());
@@ -239,8 +238,7 @@ bool CSimplifiedMNListDiff::BuildQuorumChainlockInfo(const llmq::CQuorumManager&
239238

240239
UniValue CSimplifiedMNListDiff::ToJson(bool extended) const
241240
{
242-
UniValue obj;
243-
obj.setObject();
241+
UniValue obj(UniValue::VOBJ);
244242

245243
obj.pushKV("nVersion", nVersion);
246244
obj.pushKV("baseBlockHash", baseBlockHash.ToString());

src/governance/classes.cpp

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -24,55 +24,41 @@ CAmount ParsePaymentAmount(const std::string& strAmount)
2424
{
2525
CAmount nAmount = 0;
2626
if (strAmount.empty()) {
27-
std::ostringstream ostr;
28-
ostr << "ParsePaymentAmount: Amount is empty";
29-
throw std::runtime_error(ostr.str());
27+
throw std::runtime_error(strprintf("%s -- Amount is empty", __func__));
3028
}
3129
if (strAmount.size() > 20) {
3230
// String is much too long, the functions below impose stricter
3331
// requirements
34-
std::ostringstream ostr;
35-
ostr << "ParsePaymentAmount: Amount string too long";
36-
throw std::runtime_error(ostr.str());
32+
throw std::runtime_error(strprintf("%s -- Amount string too long", __func__));
3733
}
3834
// Make sure the string makes sense as an amount
3935
// Note: No spaces allowed
4036
// Also note: No scientific notation
4137
size_t pos = strAmount.find_first_not_of("0123456789.");
4238
if (pos != std::string::npos) {
43-
std::ostringstream ostr;
44-
ostr << "ParsePaymentAmount: Amount string contains invalid character";
45-
throw std::runtime_error(ostr.str());
39+
throw std::runtime_error(strprintf("%s -- Amount string contains invalid character", __func__));
4640
}
4741

4842
pos = strAmount.find('.');
4943
if (pos == 0) {
5044
// JSON doesn't allow values to start with a decimal point
51-
std::ostringstream ostr;
52-
ostr << "ParsePaymentAmount: Invalid amount string, leading decimal point not allowed";
53-
throw std::runtime_error(ostr.str());
45+
throw std::runtime_error(strprintf("%s -- Invalid amount string, leading decimal point not allowed", __func__));
5446
}
5547

5648
// Make sure there's no more than 1 decimal point
5749
if ((pos != std::string::npos) && (strAmount.find('.', pos + 1) != std::string::npos)) {
58-
std::ostringstream ostr;
59-
ostr << "ParsePaymentAmount: Invalid amount string, too many decimal points";
60-
throw std::runtime_error(ostr.str());
50+
throw std::runtime_error(strprintf("%s -- Invalid amount string, too many decimal points", __func__));
6151
}
6252

6353
// Note this code is taken from AmountFromValue in rpcserver.cpp
6454
// which is used for parsing the amounts in createrawtransaction.
6555
if (!ParseFixedPoint(strAmount, 8, &nAmount)) {
6656
nAmount = 0;
67-
std::ostringstream ostr;
68-
ostr << "ParsePaymentAmount: ParseFixedPoint failed for string: " << strAmount;
69-
throw std::runtime_error(ostr.str());
57+
throw std::runtime_error(strprintf("%s -- ParseFixedPoint failed for string \"%s\"", __func__, strAmount));
7058
}
7159
if (!MoneyRange(nAmount)) {
7260
nAmount = 0;
73-
std::ostringstream ostr;
74-
ostr << "ParsePaymentAmount: Invalid amount string, value outside of valid money range";
75-
throw std::runtime_error(ostr.str());
61+
throw std::runtime_error(strprintf("%s -- Invalid amount string, value outside of valid money range", __func__));
7662
}
7763

7864
return nAmount;
@@ -188,17 +174,15 @@ void CSuperblock::ParsePaymentSchedule(const std::string& strPaymentAddresses, c
188174
// IF THESE DON'T MATCH, SOMETHING IS WRONG
189175

190176
if (vecPaymentAddresses.size() != vecPaymentAmounts.size() || vecPaymentAddresses.size() != vecProposalHashes.size()) {
191-
std::ostringstream ostr;
192-
ostr << "CSuperblock::ParsePaymentSchedule -- Mismatched payments, amounts and proposalHashes";
193-
LogPrintf("%s\n", ostr.str());
194-
throw std::runtime_error(ostr.str());
177+
std::string msg{strprintf("CSuperblock::%s -- Mismatched payments, amounts and proposalHashes", __func__)};
178+
LogPrintf("%s\n", msg);
179+
throw std::runtime_error(msg);
195180
}
196181

197182
if (vecPaymentAddresses.empty()) {
198-
std::ostringstream ostr;
199-
ostr << "CSuperblock::ParsePaymentSchedule -- Error no payments";
200-
LogPrintf("%s\n", ostr.str());
201-
throw std::runtime_error(ostr.str());
183+
std::string msg{strprintf("CSuperblock::%s -- Error no payments", __func__)};
184+
LogPrintf("%s\n", msg);
185+
throw std::runtime_error(msg);
202186
}
203187

204188
// LOOP THROUGH THE ADDRESSES/AMOUNTS AND CREATE PAYMENTS
@@ -210,36 +194,33 @@ void CSuperblock::ParsePaymentSchedule(const std::string& strPaymentAddresses, c
210194
for (int i = 0; i < (int)vecPaymentAddresses.size(); i++) {
211195
CTxDestination dest = DecodeDestination(vecPaymentAddresses[i]);
212196
if (!IsValidDestination(dest)) {
213-
std::ostringstream ostr;
214-
ostr << "CSuperblock::ParsePaymentSchedule -- Invalid Dash Address : " << vecPaymentAddresses[i];
215-
LogPrintf("%s\n", ostr.str());
216-
throw std::runtime_error(ostr.str());
197+
std::string msg{strprintf("CSuperblock::%s -- Invalid Dash Address: %s", __func__, vecPaymentAddresses[i])};
198+
LogPrintf("%s\n", msg);
199+
throw std::runtime_error(msg);
217200
}
218201

219202
CAmount nAmount = ParsePaymentAmount(vecPaymentAmounts[i]);
220203

221204
uint256 proposalHash;
222205
if (!ParseHashStr(vecProposalHashes[i], proposalHash)) {
223-
std::ostringstream ostr;
224-
ostr << "CSuperblock::ParsePaymentSchedule -- Invalid proposal hash : " << vecProposalHashes[i];
225-
LogPrintf("%s\n", ostr.str());
226-
throw std::runtime_error(ostr.str());
206+
std::string msg{strprintf("CSuperblock::%s -- Invalid proposal hash: %s", __func__, vecProposalHashes[i])};
207+
LogPrintf("%s\n", msg);
208+
throw std::runtime_error(msg);
227209
}
228210

229211
LogPrint(BCLog::GOBJECT, /* Continued */
230-
"CSuperblock::ParsePaymentSchedule -- i = %d, amount string = %s, nAmount = %lld, proposalHash = %s\n",
212+
"CSuperblock::%s -- i = %d, amount string = %s, nAmount = %lld, proposalHash = %s\n", __func__,
231213
i, vecPaymentAmounts[i], nAmount, proposalHash.ToString());
232214

233215
CGovernancePayment payment(dest, nAmount, proposalHash);
234216
if (payment.IsValid()) {
235217
vecPayments.push_back(payment);
236218
} else {
237219
vecPayments.clear();
238-
std::ostringstream ostr;
239-
ostr << "CSuperblock::ParsePaymentSchedule -- Invalid payment found: address = " << EncodeDestination(dest)
240-
<< ", amount = " << nAmount;
241-
LogPrintf("%s\n", ostr.str());
242-
throw std::runtime_error(ostr.str());
220+
std::string msg{strprintf("CSuperblock::%s -- Invalid payment found: address = %s, amount = %d", __func__,
221+
EncodeDestination(dest), nAmount)};
222+
LogPrintf("%s\n", msg);
223+
throw std::runtime_error(msg);
243224
}
244225
}
245226
}

src/governance/exceptions.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <governance/exceptions.h>
6+
#include <tinyformat.h>
67

78
#include <iostream>
89
#include <sstream>
@@ -32,11 +33,8 @@ std::ostream& operator<<(std::ostream& os, governance_exception_type_enum_t eTyp
3233
CGovernanceException::CGovernanceException(const std::string& strMessageIn,
3334
governance_exception_type_enum_t eTypeIn,
3435
int nNodePenaltyIn) :
35-
strMessage(),
36-
eType(eTypeIn),
37-
nNodePenalty(nNodePenaltyIn)
36+
strMessage{strprintf("%s:%s", eTypeIn, strMessageIn)},
37+
eType{eTypeIn},
38+
nNodePenalty{nNodePenaltyIn}
3839
{
39-
std::ostringstream ostr;
40-
ostr << eType << ":" << strMessageIn;
41-
strMessage = ostr.str();
4240
}

src/governance/governance.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,44 +1131,43 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote,
11311131
uint256 nHashGovobj = vote.GetParentHash();
11321132

11331133
if (cmapVoteToObject.HasKey(nHashVote)) {
1134-
LogPrint(BCLog::GOBJECT, "CGovernanceObject::ProcessVote -- skipping known valid vote %s for object %s\n", nHashVote.ToString(), nHashGovobj.ToString());
1134+
LogPrint(BCLog::GOBJECT, "CGovernanceObject::%s -- skipping known valid vote %s for object %s\n", __func__,
1135+
nHashVote.ToString(), nHashGovobj.ToString());
11351136
LEAVE_CRITICAL_SECTION(cs);
11361137
return false;
11371138
}
11381139

11391140
if (cmapInvalidVotes.HasKey(nHashVote)) {
1140-
std::ostringstream ostr;
1141-
ostr << "CGovernanceManager::ProcessVote -- Old invalid vote "
1142-
<< ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort()
1143-
<< ", governance object hash = " << nHashGovobj.ToString();
1144-
LogPrint(BCLog::GOBJECT, "%s\n", ostr.str());
1145-
exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20);
1141+
std::string msg{strprintf("CGovernanceManager::%s -- Old invalid vote, MN outpoint = %s, governance object hash = %s",
1142+
__func__, vote.GetMasternodeOutpoint().ToStringShort(), nHashGovobj.ToString())};
1143+
LogPrint(BCLog::GOBJECT, "%s\n", msg);
1144+
exception = CGovernanceException(msg, GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20);
11461145
LEAVE_CRITICAL_SECTION(cs);
11471146
return false;
11481147
}
11491148

11501149
auto it = mapObjects.find(nHashGovobj);
11511150
if (it == mapObjects.end()) {
1152-
std::ostringstream ostr;
1153-
ostr << "CGovernanceManager::ProcessVote -- Unknown parent object " << nHashGovobj.ToString()
1154-
<< ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort();
1155-
exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING);
1151+
std::string msg{strprintf("CGovernanceManager::%s -- Unknown parent object %s, MN outpoint = %s", __func__,
1152+
nHashGovobj.ToString(), vote.GetMasternodeOutpoint().ToStringShort())};
1153+
exception = CGovernanceException(msg, GOVERNANCE_EXCEPTION_WARNING);
11561154
if (cmmapOrphanVotes.Insert(nHashGovobj, vote_time_pair_t(vote, GetTime<std::chrono::seconds>().count() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) {
11571155
LEAVE_CRITICAL_SECTION(cs);
11581156
RequestGovernanceObject(pfrom, nHashGovobj, connman);
1159-
LogPrint(BCLog::GOBJECT, "%s\n", ostr.str());
1157+
LogPrint(BCLog::GOBJECT, "%s\n", msg);
11601158
return false;
11611159
}
11621160

1163-
LogPrint(BCLog::GOBJECT, "%s\n", ostr.str());
1161+
LogPrint(BCLog::GOBJECT, "%s\n", msg);
11641162
LEAVE_CRITICAL_SECTION(cs);
11651163
return false;
11661164
}
11671165

11681166
CGovernanceObject& govobj = it->second;
11691167

11701168
if (govobj.IsSetCachedDelete() || govobj.IsSetExpired()) {
1171-
LogPrint(BCLog::GOBJECT, "CGovernanceObject::ProcessVote -- ignoring vote for expired or deleted object, hash = %s\n", nHashGovobj.ToString());
1169+
LogPrint(BCLog::GOBJECT, "CGovernanceObject::%s -- ignoring vote for expired or deleted object, hash = %s\n",
1170+
__func__, nHashGovobj.ToString());
11721171
LEAVE_CRITICAL_SECTION(cs);
11731172
return false;
11741173
}

0 commit comments

Comments
 (0)