VerusStakeTransaction
This commit is contained in:
@@ -10,18 +10,42 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CoinbaseGuard.h"
|
#include "CoinbaseGuard.h"
|
||||||
|
#include "script/script.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
extern int32_t VERUS_MIN_STAKEAGE;
|
extern int32_t VERUS_MIN_STAKEAGE;
|
||||||
|
|
||||||
bool UnpackStakeOpRet(const CTransaction &stakeTx, std::vector<std::vector<unsigned char>> vData)
|
bool UnpackStakeOpRet(const CTransaction &stakeTx, std::vector<std::vector<unsigned char>> &vData)
|
||||||
{
|
{
|
||||||
bool isValid = stakeTx.vout[stakeTx.vout.size() - 1].scriptPubKey.GetOpretData(vData);
|
bool isValid = stakeTx.vout[stakeTx.vout.size() - 1].scriptPubKey.GetOpretData(vData);
|
||||||
|
|
||||||
if (isValid && (vData.size() >= CStakeParams::STAKE_MINPARAMS) && (vData.size() <= CStakeParams::STAKE_MAXPARAMS))
|
if (isValid && vData.size() == 1 && vData[0][0] > 0 && vData[0][0] < 4)
|
||||||
{
|
{
|
||||||
return true;
|
CScript data = CScript(vData[0].begin(), vData[0].end());
|
||||||
|
vData.clear();
|
||||||
|
|
||||||
|
uint32_t bytesTotal;
|
||||||
|
CScript::const_iterator pc = data.begin();
|
||||||
|
std::vector<unsigned char> vch = std::vector<unsigned char>();
|
||||||
|
opcodetype op;
|
||||||
|
bool moreData = true;
|
||||||
|
|
||||||
|
for (bytesTotal = vch.size();
|
||||||
|
bytesTotal <= nMaxDatacarrierBytes && !(isValid = (pc == data.end())) && (moreData = data.GetOp(pc, op, vch)) && (op > 0 && op <= OP_PUSHDATA4);
|
||||||
|
bytesTotal += vch.size())
|
||||||
|
{
|
||||||
|
vData.push_back(vch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we ran out of data, we're ok
|
||||||
|
if (isValid)
|
||||||
|
|
||||||
|
if (isValid && (vData.size() >= CStakeParams::STAKE_MINPARAMS) && (vData.size() <= CStakeParams::STAKE_MAXPARAMS))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +63,7 @@ CStakeParams::CStakeParams(std::vector<std::vector<unsigned char>> vData)
|
|||||||
vData[0][0] == OPRETTYPE_STAKEPARAMS && vData[1].size() <= 4 &&
|
vData[0][0] == OPRETTYPE_STAKEPARAMS && vData[1].size() <= 4 &&
|
||||||
vData[2].size() <= 4 &&
|
vData[2].size() <= 4 &&
|
||||||
vData[3].size() == sizeof(prevHash) &&
|
vData[3].size() == sizeof(prevHash) &&
|
||||||
(vData.size() == STAKE_MINPARAMS || vData[4].size() == 20 || vData[5].size() == 33))
|
(vData.size() == STAKE_MINPARAMS || (vData.size() == STAKE_MAXPARAMS && vData[4].size() == 33)))
|
||||||
{
|
{
|
||||||
for (auto ch : vData[1])
|
for (auto ch : vData[1])
|
||||||
{
|
{
|
||||||
@@ -54,20 +78,12 @@ CStakeParams::CStakeParams(std::vector<std::vector<unsigned char>> vData)
|
|||||||
|
|
||||||
if (vData.size() == 4)
|
if (vData.size() == 4)
|
||||||
{
|
{
|
||||||
dest = CTxDestination();
|
pk = CPubKey();
|
||||||
}
|
|
||||||
else if (vData[4].size() == 20)
|
|
||||||
{
|
|
||||||
dest = CTxDestination(CKeyID(uint160(vData[4])));
|
|
||||||
}
|
}
|
||||||
else if (vData[4].size() == 33)
|
else if (vData[4].size() == 33)
|
||||||
{
|
{
|
||||||
CPubKey pk = CPubKey(vData[4]);
|
pk = CPubKey(vData[4]);
|
||||||
if (pk.IsValid())
|
if (!pk.IsValid())
|
||||||
{
|
|
||||||
dest = pk;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// invalidate
|
// invalidate
|
||||||
srcHeight = 0;
|
srcHeight = 0;
|
||||||
@@ -119,21 +135,11 @@ bool ValidateStakeTransaction(const CTransaction &stakeTx, CStakeParams &stakePa
|
|||||||
(stakeParams.blkHeight - stakeParams.srcHeight >= VERUS_MIN_STAKEAGE) &&
|
(stakeParams.blkHeight - stakeParams.srcHeight >= VERUS_MIN_STAKEAGE) &&
|
||||||
Solver(srcTx.vout[stakeTx.vin[0].prevout.n].scriptPubKey, txType, vAddr))
|
Solver(srcTx.vout[stakeTx.vin[0].prevout.n].scriptPubKey, txType, vAddr))
|
||||||
{
|
{
|
||||||
if (txType == TX_PUBKEY)
|
if (txType == TX_PUBKEY && !stakeParams.pk.IsValid())
|
||||||
{
|
{
|
||||||
if (stakeParams.dest.which() == 0)
|
stakeParams.pk = CPubKey(vAddr[0]);
|
||||||
{
|
|
||||||
stakeParams.dest = CPubKey(vAddr[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (txType == TX_PUBKEYHASH)
|
if ((txType == TX_PUBKEY) || (txType == TX_PUBKEYHASH && stakeParams.pk.IsFullyValid()))
|
||||||
{
|
|
||||||
if (stakeParams.dest.which() == 0)
|
|
||||||
{
|
|
||||||
stakeParams.dest = CKeyID(uint160(vAddr[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((txType == TX_PUBKEY) && (txType == TX_PUBKEYHASH))
|
|
||||||
{
|
{
|
||||||
auto consensusBranchId = CurrentEpochBranchId(stakeParams.blkHeight, Params().GetConsensus());
|
auto consensusBranchId = CurrentEpochBranchId(stakeParams.blkHeight, Params().GetConsensus());
|
||||||
isValid = VerifyScript(stakeTx.vin[0].scriptSig,
|
isValid = VerifyScript(stakeTx.vin[0].scriptSig,
|
||||||
@@ -177,7 +183,7 @@ bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxO
|
|||||||
// version
|
// version
|
||||||
// utxo source hash
|
// utxo source hash
|
||||||
// utxo source output
|
// utxo source output
|
||||||
// hashed address of destination's pubkey
|
// destination's pubkey
|
||||||
CKeyID key = dest.GetID();
|
CKeyID key = dest.GetID();
|
||||||
vout.scriptPubKey << p.AsVector() << OP_DROP
|
vout.scriptPubKey << p.AsVector() << OP_DROP
|
||||||
<< a1 << OP_DROP << a2 << OP_DROP
|
<< a1 << OP_DROP << a2 << OP_DROP
|
||||||
@@ -230,6 +236,7 @@ bool CoinbaseGuardValidate(struct CCcontract_info *cp, Eval* eval, const CTransa
|
|||||||
// return fail
|
// return fail
|
||||||
cc_free(cc);
|
cc_free(cc);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue CoinbaseGuardInfo()
|
UniValue CoinbaseGuardInfo()
|
||||||
|
|||||||
@@ -27,15 +27,36 @@ class CStakeParams
|
|||||||
uint32_t srcHeight;
|
uint32_t srcHeight;
|
||||||
uint32_t blkHeight;
|
uint32_t blkHeight;
|
||||||
uint256 prevHash;
|
uint256 prevHash;
|
||||||
CTxDestination dest;
|
CPubKey pk;
|
||||||
|
|
||||||
CStakeParams() : srcHeight(0), blkHeight(0), prevHash(), dest() {}
|
CStakeParams() : srcHeight(0), blkHeight(0), prevHash(), pk() {}
|
||||||
|
|
||||||
CStakeParams(std::vector<std::vector<unsigned char>> vData);
|
CStakeParams(std::vector<std::vector<unsigned char>> vData);
|
||||||
|
|
||||||
|
CStakeParams(uint32_t _srcHeight, uint32_t _blkHeight, const uint256 &_prevHash, const CPubKey &_pk) :
|
||||||
|
srcHeight(_srcHeight), blkHeight(_blkHeight), prevHash(_prevHash), pk(_pk) {}
|
||||||
|
|
||||||
|
std::vector<unsigned char> AsVector()
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> ret;
|
||||||
|
CScript scr = CScript() << OPRETTYPE_STAKEPARAMS
|
||||||
|
<< srcHeight << blkHeight
|
||||||
|
<< std::vector<unsigned char>(prevHash.begin(), prevHash.end());
|
||||||
|
|
||||||
|
if (pk.IsValid())
|
||||||
|
{
|
||||||
|
scr << std::vector<unsigned char>(pk.begin(), pk.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = std::vector<unsigned char>(scr.begin(), scr.end());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsValid() { return srcHeight != 0; }
|
bool IsValid() { return srcHeight != 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool UnpackStakeOpRet(const CTransaction &stakeTx, std::vector<std::vector<unsigned char>> &vData);
|
||||||
|
|
||||||
bool ValidateStakeTransaction(const CTransaction &stakeTx, CStakeParams &stakeParams);
|
bool ValidateStakeTransaction(const CTransaction &stakeTx, CStakeParams &stakeParams);
|
||||||
|
|
||||||
bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout);
|
bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "amount.h"
|
#include "amount.h"
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
|
#include "cc/CoinbaseGuard.h"
|
||||||
#include "importcoin.h"
|
#include "importcoin.h"
|
||||||
#include "consensus/consensus.h"
|
#include "consensus/consensus.h"
|
||||||
#include "consensus/upgrades.h"
|
#include "consensus/upgrades.h"
|
||||||
@@ -127,12 +128,22 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
|
|||||||
int64_t komodo_block_unlocktime(uint32_t nHeight);
|
int64_t komodo_block_unlocktime(uint32_t nHeight);
|
||||||
uint64_t komodo_commission(const CBlock *block);
|
uint64_t komodo_commission(const CBlock *block);
|
||||||
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
|
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
|
||||||
int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig);
|
int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey &pk);
|
||||||
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
|
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
|
||||||
|
|
||||||
CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
|
CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
|
||||||
{
|
{
|
||||||
CScript scriptPubKeyIn(_scriptPubKeyIn);
|
CScript scriptPubKeyIn(_scriptPubKeyIn);
|
||||||
|
|
||||||
|
CPubKey pk = CPubKey();
|
||||||
|
std::vector<std::vector<unsigned char>> vAddrs;
|
||||||
|
txnouttype txT;
|
||||||
|
if (Solver(scriptPubKeyIn, txT, vAddrs))
|
||||||
|
{
|
||||||
|
if (txT == TX_PUBKEY)
|
||||||
|
pk = CPubKey(vAddrs[0]);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params();
|
uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params();
|
||||||
//fprintf(stderr,"create new block\n");
|
//fprintf(stderr,"create new block\n");
|
||||||
// Create new block
|
// Create new block
|
||||||
@@ -435,7 +446,7 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
uint32_t nBitsPOS;
|
uint32_t nBitsPOS;
|
||||||
arith_uint256 posHash;
|
arith_uint256 posHash;
|
||||||
|
|
||||||
siglen = verus_staked(pblock, txStaked, nBitsPOS, posHash, utxosig);
|
siglen = verus_staked(pblock, txStaked, nBitsPOS, posHash, utxosig, pk);
|
||||||
blocktime = GetAdjustedTime();
|
blocktime = GetAdjustedTime();
|
||||||
|
|
||||||
// change the scriptPubKeyIn to the same output script exactly as the staking transaction
|
// change the scriptPubKeyIn to the same output script exactly as the staking transaction
|
||||||
@@ -470,6 +481,21 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
txNew.vout.resize(1);
|
txNew.vout.resize(1);
|
||||||
txNew.vout[0].scriptPubKey = scriptPubKeyIn;
|
txNew.vout[0].scriptPubKey = scriptPubKeyIn;
|
||||||
txNew.vout[0].nValue = GetBlockSubsidy(nHeight,chainparams.GetConsensus()) + nFees;
|
txNew.vout[0].nValue = GetBlockSubsidy(nHeight,chainparams.GetConsensus()) + nFees;
|
||||||
|
|
||||||
|
// once we get to Sapling, enable CC CoinbaseGuard for stake transactions
|
||||||
|
if (isStake && Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight >= nHeight)
|
||||||
|
{
|
||||||
|
// if there is a specific destination, use it
|
||||||
|
CTransaction stakeTx = pblock->vtx[pblock->vtx.size() - 1];
|
||||||
|
CStakeParams p;
|
||||||
|
if (ValidateStakeTransaction(stakeTx, p))
|
||||||
|
{
|
||||||
|
if (!MakeGuardedOutput(txNew.vout[0].nValue, p.pk, stakeTx, txNew.vout[0]))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
txNew.nExpiryHeight = 0;
|
txNew.nExpiryHeight = 0;
|
||||||
txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||||
|
|
||||||
@@ -488,8 +514,13 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
// prepend time lock to original script unless original script is P2SH, in which case, we will leave the coins
|
// prepend time lock to original script unless original script is P2SH, in which case, we will leave the coins
|
||||||
// protected only by the time lock rather than 100% inaccessible
|
// protected only by the time lock rather than 100% inaccessible
|
||||||
opretScript.AddCheckLockTimeVerify(komodo_block_unlocktime(nHeight));
|
opretScript.AddCheckLockTimeVerify(komodo_block_unlocktime(nHeight));
|
||||||
if (!scriptPubKeyIn.IsPayToScriptHash())
|
if (scriptPubKeyIn.IsPayToScriptHash() || scriptPubKeyIn.IsPayToCryptoCondition())
|
||||||
opretScript += scriptPubKeyIn;
|
{
|
||||||
|
fprintf(stderr,"ERROR: attempt to add timelock to pay2sh or pay2cc\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
opretScript += scriptPubKeyIn;
|
||||||
|
|
||||||
txNew.vout[0].scriptPubKey = CScriptExt().PayToScriptHash(CScriptID(opretScript));
|
txNew.vout[0].scriptPubKey = CScriptExt().PayToScriptHash(CScriptID(opretScript));
|
||||||
txNew.vout[1].scriptPubKey = CScriptExt().OpReturnScript(opretScript, OPRETTYPE_TIMELOCK);
|
txNew.vout[1].scriptPubKey = CScriptExt().OpReturnScript(opretScript, OPRETTYPE_TIMELOCK);
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ bool CScript::GetOpretData(std::vector<std::vector<unsigned char>>& vData) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript, std::vector<std::vector<unsigned char>>& vSolutions) const
|
bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript, std::vector<std::vector<unsigned char>>& vParams) const
|
||||||
{
|
{
|
||||||
const_iterator pc = begin();
|
const_iterator pc = begin();
|
||||||
vector<unsigned char> data;
|
vector<unsigned char> data;
|
||||||
@@ -312,7 +312,7 @@ bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript, std::vector<std::vec
|
|||||||
if (opcode == OP_CHECKCRYPTOCONDITION)
|
if (opcode == OP_CHECKCRYPTOCONDITION)
|
||||||
{
|
{
|
||||||
const_iterator pcCCEnd = pc;
|
const_iterator pcCCEnd = pc;
|
||||||
if (GetBalancedData(pc, vSolutions))
|
if (GetBalancedData(pc, vParams))
|
||||||
{
|
{
|
||||||
if (pCCSubScript)
|
if (pCCSubScript)
|
||||||
*pCCSubScript = CScript(begin(),pc);
|
*pCCSubScript = CScript(begin(),pc);
|
||||||
@@ -324,8 +324,8 @@ bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript, std::vector<std::vec
|
|||||||
|
|
||||||
bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript) const
|
bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript) const
|
||||||
{
|
{
|
||||||
std::vector<std::vector<unsigned char>> vSolutions;
|
std::vector<std::vector<unsigned char>> vParams;
|
||||||
return IsPayToCryptoCondition(pCCSubScript, vSolutions);
|
return IsPayToCryptoCondition(pCCSubScript, vParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CScript::IsPayToCryptoCondition() const
|
bool CScript::IsPayToCryptoCondition() const
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
|
|||||||
// otherwise, push back the corresponding pub key
|
// otherwise, push back the corresponding pub key
|
||||||
vPK.push_back(CPubKey(ParseHex(C.CChexstr)));
|
vPK.push_back(CPubKey(ParseHex(C.CChexstr)));
|
||||||
}
|
}
|
||||||
else if (vParams.size() >= (extraAddrs + 1))
|
else if (vParams.size() > extraAddrs)
|
||||||
{
|
{
|
||||||
bool havePriv;
|
bool havePriv;
|
||||||
vKeyID.push_back(CKeyID(uint160(vParams[1])));
|
vKeyID.push_back(CKeyID(uint160(vParams[1])));
|
||||||
@@ -195,7 +195,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
|
|||||||
return ret.size() != 0;
|
return ret.size() != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (extraAddrs > 1 && vParams.size() >= (extraAddrs + 1))
|
else if (extraAddrs > 1 && vParams.size() > extraAddrs)
|
||||||
{
|
{
|
||||||
// we need to get 2 addresses, and we will need the private key for one
|
// we need to get 2 addresses, and we will need the private key for one
|
||||||
// to spend
|
// to spend
|
||||||
|
|||||||
@@ -5125,9 +5125,9 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
|||||||
return(siglen);
|
return(siglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig)
|
int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey &pk)
|
||||||
{
|
{
|
||||||
return pwalletMain->VerusStakeTransaction(pBlock, txNew, nBits, hashResult, utxosig);
|
return pwalletMain->VerusStakeTransaction(pBlock, txNew, nBits, hashResult, utxosig, pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ensure_CCrequirements()
|
int32_t ensure_CCrequirements()
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
#include "coins.h"
|
#include "coins.h"
|
||||||
#include "zcash/zip32.h"
|
#include "zcash/zip32.h"
|
||||||
|
#include "cc/CoinbaseGuard.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@@ -44,6 +45,8 @@ bool fSendFreeTransactions = false;
|
|||||||
bool fPayAtLeastCustomFee = true;
|
bool fPayAtLeastCustomFee = true;
|
||||||
#include "komodo_defs.h"
|
#include "komodo_defs.h"
|
||||||
|
|
||||||
|
extern int32_t USE_EXTERNAL_PUBKEY;
|
||||||
|
extern std::string NOTARY_PUBKEY;
|
||||||
extern int32_t KOMODO_EXCHANGEWALLET;
|
extern int32_t KOMODO_EXCHANGEWALLET;
|
||||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||||
extern int32_t VERUS_MIN_STAKEAGE;
|
extern int32_t VERUS_MIN_STAKEAGE;
|
||||||
@@ -1245,7 +1248,7 @@ bool CWallet::VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const
|
int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey pk) const
|
||||||
{
|
{
|
||||||
CTransaction stakeSource;
|
CTransaction stakeSource;
|
||||||
int32_t voutNum, siglen = 0;
|
int32_t voutNum, siglen = 0;
|
||||||
@@ -1257,6 +1260,9 @@ int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNe
|
|||||||
tipindex = chainActive.LastTip();
|
tipindex = chainActive.LastTip();
|
||||||
bool extendedStake = tipindex->GetHeight() >= Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight;
|
bool extendedStake = tipindex->GetHeight() >= Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight;
|
||||||
|
|
||||||
|
if (!extendedStake)
|
||||||
|
pk = CPubKey();
|
||||||
|
|
||||||
bnTarget = lwmaGetNextPOSRequired(tipindex, Params().GetConsensus());
|
bnTarget = lwmaGetNextPOSRequired(tipindex, Params().GetConsensus());
|
||||||
|
|
||||||
if (!VerusSelectStakeOutput(pBlock, hashResult, stakeSource, voutNum, tipindex->GetHeight() + 1, bnTarget) ||
|
if (!VerusSelectStakeOutput(pBlock, hashResult, stakeSource, voutNum, tipindex->GetHeight() + 1, bnTarget) ||
|
||||||
@@ -1278,17 +1284,16 @@ int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNe
|
|||||||
txNew.vin[0].prevout.hash = stakeSource.GetHash();
|
txNew.vin[0].prevout.hash = stakeSource.GetHash();
|
||||||
txNew.vin[0].prevout.n = voutNum;
|
txNew.vin[0].prevout.n = voutNum;
|
||||||
|
|
||||||
CPubKey pk = CPubKey();
|
|
||||||
|
|
||||||
if (whichType == TX_PUBKEY)
|
if (whichType == TX_PUBKEY)
|
||||||
{
|
{
|
||||||
txNew.vout[0].scriptPubKey << ToByteVector(vSolutions[0]) << OP_CHECKSIG;
|
txNew.vout[0].scriptPubKey << ToByteVector(vSolutions[0]) << OP_CHECKSIG;
|
||||||
pk = CPubKey(vSolutions[0]);
|
if (!pk.IsValid())
|
||||||
|
pk = CPubKey(vSolutions[0]);
|
||||||
}
|
}
|
||||||
else if (whichType == TX_PUBKEYHASH)
|
else if (whichType == TX_PUBKEYHASH)
|
||||||
{
|
{
|
||||||
txNew.vout[0].scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(vSolutions[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
|
txNew.vout[0].scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(vSolutions[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||||
if (extendedStake)
|
if (extendedStake && !pk.IsValid())
|
||||||
{
|
{
|
||||||
// we need a pubkey, so try to get one from the key ID, if not there, fail
|
// we need a pubkey, so try to get one from the key ID, if not there, fail
|
||||||
if (!keystore.GetPubKey(CKeyID(uint160(vSolutions[0])), pk))
|
if (!keystore.GetPubKey(CKeyID(uint160(vSolutions[0])), pk))
|
||||||
@@ -1299,7 +1304,7 @@ int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNe
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// if we are staking with the extended format, add the opreturn data required
|
// if we are staking with the extended format, add the opreturn data required
|
||||||
//if (extendedStake)
|
if (extendedStake)
|
||||||
{
|
{
|
||||||
uint256 srcBlock = uint256();
|
uint256 srcBlock = uint256();
|
||||||
CBlockIndex *pSrcIndex;
|
CBlockIndex *pSrcIndex;
|
||||||
@@ -1314,14 +1319,7 @@ int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNe
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
txOut1.scriptPubKey << OP_RETURN
|
txOut1.scriptPubKey << OP_RETURN
|
||||||
<< (int8_t)OPRETTYPE_STAKEPARAMS
|
<< CStakeParams(pSrcIndex->GetHeight(), tipindex->GetHeight(), pBlock->hashPrevBlock, pk).AsVector();
|
||||||
<< pSrcIndex->GetHeight() << tipindex->GetHeight()
|
|
||||||
<< std::vector<unsigned char>(pBlock->hashPrevBlock.begin(), pBlock->hashPrevBlock.end())
|
|
||||||
<< std::vector<unsigned char>(pk.begin(), pk.end());
|
|
||||||
|
|
||||||
// need to decide how to decide, but then we can add a delegated source here for the coinbase output
|
|
||||||
//if (USE_EXTERNAL_PUBKEY)
|
|
||||||
// txOut1.scriptPubKey << ParseHex(NOTARY_PUBKEY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nValue = txNew.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
|
nValue = txNew.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
|
||||||
|
|||||||
@@ -1278,7 +1278,7 @@ public:
|
|||||||
|
|
||||||
// staking functions
|
// staking functions
|
||||||
bool VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult, CTransaction &stakeSource, int32_t &voutNum, int32_t nHeight, uint32_t &bnTarget) const;
|
bool VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult, CTransaction &stakeSource, int32_t &voutNum, int32_t nHeight, uint32_t &bnTarget) const;
|
||||||
int32_t VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const;
|
int32_t VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey pk) const;
|
||||||
|
|
||||||
/* Find unspent notes filtered by payment address, min depth and max depth */
|
/* Find unspent notes filtered by payment address, min depth and max depth */
|
||||||
void GetUnspentFilteredNotes(std::vector<CUnspentSproutNotePlaintextEntry>& sproutEntries,
|
void GetUnspentFilteredNotes(std::vector<CUnspentSproutNotePlaintextEntry>& sproutEntries,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "keystore.h"
|
#include "keystore.h"
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
#include "script/standard.h"
|
#include "script/standard.h"
|
||||||
|
#include "cc/eval.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
@@ -83,6 +84,30 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& _scriptPubKey)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TX_CRYPTOCONDITION:
|
||||||
|
{
|
||||||
|
// some crypto conditions we consider "mine" if our address is the first specified
|
||||||
|
// extra address
|
||||||
|
CScript subScript;
|
||||||
|
vector<valtype> vParams;
|
||||||
|
COptCCParams p;
|
||||||
|
if (scriptPubKey.IsPayToCryptoCondition(&subScript, vParams))
|
||||||
|
{
|
||||||
|
if (vParams.size() > 1)
|
||||||
|
{
|
||||||
|
p = COptCCParams(vParams[0]);
|
||||||
|
// if we are the primary output on a coinbase guard, it is ours
|
||||||
|
if (p.IsValid() && p.evalCode == EVAL_COINBASEGUARD && vParams[1].size() == 20)
|
||||||
|
{
|
||||||
|
CKeyID adr = CKeyID(uint160(vParams[1]));
|
||||||
|
if (keystore.HaveKey(keyID))
|
||||||
|
return ISMINE_SPENDABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TX_MULTISIG:
|
case TX_MULTISIG:
|
||||||
{
|
{
|
||||||
// Only consider transactions "mine" if we own ALL the
|
// Only consider transactions "mine" if we own ALL the
|
||||||
|
|||||||
Reference in New Issue
Block a user