Merge pull request #374 from UdjinM6/v0.12.0.x_ds_reservekeys

V0.12.0.x deal with reservekeys in CreateDenominated and MakeCollaterals more accurate (+todo)
This commit is contained in:
evan82 2015-06-22 12:25:27 -07:00
commit 511b11aa53

View File

@ -1720,38 +1720,43 @@ bool CDarksendPool::SendRandomPaymentToSelf()
// Split up large inputs or create fee sized inputs // Split up large inputs or create fee sized inputs
bool CDarksendPool::MakeCollateralAmounts() bool CDarksendPool::MakeCollateralAmounts()
{ {
// make our change address
CReserveKey reservekey(pwalletMain);
CScript scriptChange;
CPubKey vchPubKey;
assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
scriptChange = GetScriptForDestination(vchPubKey.GetID());
CWalletTx wtx; CWalletTx wtx;
int64_t nFeeRet = 0; int64_t nFeeRet = 0;
std::string strFail = ""; std::string strFail = "";
vector< pair<CScript, int64_t> > vecSend; vector< pair<CScript, int64_t> > vecSend;
CCoinControl *coinControl = NULL;
vecSend.push_back(make_pair(scriptChange, DARKSEND_COLLATERAL*4)); // make our collateral address
CReserveKey reservekeyCollateral(pwalletMain);
// make our change address
CReserveKey reservekeyChange(pwalletMain);
CScript scriptCollateral;
CPubKey vchPubKey;
assert(reservekeyCollateral.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
scriptCollateral = GetScriptForDestination(vchPubKey.GetID());
vecSend.push_back(make_pair(scriptCollateral, DARKSEND_COLLATERAL*4));
CCoinControl *coinControl=NULL;
// try to use non-denominated and not mn-like funds // try to use non-denominated and not mn-like funds
bool success = pwalletMain->CreateTransaction(vecSend, wtx, reservekey, bool success = pwalletMain->CreateTransaction(vecSend, wtx, reservekeyChange,
nFeeRet, strFail, coinControl, ONLY_NONDENOMINATED_NOTMN); nFeeRet, strFail, coinControl, ONLY_NONDENOMINATED_NOTMN);
if(!success){ if(!success){
// if we failed (most likeky not enough funds), try to use denominated instead - // if we failed (most likeky not enough funds), try to use denominated instead -
// MN-like funds should not be touched in any case and we can't mix denominated without collaterals anyway // MN-like funds should not be touched in any case and we can't mix denominated without collaterals anyway
success = pwalletMain->CreateTransaction(vecSend, wtx, reservekey, success = pwalletMain->CreateTransaction(vecSend, wtx, reservekeyChange,
nFeeRet, strFail, coinControl, ONLY_DENOMINATED); nFeeRet, strFail, coinControl, ONLY_DENOMINATED);
if(!success){ if(!success){
LogPrintf("MakeCollateralAmounts: Error - %s\n", strFail.c_str()); LogPrintf("MakeCollateralAmounts: ONLY_DENOMINATED Error - %s\n", strFail);
reservekeyCollateral.ReturnKey();
return false; return false;
} }
} }
reservekeyCollateral.KeepKey();
// use the same cachedLastSuccess as for DS mixinx to prevent race // use the same cachedLastSuccess as for DS mixinx to prevent race
if(pwalletMain->CommitTransaction(wtx, reservekey)) if(pwalletMain->CommitTransaction(wtx, reservekeyChange))
cachedLastSuccess = chainActive.Tip()->nHeight; cachedLastSuccess = chainActive.Tip()->nHeight;
LogPrintf("MakeCollateralAmounts Success: tx %s\n", wtx.GetHash().GetHex().c_str()); LogPrintf("MakeCollateralAmounts Success: tx %s\n", wtx.GetHash().GetHex().c_str());
@ -1762,23 +1767,27 @@ bool CDarksendPool::MakeCollateralAmounts()
// Create denominations // Create denominations
bool CDarksendPool::CreateDenominated(int64_t nTotalValue) bool CDarksendPool::CreateDenominated(int64_t nTotalValue)
{ {
// make our change address
CReserveKey reservekey(pwalletMain);
CScript scriptChange;
CPubKey vchPubKey;
assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
scriptChange = GetScriptForDestination(vchPubKey.GetID());
CWalletTx wtx; CWalletTx wtx;
int64_t nFeeRet = 0; int64_t nFeeRet = 0;
std::string strFail = ""; std::string strFail = "";
vector< pair<CScript, int64_t> > vecSend; vector< pair<CScript, int64_t> > vecSend;
int64_t nValueLeft = nTotalValue; int64_t nValueLeft = nTotalValue;
// make our collateral address
CReserveKey reservekeyCollateral(pwalletMain);
// make our change address
CReserveKey reservekeyChange(pwalletMain);
// make our denom addresses
CReserveKey reservekeyDenom(pwalletMain);
CScript scriptCollateral;
CPubKey vchPubKey;
assert(reservekeyCollateral.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
scriptCollateral = GetScriptForDestination(vchPubKey.GetID());
// ****** Add collateral outputs ************ / // ****** Add collateral outputs ************ /
if(!pwalletMain->HasCollateralInputs()) { if(!pwalletMain->HasCollateralInputs()) {
vecSend.push_back(make_pair(scriptChange, DARKSEND_COLLATERAL*4)); vecSend.push_back(make_pair(scriptCollateral, DARKSEND_COLLATERAL*4));
nValueLeft -= DARKSEND_COLLATERAL*4; nValueLeft -= DARKSEND_COLLATERAL*4;
} }
@ -1788,14 +1797,15 @@ bool CDarksendPool::CreateDenominated(int64_t nTotalValue)
// add each output up to 10 times until it can't be added again // add each output up to 10 times until it can't be added again
while(nValueLeft - v >= DARKSEND_COLLATERAL && nOutputs <= 10) { while(nValueLeft - v >= DARKSEND_COLLATERAL && nOutputs <= 10) {
CScript scriptChange; CScript scriptDenom;
CPubKey vchPubKey; CPubKey vchPubKey;
//use a unique change address //use a unique change address
assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked assert(reservekeyDenom.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
scriptChange = GetScriptForDestination(vchPubKey.GetID()); scriptDenom = GetScriptForDestination(vchPubKey.GetID());
reservekey.KeepKey(); // TODO: do not keep reservekeyDenom here
reservekeyDenom.KeepKey();
vecSend.push_back(make_pair(scriptChange, v)); vecSend.push_back(make_pair(scriptDenom, v));
//increment outputs and subtract denomination amount //increment outputs and subtract denomination amount
nOutputs++; nOutputs++;
@ -1810,18 +1820,25 @@ bool CDarksendPool::CreateDenominated(int64_t nTotalValue)
// if we have anything left over, it will be automatically send back as change - there is no need to send it manually // if we have anything left over, it will be automatically send back as change - there is no need to send it manually
CCoinControl *coinControl=NULL; CCoinControl *coinControl=NULL;
bool success = pwalletMain->CreateTransaction(vecSend, wtx, reservekey, bool success = pwalletMain->CreateTransaction(vecSend, wtx, reservekeyChange,
nFeeRet, strFail, coinControl, ONLY_NONDENOMINATED_NOTMN); nFeeRet, strFail, coinControl, ONLY_NONDENOMINATED_NOTMN);
if(!success){ if(!success){
LogPrintf("CreateDenominated: Error - %s\n", strFail.c_str()); LogPrintf("CreateDenominated: Error - %s\n", strFail.c_str());
// TODO: return reservekeyDenom here
reservekeyCollateral.ReturnKey();
return false; return false;
} }
// use the same cachedLastSuccess as for DS mixinx to prevent race // TODO: keep reservekeyDenom here
if(pwalletMain->CommitTransaction(wtx, reservekey)) reservekeyCollateral.KeepKey();
cachedLastSuccess = chainActive.Tip()->nHeight;
LogPrintf("CreateDenominated Success: tx %s\n", wtx.GetHash().GetHex().c_str()); // use the same cachedLastSuccess as for DS mixinx to prevent race
if(pwalletMain->CommitTransaction(wtx, reservekeyChange))
cachedLastSuccess = chainActive.Tip()->nHeight;
else
LogPrintf("CreateDenominated: CommitTransaction failed!\n");
LogPrintf("CreateDenominated: tx %s\n", wtx.GetHash().GetHex().c_str());
return true; return true;
} }