Skip to content

Commit

Permalink
Merge pull request #204 from dooglus/stake-to-address
Browse files Browse the repository at this point in the history
Add -staketo flag
  • Loading branch information
dooglus committed Jul 19, 2015
2 parents 89755e0 + 0721c5e commit b1f23e7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 9 deletions.
9 changes: 9 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ bool fCombineAny;
bool fUseFastIndex;
bool fCreditStakesToAccounts;
enum Checkpoints::CPMode CheckpointsMode;
CKeyID staketokeyID;
bool fStakeTo = false;
vector<CKeyID> vChangeAddresses;
set<CBitcoinAddress> setSpendLastAddresses;
set<CBitcoinAddress> setStakeAddresses;
Expand Down Expand Up @@ -260,6 +262,7 @@ std::string HelpMessage()
strUsage += " " + _(" %a in cmd is replaced by the address which staked,") + "\n";
strUsage += " " + _(" %t in cmd is replaced by the total amount staked by this wallet, and") + "\n";
strUsage += " " + _(" %s in cmd is replaced by the total amount staked by the address which just staked)") + "\n";
strUsage += " -staketo=<addr> " + _("Address to move coins to as they stake") + "\n";
strUsage += " -change=<addr> " + _("Address to send change to") + "\n";
strUsage += " -spendlast=<addr> " + _("Avoid spending outputs from given address(es) if possible") + "\n";
strUsage += " -stake=<addr> " + _("Stake only outputs at the specified address(es)") + "\n";
Expand Down Expand Up @@ -474,6 +477,12 @@ bool AppInit2(boost::thread_group& threadGroup)
}
#endif

if (mapArgs.count("-staketo")) {
if (!CBitcoinAddress(GetArg("-staketo", "")).GetKeyID(staketokeyID))
return InitError(strprintf(_("Bad -staketo address: '%s'"), GetArg("-staketo", "")));
fStakeTo = true;
}

if (mapArgs.count("-change"))
{
BOOST_FOREACH(std::string strChange, mapMultiArgs["-change"]) {
Expand Down
35 changes: 26 additions & 9 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ extern bool fCombineAny;
static unsigned int GetStakeSplitAge() { return 1 * 24 * 60 * 60; }

extern vector<CKeyID> vChangeAddresses;
extern CKeyID staketokeyID;
extern bool fStakeTo;
extern set<CBitcoinAddress> setSpendLastAddresses;
extern set<CBitcoinAddress> setStakeAddresses;

Expand Down Expand Up @@ -2069,6 +2071,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
CScript scriptPubKeyKernel;
int64_t nBlockTime;
CTxDB txdb("r");
CKeyID stakingkeyID;
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
{
if (!pcoin.first->hash)
Expand Down Expand Up @@ -2138,7 +2141,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
if (whichType == TX_PUBKEYHASH) // pay to address type
{
// convert to pay to public key type
if (!keystore.GetKey(uint160(vSolutions[0]), key))
stakingkeyID = uint160(vSolutions[0]);
if (!keystore.GetKey(stakingkeyID, key))
{
LogPrint("stake", "[STAKE] fail %s:%-3d (%s CLAM) - can't get public key (a)\n",
pcoin.first->hash.ToString(), pcoin.second, FormatMoney(pcoin.first->vout[pcoin.second].nValue));
Expand All @@ -2149,7 +2153,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
if (whichType == TX_PUBKEY)
{
valtype& vchPubKey = vSolutions[0];
if (!keystore.GetKey(Hash160(vchPubKey), key))
stakingkeyID = Hash160(vchPubKey);
if (!keystore.GetKey(stakingkeyID, key))
{
LogPrint("stake", "[STAKE] fail %s:%-3d (%s CLAM) - can't get public key, type %d\n",
pcoin.first->hash.ToString(), pcoin.second, FormatMoney(pcoin.first->vout[pcoin.second].nValue),
Expand Down Expand Up @@ -2209,17 +2214,29 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
txNew.strCLAMSpeech.resize(MAX_TX_COMMENT_LEN);
}

CScript scriptStakeTo;
int nFirstRealOutput;
// if we are staking to a specific address, and it's different than the address that is staking, make a new output for it
if (fStakeTo && stakingkeyID != staketokeyID) {
nFirstRealOutput = 2;
scriptStakeTo.SetDestination(staketokeyID);
txNew.vout.push_back(CTxOut(0, scriptStakeTo));
} else {
nFirstRealOutput = 1;
scriptStakeTo = txNew.vout[1].scriptPubKey;
}

// if we're splitting on size, only split if the new size will make it at least double the split size
// and if we're not, split on age
if (( nSplitSize && nCredit >= nSplitSize * 2) ||
(!nSplitSize && GetWeight(nBlockTime, (int64_t)txNew.nTime) < GetStakeSplitAge()))
{
if (nSplitSize) {
int n = 1;
int n = nFirstRealOutput;

while (true) {
if (n > 1)
txNew.vout.push_back(CTxOut(0, txNew.vout[1].scriptPubKey));
if (n > nFirstRealOutput)
txNew.vout.push_back(CTxOut(0, scriptStakeTo));

if (nCredit < nSplitSize * 2) {
txNew.vout[n].nValue = nCredit;
Expand All @@ -2232,9 +2249,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
n++;
}
} else {
txNew.vout.push_back(CTxOut(0, txNew.vout[1].scriptPubKey)); //split stake
txNew.vout[1].nValue = (nCredit / 2 / CENT) * CENT;
txNew.vout[2].nValue = nCredit - txNew.vout[1].nValue;
txNew.vout.push_back(CTxOut(0, scriptStakeTo)); //split stake
txNew.vout[nFirstRealOutput].nValue = (nCredit / 2 / CENT) * CENT;
txNew.vout[nFirstRealOutput+1].nValue = nCredit - txNew.vout[1].nValue;
}
} else {
// we're not splitting the output, so attempt to add more inputs
Expand Down Expand Up @@ -2264,7 +2281,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
}

// we're not splitting, so put all the value in the first and only real output
txNew.vout[1].nValue = nCredit;
txNew.vout[nFirstRealOutput].nValue = nCredit;
}

// Sign
Expand Down

0 comments on commit b1f23e7

Please sign in to comment.