Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions src/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2663,11 +2663,12 @@ Value sendanontosdc(const Array& params, bool fHelp)

Value estimateanonfee(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 2 || params.size() > 3)
if (fHelp || params.size() < 2 || params.size() > 4)
throw std::runtime_error(
"estimateanonfee <amount> <ring_size> [narration]\n"
"estimateanonfee <amount> <ring_size> [included] [narration]\n"
"<amount>is a real number and is rounded to the nearest 0.000001\n"
"<ring_size> is a number of outputs of the same amount to include in the signature");
"<ring_size> is a number of outputs of the same amount to include in the signature\n"
"[included] if set to 1 then <amount> also includes the fee");

int64_t nAmount = AmountFromValue(params[0]);

Expand All @@ -2677,32 +2678,56 @@ Value estimateanonfee(const Array& params, bool fHelp)
if (nRingSize < MIN_RING_SIZE || nRingSize > MAX_RING_SIZE)
ssThrow << "Ring size must be >= " << MIN_RING_SIZE << " and <= " << MAX_RING_SIZE << ".", throw std::runtime_error(ssThrow.str());


LogPrintf("EstimateAnonFee before narration\n");
std::string sNarr;
if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
sNarr = params[2].get_str();
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
sNarr = params[3].get_str();

LogPrintf("EstimateAnonFee after narration\n");

if (sNarr.length() > 24)
throw std::runtime_error("Narration must be 24 characters or less.");

bool included = false;

if(params.size() > 2){
std::string value = params[2].get_str();
if (IsStringBoolPositive(value)){
included = true;
}
}

Object result;
CWalletTx wtx;
int64_t nFee = 0;
std::string sError;
if (!pwalletMain->EstimateAnonFee(nAmount, nRingSize, sNarr, wtx, nFee, sError))
int64_t nMaxAmount = pwalletMain->GetShadowBalance();

if(included){
uint64_t nFeeRequired = pwalletMain->EstimateAnonFeeIncluded(nAmount, nRingSize, sNarr, wtx, sError);
result.push_back(Pair("Amount", ValueFromAmount(nAmount - nFeeRequired)));
result.push_back(Pair("Estimated fee", ValueFromAmount(nFeeRequired)));
if(nFeeRequired == 0){
LogPrintf("EstimateAnonFeeIncluded failed %s\n", sError.c_str());
throw JSONRPCError(RPC_WALLET_ERROR, sError);
}
}
else if(!pwalletMain->EstimateAnonFee(nAmount, nMaxAmount, nRingSize, sNarr, wtx, nFee, sError))
{
LogPrintf("EstimateAnonFee failed %s\n", sError.c_str());
throw JSONRPCError(RPC_WALLET_ERROR, sError);
};

uint32_t nBytes = ::GetSerializeSize(*(CTransaction*)&wtx, SER_NETWORK, PROTOCOL_VERSION);

Object result;


result.push_back(Pair("Estimated bytes", (int)nBytes));
result.push_back(Pair("Estimated inputs", (int)wtx.vin.size()));
result.push_back(Pair("Estimated outputs", (int)wtx.vout.size()));
result.push_back(Pair("Estimated fee", ValueFromAmount(nFee)));

if(!included)
result.push_back(Pair("Estimated fee", ValueFromAmount(nFee)));

