Auto merge of #4304 - oxarbitrage:issue3893, r=str4d
Add status to transactions in RPC calls Closes https://github.com/zcash/zcash/issues/3893.
This commit is contained in:
commit
d0b533aacb
|
@ -86,6 +86,8 @@ void EnsureWalletIsUnlocked()
|
||||||
void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
|
void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
|
||||||
{
|
{
|
||||||
int confirms = wtx.GetDepthInMainChain();
|
int confirms = wtx.GetDepthInMainChain();
|
||||||
|
std::string status = "waiting";
|
||||||
|
|
||||||
entry.push_back(Pair("confirmations", confirms));
|
entry.push_back(Pair("confirmations", confirms));
|
||||||
if (wtx.IsCoinBase())
|
if (wtx.IsCoinBase())
|
||||||
entry.push_back(Pair("generated", true));
|
entry.push_back(Pair("generated", true));
|
||||||
|
@ -95,7 +97,18 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
|
||||||
entry.push_back(Pair("blockindex", wtx.nIndex));
|
entry.push_back(Pair("blockindex", wtx.nIndex));
|
||||||
entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
|
entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
|
||||||
entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight));
|
entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight));
|
||||||
|
status = "mined";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int height = chainActive.Height();
|
||||||
|
if (!IsExpiredTx(wtx, height) && IsExpiringSoonTx(wtx, height + 1))
|
||||||
|
status = "expiringsoon";
|
||||||
|
else if (IsExpiredTx(wtx, height))
|
||||||
|
status = "expired";
|
||||||
|
}
|
||||||
|
entry.push_back(Pair("status", status));
|
||||||
|
|
||||||
uint256 hash = wtx.GetHash();
|
uint256 hash = wtx.GetHash();
|
||||||
entry.push_back(Pair("txid", hash.GetHex()));
|
entry.push_back(Pair("txid", hash.GetHex()));
|
||||||
UniValue conflicts(UniValue::VARR);
|
UniValue conflicts(UniValue::VARR);
|
||||||
|
@ -1443,6 +1456,8 @@ UniValue listtransactions(const UniValue& params, bool fHelp)
|
||||||
" transaction between accounts, and not associated with an address,\n"
|
" transaction between accounts, and not associated with an address,\n"
|
||||||
" transaction id or block. 'send' and 'receive' transactions are \n"
|
" transaction id or block. 'send' and 'receive' transactions are \n"
|
||||||
" associated with an address, transaction id and block details\n"
|
" associated with an address, transaction id and block details\n"
|
||||||
|
" \"status\" : \"mined|waiting|expiringsoon|expired\", (string) The transaction status, can be 'mined', 'waiting', 'expiringsoon' \n"
|
||||||
|
" or 'expired'. Available for 'send' and 'receive' category of transactions.\n"
|
||||||
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
|
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
|
||||||
" 'move' category for moves outbound. It is positive for the 'receive' category,\n"
|
" 'move' category for moves outbound. It is positive for the 'receive' category,\n"
|
||||||
" and for the 'move' category for inbound funds.\n"
|
" and for the 'move' category for inbound funds.\n"
|
||||||
|
@ -1639,6 +1654,8 @@ UniValue listsinceblock(const UniValue& params, bool fHelp)
|
||||||
" \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
|
" \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
|
||||||
" \"address\":\"zcashaddress\", (string) The Zcash address of the transaction. Not present for move transactions (category = move).\n"
|
" \"address\":\"zcashaddress\", (string) The Zcash address of the transaction. Not present for move transactions (category = move).\n"
|
||||||
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
|
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
|
||||||
|
" \"status\" : \"mined|waiting|expiringsoon|expired\", (string) The transaction status, can be 'mined', 'waiting', 'expiringsoon' \n"
|
||||||
|
" or 'expired'. Available for 'send' and 'receive' category of transactions.\n"
|
||||||
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
|
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
|
||||||
" outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
|
" outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
|
||||||
" \"vout\" : n, (numeric) the vout value\n"
|
" \"vout\" : n, (numeric) the vout value\n"
|
||||||
|
@ -1725,6 +1742,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp)
|
||||||
"2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
|
"2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
|
||||||
"\nResult:\n"
|
"\nResult:\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
" \"status\" : \"mined|waiting|expiringsoon|expired\", (string) The transaction status, can be 'mined', 'waiting', 'expiringsoon' or 'expired'\n"
|
||||||
" \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
|
" \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
|
||||||
" \"confirmations\" : n, (numeric) The number of confirmations\n"
|
" \"confirmations\" : n, (numeric) The number of confirmations\n"
|
||||||
" \"blockhash\" : \"hash\", (string) The block hash\n"
|
" \"blockhash\" : \"hash\", (string) The block hash\n"
|
||||||
|
|
|
@ -2008,5 +2008,89 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestWTxStatus(const Consensus::Params consensusParams, const int delta) {
|
||||||
|
|
||||||
|
auto AddTrx = [&consensusParams]() {
|
||||||
|
auto taddr = pwalletMain->GenerateNewKey().GetID();
|
||||||
|
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(consensusParams, 1);
|
||||||
|
CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(taddr) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||||
|
mtx.vout.push_back(CTxOut(5 * COIN, scriptPubKey));
|
||||||
|
CWalletTx wtx(pwalletMain, mtx);
|
||||||
|
pwalletMain->AddToWallet(wtx, true, NULL);
|
||||||
|
return wtx;
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<uint256> hashes;
|
||||||
|
CWalletTx wtx;
|
||||||
|
auto FakeMine = [&](const int height, bool has_trx) {
|
||||||
|
BOOST_CHECK_EQUAL(height, chainActive.Height());
|
||||||
|
CBlock block;
|
||||||
|
if (has_trx) block.vtx.push_back(wtx);
|
||||||
|
block.hashMerkleRoot = block.BuildMerkleTree();
|
||||||
|
auto blockHash = block.GetHash();
|
||||||
|
CBlockIndex fakeIndex {block};
|
||||||
|
fakeIndex.nHeight = height+1;
|
||||||
|
mapBlockIndex.insert(std::make_pair(blockHash, &fakeIndex));
|
||||||
|
chainActive.SetTip(&fakeIndex);
|
||||||
|
BOOST_CHECK(chainActive.Contains(&fakeIndex));
|
||||||
|
BOOST_CHECK_EQUAL(height+1, chainActive.Height());
|
||||||
|
|
||||||
|
if (has_trx) {
|
||||||
|
wtx.SetMerkleBranch(block);
|
||||||
|
pwalletMain->AddToWallet(wtx, true, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashes.push_back(blockHash);
|
||||||
|
UniValue retValue = CallRPC("gettransaction " + wtx.GetHash().GetHex());
|
||||||
|
return retValue.get_obj();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add a transaction to the wallet
|
||||||
|
wtx = AddTrx();
|
||||||
|
|
||||||
|
// Mine blocks but never include the transaction, check status of wallet trx
|
||||||
|
for(int i=0; i<=delta + 1; i++) {
|
||||||
|
auto retObj = FakeMine(i, false);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(find_value(retObj, "confirmations").get_real(), -1);
|
||||||
|
auto status = find_value(retObj, "status").get_str();
|
||||||
|
if (i >= delta - TX_EXPIRING_SOON_THRESHOLD && i <= delta)
|
||||||
|
BOOST_CHECK_EQUAL(status, "expiringsoon");
|
||||||
|
else if (i >= delta - TX_EXPIRING_SOON_THRESHOLD)
|
||||||
|
BOOST_CHECK_EQUAL(status, "expired");
|
||||||
|
else
|
||||||
|
BOOST_CHECK_EQUAL(status, "waiting");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now mine including the transaction, check status
|
||||||
|
auto retObj = FakeMine(delta + 2, true);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(find_value(retObj, "confirmations").get_real(), 1);
|
||||||
|
BOOST_CHECK_EQUAL(find_value(retObj, "status").get_str(), "mined");
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
chainActive.SetTip(NULL);
|
||||||
|
for (auto hash : hashes)
|
||||||
|
mapBlockIndex.erase(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rpc_gettransaction_status_sapling)
|
||||||
|
{
|
||||||
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
|
||||||
|
TestWTxStatus(RegtestActivateSapling(), DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA);
|
||||||
|
|
||||||
|
RegtestDeactivateSapling();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rpc_gettransaction_status_blossom)
|
||||||
|
{
|
||||||
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
|
||||||
|
TestWTxStatus(RegtestActivateBlossom(true), DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA);
|
||||||
|
|
||||||
|
RegtestDeactivateBlossom();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in New Issue