Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add -staketo flag #204

Merged
merged 2 commits into from
Jul 19, 2015
Merged
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
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