diff --git a/src/miner.cpp b/src/miner.cpp index 46d669563..9e502badf 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -312,6 +312,7 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, if (cheatSpend) { + cheatTx = cheatSpend.value(); std::list removed; mempool.removeConflicts(cheatTx, removed); printf("Found cheating stake! Adding cheat spend for %.8f at block #%d, coinbase tx\n%s\n", diff --git a/src/script/sign.cpp b/src/script/sign.cpp index e384d0e74..ec7d89dac 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -12,6 +12,7 @@ #include "uint256.h" #include "cc/CCinclude.h" #include "cc/eval.h" +#include "key_io.h" #include @@ -96,6 +97,11 @@ CC *CCcond1(uint8_t evalcode,CPubKey pk) return CCNewThreshold(2, {condCC, Sig}); } +// TODO: these are redundant and should be cleaned up to one file +std::string _StakeGuardAddr = "RCG8KwJNDVwpUBcdoa6AoHqHVJsA1uMYMR"; +std::string _StakeGuardPubKey = "03166b7813a4855a88e9ef7340a692ef3c2decedfdc2c7563ec79537e89667d935"; +std::string _StakeGuardWIF = "Uw7vRYHGKjyi1FaJ8Lv1USSuj7ntUti8fAhSDiCdbzuV6yDagaTn"; + std::vector &GetCryptoConditions() { static bool initialized = false; @@ -105,11 +111,10 @@ std::vector &GetCryptoConditions() if (!initialized) { C.evalcode = EVAL_STAKEGUARD; - uint8_t privKey[32] = { 0x9b, 0x17, 0x66, 0xe5, 0x82, 0x66, 0xac, 0xb6, 0xba, 0x43, 0x83, 0x74, 0xf7, 0x63, 0x11, 0x3b, 0xf0, 0xf3, 0x50, 0x6f, 0xd9, 0x6b, 0x67, 0x85, 0xf9, 0x7a, 0xf0, 0x54, 0x4d, 0xb1, 0x30, 0x77 }; - strcpy(C.unspendableCCaddr,"RGKRjeTBw4LYFotSDLT6RWzMHbhXri6BG6"); - strcpy(C.normaladdr,"RFYE2yL3KknWdHK6uNhvWacYsCUtwzjY3u"); - strcpy(C.CChexstr,"02adf84e0e075cf90868bd4e3d34a03420e034719649c41f371fc70d8e33aa2702"); - memcpy(C.CCpriv, privKey, 32); + strcpy(C.unspendableCCaddr,_StakeGuardAddr.c_str()); + strcpy(C.normaladdr,_StakeGuardAddr.c_str()); + strcpy(C.CChexstr,_StakeGuardPubKey.c_str()); + memcpy(C.CCpriv, DecodeSecret(_StakeGuardWIF).begin(),32); vCC.push_back(C); initialized = true; diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 558cd0756..07e201326 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -57,7 +57,7 @@ void TransactionBuilder::AddSaplingOutput( mtx.valueBalance -= value; } -void TransactionBuilder::AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value) +void TransactionBuilder::AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value, uint32_t _nSequence) { if (keystore == nullptr) { if (!scriptPubKey.IsPayToCryptoCondition()) @@ -67,6 +67,7 @@ void TransactionBuilder::AddTransparentInput(COutPoint utxo, CScript scriptPubKe } mtx.vin.emplace_back(utxo); + mtx.vin[mtx.vin.size() - 1].nSequence = _nSequence; tIns.emplace_back(scriptPubKey, value); } diff --git a/src/transaction_builder.h b/src/transaction_builder.h index d040ed06c..49c09294d 100644 --- a/src/transaction_builder.h +++ b/src/transaction_builder.h @@ -92,7 +92,7 @@ public: std::array memo = {{0}}); // Assumes that the value correctly corresponds to the provided UTXO. - void AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value); + void AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value, uint32_t nSequence = 0xffffffff); bool AddTransparentOutput(CTxDestination& to, CAmount value); @@ -104,6 +104,8 @@ public: bool SendChangeTo(CTxDestination& changeAddr); + void SetLockTime(uint32_t time) { this->mtx.nLockTime = time; } + boost::optional Build(); }; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 43c112912..4e2895675 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -37,6 +37,8 @@ using namespace libzcash; +extern char ASSETCHAINS_SYMBOL[65]; + extern UniValue signrawtransaction(const UniValue& params, bool fHelp); extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); @@ -351,6 +353,12 @@ bool AsyncRPCOperation_sendmany::main_impl() { CAmount amount = std::get<2>(t); builder_.AddTransparentInput(COutPoint(txid, vout), scriptPubKey, amount); } + // for Komodo, set lock time to accure interest, for other chains, set + // locktime to spend time locked coinbases + if (ASSETCHAINS_SYMBOL[0] == 0) + { + builder_.SetLockTime((uint32_t)time(NULL) - 60); // set lock time for Komodo interest + } } else { CMutableTransaction rawTx(tx_); for (SendManyInputUTXO & t : t_inputs_) { @@ -360,7 +368,10 @@ bool AsyncRPCOperation_sendmany::main_impl() { CTxIn in(COutPoint(txid, vout)); rawTx.vin.push_back(in); } - rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 + if (ASSETCHAINS_SYMBOL[0] == 0) + { + rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 + } tx_ = CTransaction(rawTx); } } diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 6814e76d2..11aa1037f 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -270,7 +270,15 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c // Add transparent inputs for (auto t : m_op->inputs_) { - m_op->builder_.AddTransparentInput(COutPoint(t.txid, t.vout), t.scriptPubKey, t.amount); + if (t.amount >= ASSETCHAINS_TIMELOCKGTE) + { + m_op->builder_.SetLockTime((uint32_t)(chainActive.Height() + 1)); + m_op->builder_.AddTransparentInput(COutPoint(t.txid, t.vout), t.scriptPubKey, t.amount, 0); + } + else + { + m_op->builder_.AddTransparentInput(COutPoint(t.txid, t.vout), t.scriptPubKey, t.amount); + } } // Send all value to the target z-addr diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bae4242e7..e00d733dd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4470,7 +4470,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) // (used if no Sapling addresses are involved) CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( Params().GetConsensus(), nextBlockHeight); - contextualTx.nLockTime = blockHeight; + contextualTx.nLockTime = nextBlockHeight; + if (contextualTx.nVersion == 1) { contextualTx.nVersion = 2; // Tx format should support vjoinsplits }