@@ -131,7 +131,7 @@ static bool VerifyIssuanceAmount(secp256k1_pedersen_commitment& value_commit, se
131131 return true ;
132132}
133133
134- bool VerifyAmounts (const std::vector<CTxOut>& inputs, const CTransaction& tx, std::vector<CCheck*>* checks, const bool store_result) {
134+ const std::string& VerifyAmounts (const std::vector<CTxOut>& inputs, const CTransaction& tx, std::vector<CCheck*>* checks, const bool store_result) {
135135 assert (!tx.IsCoinBase ());
136136 assert (inputs.size () == tx.vin .size ());
137137
@@ -161,34 +161,34 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
161161 const CConfidentialAsset& asset = inputs[i].nAsset ;
162162
163163 if (val.IsNull () || asset.IsNull ())
164- return false ;
164+ return " input val.IsNull or asset.IsNull " ;
165165
166166 if (asset.IsExplicit ()) {
167167 ret = secp256k1_generator_generate (secp256k1_ctx_verify_amounts, &gen, asset.GetAsset ().begin ());
168168 assert (ret != 0 );
169169 }
170170 else if (asset.IsCommitment ()) {
171171 if (secp256k1_generator_parse (secp256k1_ctx_verify_amounts, &gen, &asset.vchCommitment [0 ]) != 1 )
172- return false ;
172+ return " input commitment parse failed " ;
173173 }
174174 else {
175- return false ;
175+ return " input asset not explicit not commitment " ;
176176 }
177177
178178 target_generators.push_back (gen);
179179
180180 if (val.IsExplicit ()) {
181181 if (!MoneyRange (val.GetAmount ()))
182- return false ;
182+ return " input value not in moneyrange " ;
183183
184184 // Fails if val.GetAmount() == 0
185185 if (secp256k1_pedersen_commit (secp256k1_ctx_verify_amounts, &commit, explicit_blinds, val.GetAmount (), &gen) != 1 )
186- return false ;
186+ return " input explicit value pedersen commit failed " ;
187187 } else if (val.IsCommitment ()) {
188188 if (secp256k1_pedersen_commitment_parse (secp256k1_ctx_verify_amounts, &commit, &val.vchCommitment [0 ]) != 1 )
189- return false ;
189+ return " input commitment pedersen commit failed " ;
190190 } else {
191- return false ;
191+ return " input value not explicit not commitment " ;
192192 }
193193
194194 vData.push_back (commit);
@@ -228,37 +228,38 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
228228 // Must check that prevout is the blinded issuance token
229229 // prevout's asset tag = assetTokenID + assetBlindingNonce
230230 if (secp256k1_generator_generate_blinded (secp256k1_ctx_verify_amounts, &gen, assetTokenID.begin (), issuance.assetBlindingNonce .begin ()) != 1 ) {
231- return false ;
231+ return " reissuance generate blinded generator failed " ;
232232 }
233233 // Serialize the generator for direct comparison
234234 unsigned char derived_generator[33 ];
235235 secp256k1_generator_serialize (secp256k1_ctx_verify_amounts, derived_generator, &gen);
236236
237237 // Belt-and-suspenders: Check that asset commitment from issuance input is correct size
238238 if (asset.vchCommitment .size () != sizeof (derived_generator)) {
239- return false ;
239+ return " reissuance asset commitment size is not derived generator size " ;
240240 }
241241
242- // We have already checked the outputs' generator commitment for general validity, so directly compare serialized bytes
242+ // We have already checked the outputs' generator commitment for general validity,
243+ // so directly compare serialized bytes
243244 if (memcmp (asset.vchCommitment .data (), derived_generator, sizeof (derived_generator))) {
244- return false ;
245+ return " reissuance asset commitment not equal to derived generator " ;
245246 }
246247 }
247248
248249 // Process issuance of asset
249250
250251 if (!issuance.nAmount .IsValid ()) {
251- return false ;
252+ return " issuance amount not valid " ;
252253 }
253254 if (!issuance.nAmount .IsNull ()) {
254255 // Note: This check disallows issuances in transactions with *no* witness data.
255256 // This can be relaxed in a future update as a HF by passing in an empty rangeproof
256257 // to `VerifyIssuanceAmount` instead.
257258 if (i >= tx.witness .vtxinwit .size ()) {
258- return false ;
259+ return " no witness for issuance input " ;
259260 }
260261 if (!VerifyIssuanceAmount (commit, gen, assetID, issuance.nAmount , tx.witness .vtxinwit [i].vchIssuanceAmountRangeproof , checks, store_result)) {
261- return false ;
262+ return " VerifyIssuanceAmount failed " ;
262263 }
263264 target_generators.push_back (gen);
264265 vData.push_back (commit);
@@ -269,22 +270,22 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
269270 // Process issuance of reissuance tokens
270271
271272 if (!issuance.nInflationKeys .IsValid ()) {
272- return false ;
273+ return " issuance of reissuance tokens: inflatioinskeys invalid " ;
273274 }
274275 if (!issuance.nInflationKeys .IsNull ()) {
275276 // Only initial issuance can have reissuance tokens
276277 if (!issuance.assetBlindingNonce .IsNull ()) {
277- return false ;
278+ return " only initial issuance can have reissuance tokens " ;
278279 }
279280
280281 // Note: This check disallows issuances in transactions with *no* witness data.
281282 // This can be relaxed in a future update as a HF by passing in an empty rangeproof
282283 // to `VerifyIssuanceAmount` instead.
283284 if (i >= tx.witness .vtxinwit .size ()) {
284- return false ;
285+ return " no witness for reissuance input " ;
285286 }
286287 if (!VerifyIssuanceAmount (commit, gen, assetTokenID, issuance.nInflationKeys , tx.witness .vtxinwit [i].vchInflationKeysRangeproof , checks, store_result)) {
287- return false ;
288+ return " reissuance VerifyIssuanceAmount failed " ;
288289 }
289290 target_generators.push_back (gen);
290291 vData.push_back (commit);
@@ -298,35 +299,35 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
298299 const CConfidentialValue& val = tx.vout [i].nValue ;
299300 const CConfidentialAsset& asset = tx.vout [i].nAsset ;
300301 if (!asset.IsValid ())
301- return false ;
302+ return " output asset invalid " ;
302303 if (!val.IsValid ())
303- return false ;
304+ return " output value invalid " ;
304305 if (!tx.vout [i].nNonce .IsValid ())
305- return false ;
306+ return " output nonce invalid " ;
306307
307308 if (asset.IsExplicit ()) {
308309 ret = secp256k1_generator_generate (secp256k1_ctx_verify_amounts, &gen, asset.GetAsset ().begin ());
309310 assert (ret != 0 );
310311 }
311312 else if (asset.IsCommitment ()) {
312313 if (secp256k1_generator_parse (secp256k1_ctx_verify_amounts, &gen, &asset.vchCommitment [0 ]) != 1 )
313- return false ;
314+ return " output asset commitment parse failed " ;
314315 }
315316 else {
316- return false ;
317+ return " output asset is not explicit not commitment " ;
317318 }
318319
319320 if (val.IsExplicit ()) {
320321 if (!MoneyRange (val.GetAmount ()))
321- return false ;
322+ return " output value out of money range " ;
322323
323324 if (val.GetAmount () == 0 ) {
324325 if (tx.vout [i].scriptPubKey .IsUnspendable ()) {
325326 continue ;
326327 } else {
327328 // No spendable 0-value outputs
328329 // Reason: A spendable output of 0 reissuance tokens would allow reissuance without reissuance tokens.
329- return false ;
330+ return " attempted spendable 0-value output " ;
330331 }
331332 }
332333
@@ -336,9 +337,9 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
336337 }
337338 else if (val.IsCommitment ()) {
338339 if (secp256k1_pedersen_commitment_parse (secp256k1_ctx_verify_amounts, &commit, &val.vchCommitment [0 ]) != 1 )
339- return false ;
340+ return " output value pedersen commit parse failed " ;
340341 } else {
341- return false ;
342+ return " output value is not explicit not commitment " ;
342343 }
343344
344345 vData.push_back (commit);
@@ -348,7 +349,7 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
348349
349350 // Check balance
350351 if (QueueCheck (checks, new CBalanceCheck (vData, vpCommitsIn, vpCommitsOut)) != SCRIPT_ERR_OK) {
351- return false ;
352+ return " CBalanceCheck failed " ;
352353 }
353354
354355 // Range proofs
@@ -360,7 +361,7 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
360361 if (val.IsExplicit ())
361362 {
362363 if (ptxoutwit && !ptxoutwit->vchRangeproof .empty ())
363- return false ;
364+ return " explicit output value non-empty range proof " ;
364365 continue ;
365366 }
366367 if (asset.IsExplicit ()) {
@@ -369,10 +370,10 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
369370 secp256k1_generator_serialize (secp256k1_ctx_verify_amounts, &vchAssetCommitment[0 ], &gen);
370371 }
371372 if (!ptxoutwit) {
372- return false ;
373+ return " blinded output value without output witness " ;
373374 }
374375 if (QueueCheck (checks, new CRangeCheck (&val, ptxoutwit->vchRangeproof , vchAssetCommitment, tx.vout [i].scriptPubKey , store_result)) != SCRIPT_ERR_OK) {
375- return false ;
376+ return " CRangeCheck failed " ;
376377 }
377378 }
378379
@@ -384,25 +385,25 @@ bool VerifyAmounts(const std::vector<CTxOut>& inputs, const CTransaction& tx, st
384385 // No need for surjection proof
385386 if (asset.IsExplicit ()) {
386387 if (ptxoutwit && !ptxoutwit->vchSurjectionproof .empty ()) {
387- return false ;
388+ return " explicit output asset non-empty surjection proof " ;
388389 }
389390 continue ;
390391 }
391392 if (!ptxoutwit)
392- return false ;
393+ return " blinded output value without output witness " ;
393394 if (secp256k1_generator_parse (secp256k1_ctx_verify_amounts, &gen, &asset.vchCommitment [0 ]) != 1 )
394- return false ;
395+ return " output asset generator parse failed " ;
395396
396397 secp256k1_surjectionproof proof;
397398 if (secp256k1_surjectionproof_parse (secp256k1_ctx_verify_amounts, &proof, &ptxoutwit->vchSurjectionproof [0 ], ptxoutwit->vchSurjectionproof .size ()) != 1 )
398- return false ;
399+ return " output asset surjection proof failed " ;
399400
400401 if (QueueCheck (checks, new CSurjectionCheck (proof, target_generators, gen, wtxid, store_result)) != SCRIPT_ERR_OK) {
401- return false ;
402+ return " CSurjectionCheck failed " ;
402403 }
403404 }
404405
405- return true ;
406+ return " " ;
406407}
407408
408409bool VerifyCoinbaseAmount (const CTransaction& tx, const CAmountMap& mapFees) {
0 commit comments