diff --git a/src/blockassembler.cpp b/src/blockassembler.cpp index e647b9a61fe1f4..1c5b2d1405539d 100644 --- a/src/blockassembler.cpp +++ b/src/blockassembler.cpp @@ -96,10 +96,6 @@ bool SolveProofOfStake(CBlock* pblock, CBlockIndex* pindexPrev, CMutableTransact CMutableTransaction txCoinbase = NewCoinbase(pindexPrev->nHeight + 1); FillBlockPayee(txCoinbase, txCoinStake, pindexPrev, true); - if (pblock->IsProofOfShieldStake()) { - auto& shieldStake = *static_cast(pStake); - pwallet->ComputeShieldStakeProof(*pblock, shieldStake, shieldStake.note.value()); - } // Sign coinstake if (!pwallet->SignCoinStake(txCoinStake)) { @@ -110,6 +106,11 @@ bool SolveProofOfStake(CBlock* pblock, CBlockIndex* pindexPrev, CMutableTransact pblock->vtx.emplace_back(MakeTransactionRef(txCoinbase)); pblock->vtx.emplace_back(MakeTransactionRef(txCoinStake)); pblock->nTime = nTxNewTime; + + if (pblock->IsProofOfShieldStake()) { + auto& shieldStake = *static_cast(pStake); + pwallet->ComputeShieldStakeProof(*pblock, shieldStake, shieldStake.note.value()); + } return true; } diff --git a/src/kernel.cpp b/src/kernel.cpp index aa83bd674130c3..d6c397162e4b2a 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -112,7 +112,6 @@ static bool LoadStakeInput(const CBlock& block, std::unique_ptr& st if (block.IsProofOfShieldStake()) { // Sapling data existence is guaranteed with isProofOfShieldStake call const auto& saplingData = block.vtx[1]->sapData.get(); - stake = std::unique_ptr(CShieldStake::NewShieldStake(saplingData.vShieldedSpend.at(0), block.shieldStakeProof.amount, nHeight, block.nTime)); return stake != nullptr; } else { @@ -190,11 +189,12 @@ bool CheckProofOfStake(const CBlock& block, std::string& strError, const CBlockI if (stakeInput->IsShieldPIV()) { // Check proof validity // TODO: refactor, just for testing - auto& shieldStake = dynamic_cast(*stakeInput); + auto& shieldStake = static_cast(*stakeInput); if (!CheckShieldStakeValidity(block, strError, shieldStake)) { return false; } + return true; } // zPoS disabled (ContextCheck) before blocks V7, and the tx input signature is in CoinSpend diff --git a/src/primitives/block.h b/src/primitives/block.h index 1a49f5f2cbfc1c..2cb03885abcd40 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -166,7 +166,7 @@ class CBlock : public CBlockHeader bool IsProofOfStake() const { - return (vtx.size() > 1 && vtx[1]->IsCoinStake()); + return (vtx.size() > 1 && vtx[1]->IsCoinStake()) || IsProofOfShieldStake(); } bool IsProofOfShieldStake() const diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 466ac7478fb199..d1a7b9822871bc 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -147,12 +147,14 @@ bool CTransaction::IsCoinStake() const // Vout[0] must be empty, no transparent input and non empty sapling input and output bool CTransaction::IsCoinShieldStake() const { + if (!sapData) + return false; if (sapData->vShieldedSpend.empty()) return false; if (!vin.empty()) return false; - return (!sapData->vShieldedOutput.empty() && vout.size() == 1 && vout[0].IsEmpty()); + return (vout.size() == 1 && vout[0].IsEmpty()); } bool CTransaction::HasP2CSOutputs() const diff --git a/src/sapling/sapling_validation.cpp b/src/sapling/sapling_validation.cpp index 80218f284cddb3..b2251e62564ceb 100644 --- a/src/sapling/sapling_validation.cpp +++ b/src/sapling/sapling_validation.cpp @@ -5,11 +5,12 @@ #include "sapling/sapling_validation.h" -#include "consensus/consensus.h" // for MAX_BLOCK_SIZE_CURRENT -#include "script/interpreter.h" // for SigHash +#include "consensus/consensus.h" // for MAX_BLOCK_SIZE_CURRENT +#include "consensus/upgrades.h" // for CurrentEpochBranchId() #include "consensus/validation.h" // for CValidationState -#include "util/system.h" // for error() -#include "consensus/upgrades.h" // for CurrentEpochBranchId() +#include "logging.h" +#include "script/interpreter.h" // for SigHash +#include "util/system.h" // for error() #include @@ -231,6 +232,7 @@ bool CheckShieldStake(const CBlock& block, CValidationState& state, const CChain if (!block.IsProofOfShieldStake()) { return false; } + return true; // TODO: check rest // In addition to the regular checks for a tx, we also have to ensure that the provided // shieldStakeAmount is valid. To do this without creating a new circuit, the staker inserts @@ -258,6 +260,8 @@ bool CheckShieldStake(const CBlock& block, CValidationState& state, const CChain return false; } + librustzcash_sapling_verification_ctx_free(saplingCtx); + LogPrintf("Phonenuix"); return true; } diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp index 26f57d6fdcc4ee..fb254c13a65f94 100644 --- a/src/support/lockedpool.cpp +++ b/src/support/lockedpool.cpp @@ -4,6 +4,7 @@ #include "support/lockedpool.h" #include "support/cleanse.h" +#include #if defined(HAVE_CONFIG_H) #include "config/pivx-config.h" diff --git a/src/validation.cpp b/src/validation.cpp index 092e2e48f87d2d..6ec13fff29f3ac 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2478,9 +2478,11 @@ static CBlockIndex* AddToBlockIndex(const CBlock& block) EXCLUSIVE_LOCKS_REQUIRE } else { // compute and set new V2 stake modifier (hash of prevout and prevModifier) if (block.IsProofOfStake()) { - pindexNew->SetNewStakeModifier(block.vtx[1]->vin[0].prevout.hash); - } else if (block.IsProofOfShieldStake()) { - pindexNew->SetNewStakeModifier(block.vtx[1]->sapData->vShieldedSpend[0].nullifier); + if (block.IsProofOfShieldStake()) { + pindexNew->SetNewStakeModifier(block.vtx[1]->sapData->vShieldedSpend[0].nullifier); + } else { + pindexNew->SetNewStakeModifier(block.vtx[1]->vin[0].prevout.hash); + } } } } @@ -2705,7 +2707,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo return true; // These are checks that are independent of context. - const bool IsPoS = block.IsProofOfStake() || block.IsProofOfShieldStake(); + const bool IsPoS = block.IsProofOfStake(); // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. @@ -2780,7 +2782,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // that this block is invalid, so don't issue an outright ban. if (nHeight != 0 && !IsInitialBlockDownload()) { // Last output of Cold-Stake is not abused - if (block.IsProofOfStake() && !CheckColdStakeFreeOutput(*(block.vtx[1]), nHeight)) { + if ((block.IsProofOfStake() && !block.IsProofOfShieldStake()) && !CheckColdStakeFreeOutput(*(block.vtx[1]), nHeight)) { mapRejectedBlocks.emplace(block.GetHash(), GetTime()); return state.DoS(0, false, REJECT_INVALID, "bad-p2cs-outs", false, "invalid cold-stake output"); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 06810495dd5f82..5ffc6437a80e52 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5003,29 +5003,7 @@ CStakeableOutput::CStakeableOutput(const CWalletTx* txIn, bool CWallet::ComputeShieldStakeProof(CBlock& block, CStakeableShieldNote& note, CAmount suggestedValue) { assert(block.IsProofOfShieldStake()); - assert(note.note.value() > suggestedValue); - auto& proof = block.shieldStakeProof; - proof.amount = suggestedValue; - TransactionBuilder txBuilder(Params().GetConsensus(), this); - txBuilder.SetFee(0); - libzcash::SaplingExtendedSpendingKey sk; - if (!GetSaplingExtendedSpendingKey(note.address, sk)) { - return false; - } - uint256 anchor; - std::vector> witnesses; - std::vector noteop = { note.op }; - m_sspk_man->GetSaplingNoteWitnesses(noteop, witnesses, anchor); - txBuilder.AddSaplingSpend(sk.expsk, note.note, anchor, witnesses[0].get()); - // Add transparent output? - const auto& txTrial = txBuilder.Build().GetTx(); - if(txTrial) { - proof.input = txTrial->sapData->vShieldedSpend[0]; - proof.output = txTrial->sapData->vShieldedOutput[0]; - proof.amount = txTrial->sapData->valueBalance; - proof.bindingSig.insert(proof.bindingSig.end(), txTrial->sapData->bindingSig.begin(), txTrial->sapData->bindingSig.end()); - return true; - } else { - return false; - } + assert(note.note.value() >= suggestedValue); + block.shieldStakeProof.amount = suggestedValue; + return true; }