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

[Refactor] Create coinstake outputs moved from stakeInput to the wallet class. #2750

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
40 changes: 1 addition & 39 deletions src/stakeinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "chain.h"
#include "txdb.h"
#include "wallet/wallet.h"
#include "validation.h"

static bool HasStakeMinAgeOrDepth(int nHeight, uint32_t nTime, const CBlockIndex* pindex)
{
Expand Down Expand Up @@ -79,44 +79,6 @@ CAmount CPivStake::GetValue() const
return outputFrom.nValue;
}

bool CPivStake::CreateTxOuts(const CWallet* pwallet, std::vector<CTxOut>& vout, CAmount nTotal) const
{
std::vector<valtype> vSolutions;
txnouttype whichType;
CScript scriptPubKeyKernel = outputFrom.scriptPubKey;
if (!Solver(scriptPubKeyKernel, whichType, vSolutions))
return error("%s: failed to parse kernel", __func__);

if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH && whichType != TX_COLDSTAKE)
return error("%s: type=%d (%s) not supported for scriptPubKeyKernel", __func__, whichType, GetTxnOutputType(whichType));

CKey key;
if (whichType == TX_PUBKEYHASH || whichType == TX_COLDSTAKE) {
// if P2PKH or P2CS check that we have the input private key
if (!pwallet->GetKey(CKeyID(uint160(vSolutions[0])), key))
return error("%s: Unable to get staking private key", __func__);
}

vout.emplace_back(0, scriptPubKeyKernel);

// Calculate if we need to split the output
if (pwallet->nStakeSplitThreshold > 0) {
int nSplit = static_cast<int>(nTotal / pwallet->nStakeSplitThreshold);
if (nSplit > 1) {
// if nTotal is twice or more of the threshold; create more outputs
int txSizeMax = MAX_STANDARD_TX_SIZE >> 11; // limit splits to <10% of the max TX size (/2048)
if (nSplit > txSizeMax)
nSplit = txSizeMax;
for (int i = nSplit; i > 1; i--) {
LogPrintf("%s: StakeSplit: nTotal = %d; adding output %d of %d\n", __func__, nTotal, (nSplit-i)+2, nSplit);
vout.emplace_back(0, scriptPubKeyKernel);
}
}
}

return true;
}

CDataStream CPivStake::GetUniqueness() const
{
//The unique identifier for a PIV stake is the outpoint
Expand Down
1 change: 0 additions & 1 deletion src/stakeinput.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class CPivStake : public CStakeInput
CAmount GetValue() const override;
CDataStream GetUniqueness() const override;
CTxIn GetTxIn() const;
bool CreateTxOuts(const CWallet* pwallet, std::vector<CTxOut>& vout, CAmount nTotal) const;
bool IsZPIV() const override { return false; }
};

Expand Down
46 changes: 44 additions & 2 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
LOCK(cs_wallet);
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
if (it == mapWallet.end())
return NULL;
return nullptr;
return &(it->second);
}

Expand Down Expand Up @@ -3266,6 +3266,48 @@ int CWallet::GetLastBlockHeightLockWallet() const
return WITH_LOCK(cs_wallet, return m_last_block_processed_height;);
}

bool CWallet::CreateCoinstakeOuts(const CPivStake& stakeInput, std::vector<CTxOut>& vout, CAmount nTotal) const
{
std::vector<valtype> vSolutions;
txnouttype whichType;
CTxOut stakePrevout;
if (!stakeInput.GetTxOutFrom(stakePrevout)) {
return error("%s: failed to get stake input", __func__);
}
CScript scriptPubKeyKernel = stakePrevout.scriptPubKey;
if (!Solver(scriptPubKeyKernel, whichType, vSolutions))
return error("%s: failed to parse kernel", __func__);

if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH && whichType != TX_COLDSTAKE)
return error("%s: type=%d (%s) not supported for scriptPubKeyKernel", __func__, whichType, GetTxnOutputType(whichType));

CKey key;
if (whichType == TX_PUBKEYHASH || whichType == TX_COLDSTAKE) {
// if P2PKH or P2CS check that we have the input private key
if (!GetKey(CKeyID(uint160(vSolutions[0])), key))
return error("%s: Unable to get staking private key", __func__);
}

vout.emplace_back(0, scriptPubKeyKernel);

// Calculate if we need to split the output
if (nStakeSplitThreshold > 0) {
int nSplit = static_cast<int>(nTotal / nStakeSplitThreshold);
if (nSplit > 1) {
// if nTotal is twice or more of the threshold; create more outputs
int txSizeMax = MAX_STANDARD_TX_SIZE >> 11; // limit splits to <10% of the max TX size (/2048)
if (nSplit > txSizeMax)
nSplit = txSizeMax;
for (int i = nSplit; i > 1; i--) {
LogPrintf("%s: StakeSplit: nTotal = %d; adding output %d of %d\n", __func__, nTotal, (nSplit-i)+2, nSplit);
vout.emplace_back(0, scriptPubKeyKernel);
}
}
}

return true;
}

bool CWallet::CreateCoinStake(
const CBlockIndex* pindexPrev,
unsigned int nBits,
Expand Down Expand Up @@ -3335,7 +3377,7 @@ bool CWallet::CreateCoinStake(

// Create the output transaction(s)
std::vector<CTxOut> vout;
if (!stakeInput.CreateTxOuts(this, vout, nCredit)) {
if (!CreateCoinstakeOuts(stakeInput, vout, nCredit)) {
LogPrintf("%s : failed to create output\n", __func__);
it++;
continue;
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
};
CWallet::CommitResult CommitTransaction(CTransactionRef tx, CReserveKey& opReservekey, CConnman* connman);
CWallet::CommitResult CommitTransaction(CTransactionRef tx, CReserveKey* reservekey, CConnman* connman, mapValue_t* extraValues=nullptr);

bool CreateCoinstakeOuts(const CPivStake& stakeInput, std::vector<CTxOut>& vout, CAmount nTotal) const;
bool CreateCoinStake(const CBlockIndex* pindexPrev,
unsigned int nBits,
CMutableTransaction& txNew,
Expand Down
1 change: 0 additions & 1 deletion test/lint/lint-circular-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"wallet/wallet -> wallet/walletdb -> wallet/wallet"
"chain -> legacy/stakemodifier -> stakeinput -> chain"
"chain -> legacy/stakemodifier -> validation -> chain"
"kernel -> stakeinput -> wallet/wallet -> kernel"
"legacy/validation_zerocoin_legacy -> wallet/wallet -> validation -> legacy/validation_zerocoin_legacy"
"llmq/quorums_dkgsession -> llmq/quorums_dkgsessionmgr -> llmq/quorums_dkgsessionhandler -> llmq/quorums_dkgsession"
"llmq/quorums_dkgsessionhandler -> net_processing -> llmq/quorums_dkgsessionmgr -> llmq/quorums_dkgsessionhandler"
Expand Down