using namespace libzcash;
extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
+extern int32_t USE_EXTERNAL_PUBKEY;
int64_t nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime;
#define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA"
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern int32_t KOMODO_PAX;
+extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE;
int32_t komodo_is_issuer();
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp);
int32_t komodo_isrealtime(int32_t *kmdheightp);
MaybePushAddress(entry, r.destination);
if (wtx.IsCoinBase())
{
+ int btm;
if (wtx.GetDepthInMainChain() < 1)
entry.push_back(Pair("category", "orphan"));
- else if (wtx.GetBlocksToMaturity() > 0)
+ else if ((btm = wtx.GetBlocksToMaturity()) > 0)
+ {
entry.push_back(Pair("category", "immature"));
+ entry.push_back(Pair("blockstomaturity", btm));
+ }
else
entry.push_back(Pair("category", "generate"));
}
}
}
}
+ KOMODO_INTERESTSUM = sum;
+ KOMODO_WALLETBALANCE = pwalletMain->GetBalance();
return(sum);
}
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight);
bool isShielded = !fromTaddr || zaddrRecipients.size() > 0;
if (contextualTx.nVersion == 1 && isShielded) {
- contextualTx.nVersion = 2; // Tx format should support vjoinsplits
+ contextualTx.nVersion = 2; // Tx format should support vjoinsplits
}
if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
contextualTx.nExpiryHeight = nextBlockHeight + expiryDelta;
CAmount shieldedValue = 0;
CAmount remainingValue = 0;
size_t estimatedTxSize = 2000; // 1802 joinsplit description + tx overhead + wiggle room
+
+ #ifdef __LP64__
+ uint64_t utxoCounter = 0;
+ #else
size_t utxoCounter = 0;
+ #endif
+
bool maxedOutFlag = false;
size_t mempoolLimit = (nLimit != 0) ? nLimit : (size_t)GetArg("-mempooltxinputlimit", 0);
if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
continue;
}
+
// If taddr is not wildcard "*", filter utxos
if (setAddress.size()>0 && !setAddress.count(address)) {
continue;
}
}
+ #ifdef __LP64__
+ uint64_t numUtxos = inputs.size();
+ #else
size_t numUtxos = inputs.size();
+ #endif
if (numUtxos == 0) {
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any coinbase funds to shield.");
contextInfo.push_back(Pair("fee", ValueFromAmount(nFee)));
// Contextual transaction we will build on
- int nextBlockHeight = chainActive.Height() + 1;
+ int blockHeight = chainActive.Height();
+ int nextBlockHeight = blockHeight + 1;
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
Params().GetConsensus(), nextBlockHeight);
+ contextualTx.nLockTime = blockHeight;
if (contextualTx.nVersion == 1) {
- contextualTx.nVersion = 2; // Tx format should support vjoinsplits
+ contextualTx.nVersion = 2; // Tx format should support vjoinsplits
}
if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
contextualTx.nExpiryHeight = nextBlockHeight + expiryDelta;
CAmount mergedNoteValue = 0;
CAmount remainingUTXOValue = 0;
CAmount remainingNoteValue = 0;
+ #ifdef __LP64__
+ uint64_t utxoCounter = 0;
+ uint64_t noteCounter = 0;
+ #else
size_t utxoCounter = 0;
size_t noteCounter = 0;
+ #endif
bool maxedOutUTXOsFlag = false;
bool maxedOutNotesFlag = false;
size_t mempoolLimit = (nUTXOLimit != 0) ? nUTXOLimit : (size_t)GetArg("-mempooltxinputlimit", 0);
}
}
+ #ifdef __LP64__
+ uint64_t numUtxos = utxoInputs.size(); //ca333
+ uint64_t numNotes = noteInputs.size();
+ #else
size_t numUtxos = utxoInputs.size();
size_t numNotes = noteInputs.size();
+ #endif
+
if (numUtxos == 0 && numNotes == 0) {
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge.");
#include "script/sign.h"
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
extern std::string NOTARY_PUBKEY;
-uint32_t komodo_stake(arith_uint256 bnTarget,int32_t nHeight,uint256 hash,int32_t n,uint32_t blocktime,uint32_t prevtime);
+uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 hash,int32_t n,uint32_t blocktime,uint32_t prevtime,char *destaddr);
-int32_t komodo_staked(uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig)
+int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33)
+{
+ set<CBitcoinAddress> setAddress; uint8_t *script,utxosig[128]; uint256 utxotxid; uint64_t utxovalue; int32_t i,siglen=0,nMinDepth = 1,nMaxDepth = 9999999; vector<COutput> vecOutputs; uint32_t utxovout,eligible,earliest = 0; CScript best_scriptPubKey; bool fNegative,fOverflow;
+ bool signSuccess; SignatureData sigdata; uint64_t txfee; uint8_t *ptr;
+ auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
+ const CKeyStore& keystore = *pwalletMain;
+ assert(pwalletMain != NULL);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+ utxovalue = 0;
+ memset(&utxotxid,0,sizeof(utxotxid));
+ memset(&utxovout,0,sizeof(utxovout));
+ memset(utxosig,0,sizeof(utxosig));
+ pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
+ BOOST_FOREACH(const COutput& out, vecOutputs)
+ {
+ if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
+ continue;
+ if ( setAddress.size() )
+ {
+ CTxDestination address;
+ if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
+ continue;
+ if (!setAddress.count(address))
+ continue;
+ }
+ CAmount nValue = out.tx->vout[out.i].nValue;
+ if ( nValue != 10000 )
+ continue;
+ const CScript& pk = out.tx->vout[out.i].scriptPubKey;
+ CTxDestination address;
+ if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
+ {
+ //entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
+ //if (pwalletMain->mapAddressBook.count(address))
+ // entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
+ }
+ script = (uint8_t *)out.tx->vout[out.i].scriptPubKey.data();
+ if ( out.tx->vout[out.i].scriptPubKey.size() != 35 || script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(notarypub33,script+1,33) != 0 )
+ {
+ fprintf(stderr,"scriptsize.%d [0] %02x\n",(int32_t)out.tx->vout[out.i].scriptPubKey.size(),script[0]);
+ continue;
+ }
+ utxovalue = (uint64_t)nValue;
+ //decode_hex((uint8_t *)&utxotxid,32,(char *)out.tx->GetHash().GetHex().c_str());
+ utxotxid = out.tx->GetHash();
+ utxovout = out.i;
+ best_scriptPubKey = out.tx->vout[out.i].scriptPubKey;
+ //fprintf(stderr,"check %s/v%d %llu\n",(char *)utxotxid.GetHex().c_str(),utxovout,(long long)utxovalue);
+
+ txNew.vin.resize(1);
+ txNew.vout.resize(1);
+ txfee = utxovalue / 2;;
+ //for (i=0; i<32; i++)
+ // ((uint8_t *)&revtxid)[i] = ((uint8_t *)&utxotxid)[31 - i];
+ txNew.vin[0].prevout.hash = utxotxid; //revtxid;
+ txNew.vin[0].prevout.n = utxovout;
+ txNew.vout[0].scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
+ txNew.vout[0].nValue = utxovalue - txfee;
+ CTransaction txNewConst(txNew);
+ signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, utxovalue, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
+ if (!signSuccess)
+ fprintf(stderr,"notaryvin failed to create signature\n");
+ else
+ {
+ UpdateTransaction(txNew,0,sigdata);
+ ptr = (uint8_t *)sigdata.scriptSig.data();
+ siglen = sigdata.scriptSig.size();
+ for (i=0; i<siglen; i++)
+ utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
+ //fprintf(stderr," siglen.%d notaryvin %s/v%d\n",siglen,utxotxid.GetHex().c_str(),utxovout);
+ break;
+ }
+ }
+ return(siglen);
+}
+
+int32_t komodo_staked(CPubKey &pubkey, CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig)
{
set<CBitcoinAddress> setAddress; int32_t i,siglen=0,nMinDepth = 1,nMaxDepth = 9999999; vector<COutput> vecOutputs; uint32_t eligible,earliest = 0; CScript best_scriptPubKey; arith_uint256 bnTarget; bool fNegative,fOverflow;
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
//if (pwalletMain->mapAddressBook.count(address))
// entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
}
- /*entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end())));
- if (pk.IsPayToScriptHash())
- {
- CTxDestination address;
- if (ExtractDestination(pk, address)) {
- const CScriptID& hash = boost::get<CScriptID>(address);
- CScript redeemScript;
- if (pwalletMain->GetCScript(hash, redeemScript))
- entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
- }
- }
- entry.push_back(Pair("amount",ValueFromAmount(nValue)));*/
- BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
- CBlockIndex *tipindex,*pindex = it->second;
- uint64_t interest; uint32_t locktime; int32_t txheight;
- if ( pindex != 0 && (tipindex= chainActive.Tip()) != 0 )
+ //BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
+ CBlockIndex *tipindex;
+ if ( (tipindex= chainActive.Tip()) != 0 )
{
- eligible = komodo_stake(bnTarget,(uint32_t)tipindex->nHeight+1,out.tx->GetHash(),out.i,*blocktimep,(uint32_t)tipindex->nTime);
+ eligible = komodo_stake(0,bnTarget,(uint32_t)tipindex->nHeight+1,out.tx->GetHash(),out.i,0,(uint32_t)tipindex->nTime,(char *)CBitcoinAddress(address).ToString().c_str());
if ( eligible > 0 )
{
- if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || nValue < *utxovaluep)) )
+ if ( eligible != komodo_stake(1,bnTarget,(uint32_t)tipindex->nHeight+1,out.tx->GetHash(),out.i,eligible,(uint32_t)tipindex->nTime,(char *)CBitcoinAddress(address).ToString().c_str()) )
+ {
+ //fprintf(stderr,"tip.%d validation of winning blocktime failed %u -> eligible.%u\n",(uint32_t)tipindex->nHeight,*blocktimep,eligible);
+ }
+ else if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || nValue < *utxovaluep)) )
{
earliest = eligible;
best_scriptPubKey = out.tx->vout[out.i].scriptPubKey;
decode_hex((uint8_t *)utxotxidp,32,(char *)out.tx->GetHash().GetHex().c_str());
*utxovoutp = out.i;
*txtimep = (uint32_t)out.tx->nLockTime;
+ fprintf(stderr,"earliest.%u [%d] (%s) nValue %.8f locktime.%u\n",earliest,(int32_t)(earliest- *blocktimep),CBitcoinAddress(address).ToString().c_str(),(double)nValue/COIN,*txtimep);
}
}
- //fprintf(stderr,"(%s) %s/v%d nValue %.8f locktime.%u txheight.%d pindexht.%d\n",CBitcoinAddress(address).ToString().c_str(),out.tx->GetHash().GetHex().c_str(),out.i,(double)nValue/COIN,locktime,txheight,pindex->nHeight);
}
}
if ( earliest != 0 )
bool signSuccess; SignatureData sigdata; uint64_t txfee; uint8_t *ptr; uint256 revtxid,utxotxid;
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
const CKeyStore& keystore = *pwalletMain;
- CMutableTransaction txNew = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
txNew.vin.resize(1);
txNew.vout.resize(1);
txfee = 0;
((uint8_t *)&revtxid)[i] = ((uint8_t *)utxotxidp)[31 - i];
txNew.vin[0].prevout.hash = revtxid;
txNew.vin[0].prevout.n = *utxovoutp;
- txNew.vout[0].scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
+
+ // TODO: see if we can't remove this and dump the pubkey, not depend on global notary key explicitly
+ if ( USE_EXTERNAL_PUBKEY != 0 )
+ {
+ //fprintf(stderr,"use notary pubkey\n");
+ txNew.vout[0].scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
+ }
+ else
+ {
+ uint8_t *script,*ptr;
+ int32_t i;
+
+ txNew.vout[0].scriptPubKey.resize(35);
+ ptr = (uint8_t *)pubkey.begin();
+ script = (uint8_t *)(txNew.vout[0].scriptPubKey.data());
+ script[0] = 33;
+ for (i=0; i<33; i++)
+ script[i+1] = ptr[i];
+ script[34] = OP_CHECKSIG;
+ //scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
+ }
+
txNew.vout[0].nValue = *utxovaluep - txfee;
- txNew.nLockTime = *blocktimep;
+ txNew.nLockTime = earliest;
CTransaction txNewConst(txNew);
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
if (!signSuccess)
fprintf(stderr,"failed to create signature\n");
else
{
+ UpdateTransaction(txNew,0,sigdata);
ptr = (uint8_t *)sigdata.scriptSig.data();
siglen = sigdata.scriptSig.size();
for (i=0; i<siglen; i++)
utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
//fprintf(stderr," siglen.%d\n",siglen);
- fprintf(stderr,"best %u from %u, gap %d\n",eligible,*blocktimep,(int32_t)(eligible - *blocktimep));
- *blocktimep = eligible;
+ //fprintf(stderr,"best %u from %u, gap %d lag.%d\n",earliest,*blocktimep,(int32_t)(earliest - *blocktimep),(int32_t)(time(NULL) - *blocktimep));
+ *blocktimep = earliest;
}
}
return(siglen);
}
+int32_t verus_staked(CPubKey &pubkey, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig)
+{
+ return pwalletMain->VerusStakeTransaction(pubkey, txNew, nBits, hashResult, utxosig);
+}