From b15a971d6cfd811a5717ce4fb93d9fa23c28f3c3 Mon Sep 17 00:00:00 2001 From: Dmitry Petukhov Date: Tue, 30 Jul 2019 16:19:45 +0500 Subject: [PATCH] TxToUniv: check ptxoutwit->vchRangeproof.size() before secp256k1_rangeproof_info() Otherwise, ```e1-cli sendrawtransaction 02000000010161616161616161616161616161616161616161616161616161616161616161610000000000ffffffff0100000000000000000000010100000000 ``` results in ``` #0 0x00007ffff65686ab in raise () from /lib64/libc.so.6 #1 0x00007ffff6551539 in abort () from /lib64/libc.so.6 #2 0x0000555555e199bb in secp256k1_default_illegal_callback_fn (str=, data=) at src/secp256k1.c:52 #3 0x0000555555e2b8fc in secp256k1_callback_call (cb=, cb=, text=0x555555f35057 "proof != NULL") at src/util.h:24 #4 secp256k1_rangeproof_info (ctx=, exp=, mantissa=, min_value=, max_value=, proof=, plen=0) at src/modules/rangeproof/main_impl.h:230 #5 0x0000555555cb2768 in TxToUniv (tx=..., hashBlock=..., entry=..., include_hex=false, serialize_flags=0) at core_write.cpp:330 #6 0x00005555557c3f42 in decoderawtransaction (request=...) at rpc/rawtransaction.cpp:684 ``` This is because the transaction contains nValue in txout that have empty commitment. It is considered 'not explicit', but it is also not confidential. To me, it seems that empty nValue (empty commitment) is not valid at all, and probably this should have been caught in the transaction decoding code. --- src/core_write.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_write.cpp b/src/core_write.cpp index 8070e98db96..e479deedfe9 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -327,7 +327,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, uint64_t minv; uint64_t maxv; const CTxOutWitness* ptxoutwit = tx.witness.vtxoutwit.size() <= i? NULL: &tx.witness.vtxoutwit[i]; - if (ptxoutwit && secp256k1_rangeproof_info(secp256k1_blind_context, &exp, &mantissa, &minv, &maxv, &ptxoutwit->vchRangeproof[0], ptxoutwit->vchRangeproof.size())) { + if (ptxoutwit && ptxoutwit->vchRangeproof.size() && secp256k1_rangeproof_info(secp256k1_blind_context, &exp, &mantissa, &minv, &maxv, &ptxoutwit->vchRangeproof[0], ptxoutwit->vchRangeproof.size())) { if (exp == -1) { out.pushKV("value", ValueFromAmount((CAmount)minv)); } else {