Skip to content

Commit

Permalink
Merge #2750: [Refactor] Create coinstake outputs moved from stakeInpu…
Browse files Browse the repository at this point in the history
…t to the wallet class.

ccd6fcd Move-only: Create coinstake outputs moved fro stakeInput.h/cpp to wallet.h/cpp (furszy)

Pull request description:

  Fixing the circular dependency:
  "kernel -> stakeinput -> wallet/wallet -> kernel"

ACKs for top commit:
  random-zebra:
    utACK ccd6fcd

Tree-SHA512: 4a5a2f1b9dc9407e805c89073051eb20bd867402ec07e3e571556d116b4996f60461ec15454ca11948c9ea64a6b8a671d9b1bd9ae11bbba14d38e8e867bd024a
  • Loading branch information
furszy committed Mar 4, 2022
2 parents 76de203 + ccd6fcd commit fc63a6f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 43 deletions.
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

0 comments on commit fc63a6f

Please sign in to comment.