return result;
}
Expand Down
74 changes: 72 additions & 2 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3799,6 +3799,7 @@ bool CWallet::CreateAnonOutputs(CStealthAddress* sxAddress, int64_t nValue, std:
scriptSendTo << cpkTo;
scriptSendTo << pkEphem;

//segmentation fault occurs here when calling estimateanonfee
if (i == 0 && sNarr.length() > 0)
{
std::vector<unsigned char> vchNarr;
Expand Down Expand Up @@ -5148,7 +5149,7 @@ bool CWallet::ProcessLockedAnonOutputs()
return true;
};

bool CWallet::EstimateAnonFee(int64_t nValue, int nRingSize, std::string& sNarr, CWalletTx& wtxNew, int64_t& nFeeRet, std::string& sError)
bool CWallet::EstimateAnonFee(int64_t nValue, int64_t nMaxAmount, int nRingSize, std::string& sNarr, CWalletTx& wtxNew, int64_t& nFeeRet, std::string& sError)
{
if (fDebugRingSig)
LogPrintf("EstimateAnonFee()\n");
Expand All @@ -5168,7 +5169,13 @@ bool CWallet::EstimateAnonFee(int64_t nValue, int nRingSize, std::string& sNarr,
return false;
};

if (nValue + nTransactionFee > GetShadowBalance())
if (nMaxAmount <= 0)
{
sError = "Invalid max amount";
return false;
};

if (nValue + nTransactionFee > nMaxAmount)
{
sError = "Insufficient shadow funds";
return false;
Expand Down Expand Up @@ -5197,6 +5204,69 @@ bool CWallet::EstimateAnonFee(int64_t nValue, int nRingSize, std::string& sNarr,
return true;
};

int64_t CWallet::EstimateAnonFeeIncluded(int64_t nMaxAmount, int nRingSize, std::string& sNarr, CWalletTx& wtx, std::string& sError)
{

if (fDebugRingSig)
LogPrintf("EstimateAnonFeeIncluded()\n");

if (nNodeMode != NT_FULL)
{
sError = _("Error: Must be in full mode.");

if(fDebugRingSig)
LogPrintf("EstimateAnonFeeIncluded: must be full node");

return 0;
};

if (nMaxAmount <= 0)
{
sError = "Invalid amount";

if(fDebugRingSig)
LogPrintf("EstimateAnonFeeIncluded: Invalid amount");

return 0;
};

if (nMaxAmount > GetShadowBalance())
{
sError = "Insufficient funds";

if(fDebugRingSig)
LogPrintf("EstimateAnonFeeIncluded: Insufficient balance");

return 0;
};


int64_t nFeeRet = 0;
int64_t nValue = nMaxAmount - nTransactionFee;
int nFailSafe = 5000;

while(!EstimateAnonFee(nValue, nMaxAmount, nRingSize, sNarr, wtx, nFeeRet, sError) && nFailSafe > 0){
nValue = nValue - (MIN_TX_FEE_ANON);
nFailSafe--;

}

//at least 50 SDT as fee, something obviously went wrong
if(nFailSafe == 0){
LogPrintf("EstimateAnonFeeIncluded: nFaileSafe = 0");
return 0;
}

if (fDebugRingSig){
LogPrintf("EstimateAnonFeeIncluded: Found value = %d\n", nValue);
LogPrintf("EstimateAnonFeeIncluded: Fee = %d\n", nFeeRet);
LogPrintf("EstimateAnonFeeIncluded: Dust = %d\n", (GetShadowBalance() - nValue - nFeeRet));
}


return nFeeRet;
};

int CWallet::ListUnspentAnonOutputs(std::list<COwnedAnonOutput>& lUAnonOutputs, bool fMatureOnly)
{
CWalletDB walletdb(strWalletFile, "r");
Expand Down
3 changes: 2 additions & 1 deletion src/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ class CWallet : public CCryptoKeyStore
bool ExpandLockedAnonOutput(CWalletDB *pdb, CKeyID &ckeyId, CLockedAnonOutput &lao, std::set<uint256> &setUpdated);
bool ProcessLockedAnonOutputs();

bool EstimateAnonFee(int64_t nValue, int nRingSize, std::string& sNarr, CWalletTx& wtxNew, int64_t& nFeeRet, std::string& sError);
bool EstimateAnonFee(int64_t nValue, int64_t nMaxAmount, int nRingSize, std::string& sNarr, CWalletTx& wtxNew, int64_t& nFeeRet, std::string& sError);
int64_t EstimateAnonFeeIncluded(int64_t nMaxAmount, int nRingSize, std::string& sNarr, CWalletTx& wtx, std::string& sError);

int ListUnspentAnonOutputs(std::list<COwnedAnonOutput>& lUAnonOutputs, bool fMatureOnly);
int CountAnonOutputs(std::map<int64_t, int>& mOutputCounts, bool fMatureOnly);
Expand Down