Merge branch 'mastertest'

merge in mastertest
This commit is contained in:
blackjok3r
2018-11-23 13:03:59 +08:00
57 changed files with 2022 additions and 940 deletions

View File

@@ -268,7 +268,7 @@ libbitcoin_server_a_SOURCES = \
cc/dice.cpp \
cc/lotto.cpp \
cc/fsm.cpp \
cc/MofN.cpp \
cc/heir.cpp \
cc/oracles.cpp \
cc/prices.cpp \
cc/pegs.cpp \

View File

@@ -62,8 +62,8 @@ void WaitForShutdown(boost::thread_group* threadGroup)
}
else
{
komodo_interestsum();
komodo_longestchain();
//komodo_interestsum();
//komodo_longestchain();
MilliSleep(20000);
}
fShutdown = ShutdownRequested();

View File

@@ -95,7 +95,7 @@ EVAL(EVAL_DICE, 0xe6) \
EVAL(EVAL_FSM, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9) \
EVAL(EVAL_MOFN, 0xea) \
EVAL(EVAL_HEIR, 0xea) \
EVAL(EVAL_CHANNELS, 0xeb) \
EVAL(EVAL_ORACLES, 0xec) \
EVAL(EVAL_PRICES, 0xed) \

View File

@@ -24,10 +24,11 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys);
std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vector<uint8_t>proof,CPubKey destpub,int64_t amount);
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount);
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount);
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid);
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr);
UniValue GatewaysMultisig(char *txidaddr);
std::string GatewaysPartialSign(uint64_t txfee,uint256 txidaddr,std::string refcoin, std::string hex);
// CCcustom
UniValue GatewaysInfo(uint256 bindtxid);

View File

@@ -14,16 +14,16 @@
******************************************************************************/
#ifndef CC_MOFN_H
#define CC_MOFN_H
#ifndef CC_HEIR_H
#define CC_HEIR_H
#include "CCinclude.h"
#define EVAL_MOFN 0xea
#define EVAL_HEIR 0xea
bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
// CCcustom
UniValue MofNInfo();
UniValue HeirInfo();
#endif

View File

@@ -17,15 +17,17 @@
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
{
char coinaddr[64],destaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
char coinaddr[64],destaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/(maxinputs!=0?maxinputs:64);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;

View File

@@ -21,7 +21,7 @@
#include "CCauction.h"
#include "CClotto.h"
#include "CCfsm.h"
#include "CCMofN.h"
#include "CCHeir.h"
#include "CCchannels.h"
#include "CCOracles.h"
#include "CCPrices.h"
@@ -133,13 +133,13 @@ uint8_t AuctionCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x
#undef FUNCNAME
#undef EVALCODE
// MofN
#define FUNCNAME IsMofNInput
#define EVALCODE EVAL_MOFN
const char *MofNCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy";
const char *MofNNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf";
char MofNCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" };
uint8_t MofNCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce };
// Heir
#define FUNCNAME IsHeirInput
#define EVALCODE EVAL_HEIR
const char *HeirCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy";
const char *HeirNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf";
char HeirCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" };
uint8_t HeirCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
@@ -282,13 +282,13 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode)
cp->validate = AuctionValidate;
cp->ismyvin = IsAuctionInput;
break;
case EVAL_MOFN:
strcpy(cp->unspendableCCaddr,MofNCCaddr);
strcpy(cp->normaladdr,MofNNormaladdr);
strcpy(cp->CChexstr,MofNCChexstr);
memcpy(cp->CCpriv,MofNCCpriv,32);
cp->validate = MofNValidate;
cp->ismyvin = IsMofNInput;
case EVAL_HEIR:
strcpy(cp->unspendableCCaddr,HeirCCaddr);
strcpy(cp->normaladdr,HeirNormaladdr);
strcpy(cp->CChexstr,HeirCChexstr);
memcpy(cp->CCpriv,HeirCCpriv,32);
cp->validate = HeirValidate;
cp->ismyvin = IsHeirInput;
break;
case EVAL_CHANNELS:
strcpy(cp->unspendableCCaddr,ChannelsCCaddr);

View File

@@ -24,11 +24,12 @@
bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds);
std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout);
std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyvout,int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout,uint256 vin0txid,int32_t vin0vout);
double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid);
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks);
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount);
UniValue DiceInfo(uint256 diceid);
UniValue DiceList();
int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbits,struct CCcontract_info *cp,CPubKey dicepk,uint256 reffundingtxid, int32_t &entropytxs,bool random);
#endif

View File

@@ -48,9 +48,12 @@ one other technical note is that komodod has the insight-explorer extensions bui
#include <univalue.h>
#include <exception>
#include "../komodo_defs.h"
#include "../utlist.h"
#include "../uthash.h"
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE;
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE,KOMODO_DEALERNODE;
extern uint32_t ASSETCHAINS_CC;
extern char ASSETCHAINS_SYMBOL[];
extern std::string CCerror;
#define SMALLVAL 0.000000000000001
@@ -97,8 +100,8 @@ int32_t is_hexstr(char *str,int32_t n);
bool myAddtomempool(CTransaction &tx);
//uint64_t myGettxout(uint256 hash,int32_t n);
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
bool mytxid_inmempool(uint256 txid);
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
bool mySendrawtransaction(std::string res);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp);
int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp);
@@ -124,7 +127,7 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
// CCutils
CPubKey buf2pk(uint8_t *buf33);
void endiancpy(uint8_t *dest,uint8_t *src,int32_t len);
uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv);
uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,int32_t usevout);
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk);
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2);
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
@@ -136,6 +139,7 @@ bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits);
uint64_t stringbits(char *str);
uint256 revuint256(uint256 txid);
bool pubkey2addr(char *destaddr,uint8_t *pubkey33);
char *uint256_str(char *dest,uint256 txid);
char *pubkey33_str(char *dest,uint8_t *pubkey33);
uint256 Parseuint256(char *hexstr);
@@ -151,7 +155,6 @@ bool PreventCC(Eval* eval,const CTransaction &tx,int32_t preventCCvins,int32_t n
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
std::vector<uint8_t> Mypubkey();
bool Myprivkey(uint8_t myprivkey[]);
bool pubkey2addr(char *destaddr,uint8_t *pubkey33);
int64_t CCduration(int32_t &numblocks,uint256 txid);
bool isCCTxNotarizedConfirmed(uint256 txid);
// CCtx

View File

@@ -17,12 +17,12 @@
/*
FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and the opreturn.
This allows the contract transaction functions to create the appropriate vins and vouts and have FinalizeCCTx create a properly signed transaction.
By using -addressindex=1, it allows tracking of all the CC addresses
*/
bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScript scriptPubKey)
{
#ifdef ENABLE_WALLET
@@ -33,15 +33,17 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
UpdateTransaction(mtx,vini,sigdata);
return(true);
} else fprintf(stderr,"signing error for SignTx vini.%d %.8f\n",vini,(double)utxovalue/COIN);
#else
return(false);
#endif
return(false);
}
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
{
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*othercond3=0,*cond; CPubKey unspendablepk;
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0;
int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64];
uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*othercond3=0,*cond; CPubKey unspendablepk;
n = mtx.vout.size();
for (i=0; i<n; i++)
{
@@ -72,11 +74,13 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
//fprintf(stderr,"vin.%d is normal %.8f\n",i,(double)utxovalues[i]/COIN);
if (ccvins==0) normalvins++;
normalinputs += utxovalues[i];
vinimask |= (1LL << i);
}
else
{
ccvins++;
mask |= (1LL << i);
}
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
@@ -92,7 +96,17 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
if ( opret.size() > 0 )
mtx.vout.push_back(CTxOut(0,opret));
PrecomputedTransactionData txdata(mtx);
n = mtx.vin.size();
n = mtx.vin.size();
//Reorder vins so that for multiple normal vins all other except vin0 goes to the end
//This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation.
if (normalvins>1)
{
for(i=1;i<normalvins;i++)
{
mtx.vin.push_back(mtx.vin[1]);
mtx.vin.erase(mtx.vin.begin() + 1);
}
}
for (i=0; i<n; i++)
{
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
@@ -123,9 +137,9 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{
//fprintf(stderr,"matched %s unspendable2!\n",cp->unspendableaddr2);
privkey = cp->unspendablepriv2;
if ( othercond2 == 0 && cp->evalcode != EVAL_CHANNELS)
if ( othercond2 == 0 && cp->evalcode != EVAL_CHANNELS && cp->evalcode != EVAL_HEIR )
othercond2 = MakeCCcond1(cp->evalcode2,cp->unspendablepk2);
else if ( othercond2 == 0 && cp->evalcode == EVAL_CHANNELS)
else if ( othercond2 == 0 && (cp->evalcode == EVAL_CHANNELS || cp->evalcode == EVAL_HEIR) )
othercond2 = MakeCCcond1of2(cp->evalcode2,cp->unspendablepk2,cp->unspendablepk3);
cond = othercond2;
}
@@ -160,7 +174,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
}
}
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
}
}
if ( mycond != 0 )
cc_free(mycond);
if ( othercond != 0 )
@@ -276,6 +290,11 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
abovei = belowi = -1;
for (above=below=i=0; i<numunspents; i++)
{
// Filter to randomly pick utxo to avoid conflicts, and having multiple CC choose the same ones.
//if ( numunspents > 200 ) {
// if ( (rand() % 100) < 90 )
// continue;
//}
if ( (atx_value= utxos[i].nValue) <= 0 )
continue;
if ( atx_value == value )
@@ -322,21 +341,26 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
{
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=1024; int64_t above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=64; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
#ifdef ENABLE_WALLET
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL);
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
threshold = total/maxinputs;
if ( maxinputs > maxutxos )
maxutxos = maxinputs;
sum = 0;
BOOST_FOREACH(const COutput& out, vecOutputs)
{
if ( out.fSpendable != 0 )
if ( out.fSpendable != 0 && out.tx->vout[out.i].nValue >= threshold )
{
txid = out.tx->GetHash();
vout = out.i;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && vout < tx.vout.size() && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() == 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && vout < tx.vout.size() && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
//fprintf(stderr,"check %.8f to vins array.%d of %d %s/v%d\n",(double)out.tx->vout[out.i].nValue/COIN,n,maxutxos,txid.GetHex().c_str(),(int32_t)vout);
if ( mtx.vin.size() > 0 )
{
for (i=0; i<mtx.vin.size(); i++)
@@ -359,8 +383,9 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
up->txid = txid;
up->nValue = out.tx->vout[out.i].nValue;
up->vout = vout;
sum += up->nValue;
//fprintf(stderr,"add %.8f to vins array.%d of %d\n",(double)up->nValue/COIN,n,maxutxos);
if ( n >= maxutxos )
if ( n >= maxutxos || sum >= total )
break;
}
}

View File

@@ -74,6 +74,7 @@ CC* GetCryptoCondition(CScript const& scriptSig)
std::vector<unsigned char> ffbin;
if (scriptSig.GetOp(pc, opcode, ffbin))
return cc_readFulfillmentBinary((uint8_t*)ffbin.data(), ffbin.size()-1);
else return(0);
}
bool IsCCInput(CScript const& scriptSig)
@@ -193,7 +194,7 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
return(true);
}
fprintf(stderr,"ExtractDestination failed\n");
//fprintf(stderr,"ExtractDestination failed\n");
return(false);
}
@@ -385,12 +386,12 @@ int64_t CCduration(int32_t &numblocks,uint256 txid)
numblocks = 0;
if ( myGetTransaction(txid,tx,hashBlock) == 0 )
{
fprintf(stderr,"CCduration cant find duration txid %s\n",uint256_str(str,txid));
//fprintf(stderr,"CCduration cant find duration txid %s\n",uint256_str(str,txid));
return(0);
}
else if ( hashBlock == zeroid )
{
fprintf(stderr,"CCduration no hashBlock for txid %s\n",uint256_str(str,txid));
//fprintf(stderr,"CCduration no hashBlock for txid %s\n",uint256_str(str,txid));
return(0);
}
else if ( (pindex= mapBlockIndex[hashBlock]) == 0 || (txtime= pindex->nTime) == 0 || (txheight= pindex->nHeight) <= 0 )
@@ -400,7 +401,8 @@ int64_t CCduration(int32_t &numblocks,uint256 txid)
}
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nTime < txtime || pindex->nHeight <= txheight )
{
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->nHeight);
if ( pindex->nTime < txtime )
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->nHeight);
return(0);
}
numblocks = (pindex->nHeight - txheight);

View File

@@ -249,8 +249,8 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
}
fprintf(stderr,"fillbuy validated\n");
break;
case 'e': // selloffer
break; // disable swaps
//case 'e': // selloffer
// break; // disable swaps
case 's': // selloffer
//vin.0: normal input
//vin.1+: valid CC output for sale
@@ -322,6 +322,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
fprintf(stderr,"fill validated\n");
break;
case 'E': // fillexchange
return eval->Invalid("unexpected assets fillexchange funcid");
break; // disable asset swaps
//vin.0: normal input
//vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0]
@@ -371,6 +372,10 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
}
fprintf(stderr,"fill validated\n");
break;
default:
fprintf(stderr,"illegal assets funcid.(%c)\n",funcid);
return eval->Invalid("unexpected assets funcid");
break;
}
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}

View File

@@ -120,6 +120,7 @@ bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -64,7 +64,7 @@ Possible third iteration:
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub, CPubKey destpub,int32_t v)
{
char destaddr[64],channeladdr[64];
char destaddr[65],channeladdr[65];
GetCCaddress1of2(cp,channeladdr,srcpub,destpub);
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -77,7 +77,7 @@ int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
{
char destaddr[64],ccaddr[64];
char destaddr[65],ccaddr[65];
GetCCaddress(cp,ccaddr,srcpub);
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -348,8 +348,12 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
return eval->Invalid("invalid amount, refund amount and funds in channel must match!");
}
break;
default:
fprintf(stderr,"illegal channels funcid.(%c)\n",funcid);
return eval->Invalid("unexpected channels funcid");
break;
}
}
} else return eval->Invalid("unexpected channels missing funcid");
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"Channel tx validated\n");
@@ -364,7 +368,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, CTransaction openTx, uint256 &prevtxid)
{
char coinaddr[64]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
char coinaddr[65]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
CPubKey srcpub,destpub;
uint8_t myprivkey[32];
@@ -442,7 +446,7 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
funds = numpayments * payment;
if ( AddNormalinputs(mtx,mypk,funds+3*txfee,64) > 0 )
{
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
endiancpy(hash,(uint8_t *)&hentropy,32);
for (i=0; i<numpayments; i++)
{
@@ -522,7 +526,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
}
else
{
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy,channelOpenTx.vin[0].prevout.hash,channelOpenTx.vin[0].prevout.n,1);
if (prevdepth-numpayments)
{
endiancpy(hash, (uint8_t * ) & hentropy, 32);
@@ -661,7 +665,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 &&
DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3) != 0)
{
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash, channelOpenTx.vin[0].prevout.n,1);
endiancpy(hash, (uint8_t * ) & hentropy, 32);
for (i = 0; i < param1; i++)
{
@@ -692,7 +696,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
UniValue ChannelsInfo(uint256 channeltxid)
{
UniValue result(UniValue::VOBJ); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid;
struct CCcontract_info *cp,C; char myCCaddr[64],addr[64],str1[256],str2[64]; int32_t vout,numvouts,param1,numpayments;
struct CCcontract_info *cp,C; char myCCaddr[65],addr[65],str1[512],str2[256]; int32_t vout,numvouts,param1,numpayments;
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
@@ -768,4 +772,4 @@ UniValue ChannelsInfo(uint256 channeltxid)
}
}
return(result);
}
}

6
src/cc/dapps/diceloop Executable file
View File

@@ -0,0 +1,6 @@
while true
do
./c dicestatus KMDICE 5be49570c56d036abb08b6d084da93a8a86f58fc48db4a1086be95540d752d6f
sleep 10
done

View File

@@ -19,6 +19,8 @@
#include <memory.h>
#include "cJSON.c"
bits256 zeroid;
char hexbyte(int32_t c)
{
c &= 0xf;
@@ -139,7 +141,7 @@ long _stripwhite(char *buf,int accept)
char *clonestr(char *str)
{
char *clone;
if ( str == 0 || str[0] == 0 )
if ( str == 0 || str[0]==0)
{
printf("warning cloning nullstr.%p\n",str);
//#ifdef __APPLE__
@@ -330,7 +332,8 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char
system(cmdstr);
*retstrp = 0;
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
{
{
jsonstr[strlen(jsonstr)-1]='\0';
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
*retstrp = jsonstr;
@@ -357,7 +360,7 @@ bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson)
retstr[64] = 0;
decode_hex(txid.bytes,32,retstr);
}
fprintf(stderr,"broadcast %s txid.(%s)\n",acname,bits256_str(str,txid));
fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid));
free(retstr);
}
}
@@ -530,6 +533,23 @@ cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid)
return(0);
}
int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare)
{
cJSON *retjson; char *retstr; int32_t res=0;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 )
{
if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1;
free_json(retjson);
}
else if ( retstr != 0 )
{
fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
free(retstr);
}
return (res);
}
void importaddress(char *refcoin,char *acname,char *depositaddr)
{
cJSON *retjson; char *retstr;
@@ -545,6 +565,24 @@ void importaddress(char *refcoin,char *acname,char *depositaddr)
}
}
void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys,char *bindtxidstr)
{
cJSON *retjson; char *retstr,Mstr[10],tmp[128];
sprintf(Mstr,"%d",M);
sprintf(tmp,"\"%s\"",bindtxidstr);
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"addmultisigaddress",Mstr,pubkeys,tmp,"")) != 0 )
{
fprintf(stderr,"unexpected addmultisigaddress json.(%s)\n",jprint(retjson,0));
free(retstr);
}
else if ( retstr != 0 )
{
printf("addmultisigaddress.(%s)\n",retstr);
free_json(retjson);
}
}
cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required)
{
cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid;
@@ -584,7 +622,7 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
return(0);
}
satoshis -= txfee;
sprintf(array,"[\"%s\"]",depositaddr);
sprintf(array,"\'[\"%s\"]\'",depositaddr);
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 )
{
//createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
@@ -599,9 +637,12 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
change = (total - satoshis);
jaddnum(vouts,depositaddr,(double)change/SATOSHIDEN);
}
char *argA,*argB;
argA = jprint(vins,1);
argB = jprint(vouts,1);
char *tmpA=jprint(vins,1);
char *tmpB=jprint(vouts,1);
char *argA=malloc(sizeof(char) * (strlen(tmpA)+3));
char *argB=malloc(sizeof(char) * (strlen(tmpB)+3));
sprintf(argA,"\'%s\'",tmpA);
sprintf(argB,"\'%s\'",tmpB);
if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
{
printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0));
@@ -609,10 +650,13 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
}
else if ( txstr == 0 )
printf("createmultisig: null txstr and JSON2\n");
free(tmpA);
free(tmpB);
free(argA);
free(argB);
}
}
free_json(retjson);
}
else if ( retstr != 0 )
{
@@ -628,7 +672,7 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
char *retstr,*hexstr; cJSON *retjson;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 )
{
if ( jint(retjson,"complete") != 0 )
if ( is_cJSON_True(jobj(retjson,"complete")) != 0 )
return(retjson);
else if ( (hexstr= jstr(retjson,"hex")) != 0 && strlen(hexstr) > strlen(rawtx) )
{
@@ -640,18 +684,36 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
return(0);
}
char *get_gatewaysmultisig(char *refcoin,char *acname,char *bindtxidstr,char *withtxidstr,char *txidaddr)
char *get_gatewaysmultisig(char *refcoin,char *acname,char *txidaddr,int32_t *K)
{
char *retstr,*hexstr,*hex=0; cJSON *retjson;
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",bindtxidstr,refcoin,withtxidstr,txidaddr)) != 0 )
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",txidaddr,"","","")) != 0 )
{
if ( (hexstr= jstr(retjson,"hex")) != 0 )
hex = clonestr(hexstr);
if ((hexstr=jstr(retjson,"hex")) != 0 )
{
if (strlen(hexstr)>0) hex = clonestr(hexstr);
}
*K=jint(retjson,"number_of_signs");
free_json(retjson);
}
return(hex);
}
bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *hex)
{
char str[65],*retstr; cJSON *retjson;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspartialsign",bits256_str(str,txid),refcoin,hex,"")) != 0 )
{
return(komodobroadcast(refcoin,acname,retjson));
}
else if ( retstr != 0 )
{
printf("error parsing gatewayspartialsing.(%s)\n",retstr);
free(retstr);
}
return (zeroid);
}
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid)
{
char str[65],str2[65],*retstr; cJSON *retjson;
@@ -668,9 +730,9 @@ void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bit
}
}
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr)
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr, char **pubkeys)
{
char *oracle,*retstr,*name,*deposit; cJSON *retjson;
char *oracle,*retstr,*name,*deposit,temp[128]; cJSON *retjson,*pubarray; int32_t n;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 )
{
if ( (oracle= jstr(retjson,"oracletxid")) != 0 && strcmp(oracle,oraclestr) == 0 && (deposit= jstr(retjson,"deposit")) != 0 )
@@ -680,9 +742,23 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
{
*Mp = jint(retjson,"M");
*Np = jint(retjson,"N");
//printf("(%s)\n",jprint(retjson,0));
} else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
} else printf("%s != %s\n",oracle,oraclestr);
}
else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
if ((pubarray=jarray(&n,retjson,"pubkeys"))!=0)
{
*pubkeys=malloc((sizeof(char)*70*n)+64);
sprintf(*pubkeys,"\"[");
for (int i=0;i<n;i++)
{
sprintf(temp,"\\\"%s\\\"",jstri(pubarray,i));
if (i<n-1) strcat(temp,",");
strcat(*pubkeys,temp);
}
sprintf(temp,"]\"");
strcat(*pubkeys,temp);
}
}
else printf("%s != %s\n",oracle,oraclestr);
free_json(retjson);
}
else if ( retstr != 0 )
@@ -697,15 +773,14 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
{
cJSON *txobj,*vouts,*vout,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numvouts,retval = 0;
cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0;
if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 )
{
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 )
if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 )
{
for (i=0; i<numvouts; i++)
{
vout = jitem(vouts,i);
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 )
for (i=0; i<numarray; i++)
{
if ((vout = jitem(vouts,i)) !=0 && (sobj= jobj(vout,"scriptPubKey")) != 0 )
{
if ( (addresses= jarray(&n,sobj,"addresses")) != 0 )
{
@@ -715,26 +790,55 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd
if ( strcmp(addr,coinaddr) == 0 )
{
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
retval = 1;
hasvout = 1;
break;
}
}
}
}
if (hasvout==1) break;
}
}
// if (hasvout==1 && (vins=jarray(&numarray,txobj,"vin"))!=0)
// {
// for (int i=0;i<numarray;i++)
// {
// if ((vin=jitem(vins,i))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
// {
// retval=1;
// break;
// }
// }
// }
free_json(txobj);
}
return(retval);
return(hasvout);
}
int32_t coinaddrexists(char *refcoin,char *acname,char *coinaddr)
int32_t markerfromthisnodeorunconfirmed(char *refcoin,char *acname,char *coinaddr)
{
cJSON *array; bits256 txid; int32_t i,n,num=0;
cJSON *array,*item,*rawtx,*vins,*vin; bits256 txid,tmptxid; int32_t i,n,m,num=0; char *retstr;
if ( (array= get_addressutxos(refcoin,acname,coinaddr)) != 0 )
{
num = cJSON_GetArraySize(array);
free_json(array);
} else return(-1);
n=cJSON_GetArraySize(array);
for (i=0; i<n; i++)
{
if ((item=jitem(array,i))!=0 && (bits256_nonz(tmptxid=jbits256(item,"txid")))!=0 && (rawtx=get_rawtransaction(refcoin,acname,tmptxid))!=0 && (vins=jarray(&m,rawtx,"vin"))!=0)
{
for (int j=0;j<m;j++)
{
if ((vin=jitem(vins,j))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
{
num=1;
break;
}
}
}
if (num==1) break;
}
free_json(array);
}
else return(-1);
if ( num == 0 )
{
if ( (array= get_rawmempool(refcoin,acname)) != 0 )
@@ -753,7 +857,7 @@ int32_t coinaddrexists(char *refcoin,char *acname,char *coinaddr)
}
free_json(array);
} else return(-1);
}
}
return(num);
}
@@ -766,7 +870,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
/// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
/// if not enough sigs, post partially signed to acname with marker2
// monitor marker2, for the partially signed withdraws
cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,retval,processed = 0; bits256 txid,cointxid,origtxid,zeroid; int64_t satoshis;
cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,K,retval,processed = 0; bits256 txid,cointxid,origtxid; int64_t satoshis;
memset(&zeroid,0,sizeof(zeroid));
if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 )
{
@@ -783,17 +887,16 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
//process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
if ( (txidaddr= jstr(item,"txidaddr")) != 0 && (withdrawaddr= jstr(item,"withdrawaddr")) != 0 && (depositaddr= jstr(item,"depositaddr")) != 0 && (signeraddr= jstr(item,"signeraddr")) != 0 )
{
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && (retval= coinaddrexists("KMD",acname,txidaddr)) == 0 )
{
// this is less errors but more expensive: ./komodo-cli z_sendmany "signeraddr" '[{"address":"<txidaddr>","amount":0.0001},{"address":"<withdrawaddr>","amount":<withamount>}]'
txid = sendtoaddress("KMD",acname,txidaddr,10000);
if ( bits256_nonz(txid) != 0 && coinaddrexists("KMD",acname,txidaddr) > 0 )
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && markerfromthisnodeorunconfirmed("KMD",acname,txidaddr) == 0)
{
// the actual withdraw
if ( strcmp(depositaddr,signeraddr) == 0 )
{
// the actual withdraw
if ( strcmp(depositaddr,signeraddr) == 0 )
txid= sendtoaddress("KMD",acname,txidaddr,10000);
if (bits256_nonz(txid) != 0)
{
cointxid = sendtoaddress(refcoin,"",withdrawaddr,satoshis);
if ( bits256_nonz(cointxid) != 0 )
if ( bits256_nonz(cointxid) != 0)
{
fprintf(stderr,"withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
@@ -806,42 +909,40 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
}
else
{
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,bindtxidstr,bits256_str(str,origtxid),txidaddr)) == 0 )
{
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
}
if ( rawtx != 0 )
{
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
{
if ( jint(clijson,"complete") != 0 )
{
cointxid = komodobroadcast(refcoin,"",clijson);
if ( bits256_nonz(cointxid) != 0 )
{
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
}
}
else if ( jint(clijson,"partialtx") != 0 )
{
// 10000 + ith -> txidaddr
txid = komodobroadcast("KMD",acname,clijson);
fprintf(stderr,"%s M.%d of N.%d partialtx %s sent\n",refcoin,M,N,bits256_str(str,txid));
}
free_json(clijson);
}
processed++;
free(rawtx);
} else fprintf(stderr,"couldnt create msig rawtx\n");
fprintf(stderr,"ERROR sending withdraw marker %s %s to %s %.8f processed\n",refcoin,bits256_str(str,cointxid),txidaddr,(double)10000/SATOSHIDEN);
}
}
}
else if ( retval > 0 )
{
fprintf(stderr,"already did withdraw %s %s %.8f processed\n",refcoin,withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,zeroid);
}
else
{
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,txidaddr,&K)) == 0)
{
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
}
if ( rawtx != 0 )
{
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
{
if ( is_cJSON_True(jobj(clijson,"complete")) != 0 )
{
cointxid = komodobroadcast(refcoin,"",clijson);
if ( bits256_nonz(cointxid) != 0 )
{
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
}
}
else if ( jint(clijson,"partialtx") != 0 )
{
txid=gatewayspartialsign(refcoin,acname,origtxid,jstr(clijson,"hex"));
fprintf(stderr,"%d of %d partialtx %s sent\n",K+1,N,bits256_str(str,txid));
}
free_json(clijson);
}
processed++;
free(rawtx);
} else fprintf(stderr,"couldnt create msig rawtx\n");
}
}
}
}
}
@@ -907,7 +1008,7 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
int32_t main(int32_t argc,char **argv)
{
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *pubkeys,*format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
if ( argc < 6 )
{
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
@@ -943,12 +1044,18 @@ int32_t main(int32_t argc,char **argv)
printf("need to specify path to refcoin's cli as last argv\n");
exit(0);
}
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr) < 0 )
pubkeys=0;
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) < 0 )
{
printf("cant find bindtxid.(%s)\n",bindtxidstr);
exit(0);
}
importaddress(refcoin,"",depositaddr);
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0)
{
if (M==N==1) importaddress(refcoin,"",depositaddr);
else addmultisigaddress(refcoin,"",M,pubkeys,bindtxidstr);
}
if (pubkeys!=0) free(pubkeys);
printf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
}
if ( (regjson= jarray(&n,clijson,"registered")) != 0 )

3
src/cc/dapps/sendmany Executable file
View File

@@ -0,0 +1,3 @@
export addr="RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo"
./komodo-cli -ac_name=KMDICE sendmany "" "{\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023}"

2
src/cc/dapps/sendmany100 Executable file
View File

@@ -0,0 +1,2 @@
./komodo-cli -ac_name=KMDICE sendmany "" "{\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002}"

File diff suppressed because it is too large Load Diff

View File

@@ -76,11 +76,11 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
case EVAL_IMPORTPAYOUT:
return ImportPayout(vparams, txTo, nIn);
break;
case EVAL_IMPORTCOIN:
return ImportCoin(vparams, txTo, nIn);
break;
default:
return(ProcessCC(cp,this, vparams, txTo, nIn));
break;
@@ -98,10 +98,9 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) c
bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
{
// there is a LOCK(cs_main) in the normal GetTransaction(), which leads to deadlocks
//bool fAllowSlow = false; // Don't allow slow
//return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
return myGetTransaction(hash, txOut,hashBlock);
if (!myGetTransaction(hash, txOut,hashBlock)) {
return(GetTransaction(hash, txOut,hashBlock));
} else return(true);
}
@@ -115,7 +114,6 @@ bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex
return true;
}
unsigned int Eval::GetCurrentHeight() const
{
return chainActive.Height();

View File

@@ -47,7 +47,7 @@
EVAL(EVAL_FSM, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9) \
EVAL(EVAL_MOFN, 0xea) \
EVAL(EVAL_HEIR, 0xea) \
EVAL(EVAL_CHANNELS, 0xeb) \
EVAL(EVAL_ORACLES, 0xec) \
EVAL(EVAL_PRICES, 0xed) \

View File

@@ -142,14 +142,17 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/maxinputs;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
//char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )

View File

@@ -122,6 +122,7 @@ bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -143,7 +143,7 @@
*/
int32_t GatewaysAddQueue(std::string coin,uint256 txid,CScript scriptPubKey,int64_t nValue)
void GatewaysAddQueue(std::string coin,uint256 txid,CScript scriptPubKey,int64_t nValue)
{
char destaddr[64],str[65];
Getscriptaddress(destaddr,scriptPubKey);
@@ -178,6 +178,41 @@ uint8_t DecodeGatewaysOpRet(const CScript &scriptPubKey,std::string &coin,uint25
return(0);
}
uint8_t DecodeGatewaysPartialOpRet(const CScript &scriptPubKey,int32_t &K, CPubKey &signerpk, std::string &coin,std::string &hex)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> K; ss >> signerpk; ss >> coin; ss >> hex) != 0 )
{
return(f);
}
return(0);
}
uint8_t DecodeGatewaysWithdrawOpRet(const CScript &scriptPubKey, uint256 &assetid, std::string &refcoin, CPubKey &withdrawpub, int64_t &amount)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> refcoin; ss >> withdrawpub; ss >> amount) != 0 )
{
return(f);
}
return(0);
}
uint8_t DecodeGatewaysMarkdoneOpRet(const CScript &scriptPubKey, std::string &refcoin, uint256 &cointxid)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> refcoin; ss >> cointxid) != 0 )
{
return(f);
}
return(0);
}
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,std::string &coin,uint256 &tokenid,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &pubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
@@ -297,15 +332,18 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 refassetid,int64_t total,int32_t maxinputs)
{
char coinaddr[64],destaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 assetid,txid,hashBlock; std::vector<uint8_t> origpubkey; std::vector<uint8_t> vopret; CTransaction vintx; int32_t j,vout,n = 0; uint8_t evalcode,funcid;
char coinaddr[64],destaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 assetid,txid,hashBlock; std::vector<uint8_t> origpubkey; std::vector<uint8_t> vopret; CTransaction vintx; int32_t j,vout,n = 0; uint8_t evalcode,funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/maxinputs;
fprintf(stderr,"check %s for gateway inputs\n",coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
@@ -763,9 +801,11 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
return("");
}
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount)
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount)
{
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64];
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C;
uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin;
std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; CScript opret;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
@@ -788,11 +828,12 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
if ( inputs > amount )
CCchange = (inputs - amount);
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,txfee,gatewayspk));
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,mypk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'W' << assetid << refcoin << withdrawpub << amount);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
}
fprintf(stderr,"cant find enough inputs or mismatched total\n");
@@ -806,6 +847,7 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
if ( txfee == 0 )
txfee = 5000;
mypk = pubkey2pk(Mypubkey());
mtx.vin.push_back(CTxIn(withdrawtxid,2,CScript()));
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'M' << cointxid << refcoin);
@@ -814,8 +856,12 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),pending(UniValue::VARR),obj(UniValue::VOBJ); CTransaction tx; std::string coin; CPubKey mypk,gatewayspk; std::vector<CPubKey> msigpubkeys; uint256 hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2; char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64]; int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply; struct CCcontract_info *cp,C;
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,tmprefcoin; CPubKey mypk,gatewayspk,withdrawpub; std::vector<CPubKey> msigpubkeys;
uint256 cointxid,hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2;
char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64];
int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply,amount,nValue; struct CCcontract_info *cp,C;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
@@ -837,20 +883,23 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
{
queueflag = 1;
break;
}
Getscriptaddress(withmarker,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG);
SetCCunspents(unspentOutputs,withmarker);
}
SetCCunspents(unspentOutputs,coinaddr);
numqueued = 0;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 )
nValue = (int64_t)it->second.satoshis;
fprintf(stderr,"%s %d %ld\n",txid.ToString().c_str(),vout,(long)nValue);
if ( vout == 2 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) &&
DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,tmprefcoin,withdrawpub,amount) == 'W' && myIsutxo_spentinmempool(txid,vout) == 0)
{
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
Getscriptaddress(withaddr,tx.vout[1].scriptPubKey);
if ( strcmp(destaddr,coinaddr) == 0 )
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("txid",uint256_str(str,txid)));
CCtxidaddr(txidaddr,txid);
obj.push_back(Pair("txidaddr",txidaddr));
@@ -873,31 +922,72 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
return(result);
}
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr)
UniValue GatewaysMultisig(char *txidaddr)
{
UniValue result(UniValue::VOBJ); std::string coin,hex; char str[67],numstr[65],depositaddr[64],gatewaysassets[64]; uint8_t M,N; std::vector<CPubKey> pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CPubKey Gatewayspk,mypk; struct CCcontract_info *cp,C; int32_t i,n,complete,partialtx; int64_t totalsupply;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
complete = partialtx = 0;
mypk = pubkey2pk(Mypubkey());
Gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(gatewaysassets,EVAL_GATEWAYS,Gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
std::string parthex,hex,refcoin; uint256 txid,hashBlock; CTransaction tx; int32_t i,maxK,K,numvouts; CPubKey signerpk;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; UniValue result(UniValue::VOBJ);
SetCCunspents(unspentOutputs,txidaddr);
maxK=0;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
depositaddr[0] = 0;
if ( tx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,tx.vout[tx.vout.size()-1].scriptPubKey,coin,tokenid,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 0 && M <= N && N > 1 && coin == refcoin )
txid = it->first.txhash;
if (GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
{
// need a decentralized way to add signatures to msig tx
n = pubkeys.size();
for (i=0; i<n; i++)
if ( mypk == pubkeys[i] )
break;
if ( i != n )
{
hex = "";
} else fprintf(stderr,"not one of the multisig signers\n");
maxK=K;
parthex=hex;
}
}
return(hex);
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
{
const CTransaction &txmempool = e.GetTx();
const uint256 &hash = txmempool.GetHash();
if ((numvouts=txmempool.vout.size()) > 0 && DecodeGatewaysPartialOpRet(txmempool.vout[numvouts-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK)
{
maxK=K;
parthex=hex;
}
}
result.push_back(Pair("hex",parthex));
result.push_back(Pair("number_of_signs",maxK));
return (result);
}
std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string hex)
{
CMutableTransaction mtx; CScript opret; CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; char txidaddr[65];
int32_t maxK,K=0; uint256 tmptxid,parttxid,hashBlock;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 5000;
mypk = pubkey2pk(Mypubkey());
txidaddrpk=CCtxidaddr(txidaddr,txid);
SetCCunspents(unspentOutputs,txidaddr);
maxK=0;
if (unspentOutputs.size()==0)
{
if (AddNormalinputs(mtx,mypk,2*txfee,2)==0) fprintf(stderr,"error adding funds for partialsign\n");
}
else
{
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
tmptxid = it->first.txhash;
if (GetTransaction(tmptxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
{
maxK=K;
parttxid=tmptxid;
}
}
if (maxK>0) mtx.vin.push_back(CTxIn(parttxid,0,CScript()));
else fprintf(stderr,"Error finding previous partial tx\n");
}
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(txidaddrpk)) << OP_CHECKSIG));
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'P' << maxK+1 << mypk << refcoin << hex);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}

View File

@@ -13,30 +13,16 @@
* *
******************************************************************************/
#include "CCMofN.h"
#include "CCHeir.h"
/*
The idea of MofN CC is to allow non-interactive multisig, preferably in a cross chain compatible way, ie. for actual bitcoin multisig.
full redeemscript in an initial tx with opreturn
ability to post partial signatures and construct a full transaction from M such partial signatures
a new transaction would refer to the initialtx and other partial would refer to both
There is no need for a CC contract to use it for normal multisig as normal multisig transactions are already supported.
In order to take advantage of CC powers, we can create a more powerful multisig using shamir's secret MofN (up to 255) algo to allow spends. Using the same non-interactive partial signing is possible. also, in addition to spending, data payload can have additional data that is also revealed when the funds are spent.
rpc calls needed:
1) create msig address (normal or shamir)
2) post payment with partial sig
3) add partial sig to 2)
4) combine and submit M partial sigs
The idea of Heir CC is to allow crypto inheritance.
A special 1of2 CC address is created that is freely spendable by the creator. The heir is only allowed to spend after the specified amount of idle blocks. The idea is that if the address doesnt spend any funds for a year (or whatever amount set), then it is time to allow the heir to spend. The design requires the heir to spend all the funds at once
*/
// start of consensus code
int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
int64_t IsHeirvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -47,7 +33,7 @@ int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
return(0);
}
bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
bool HeirExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
@@ -65,8 +51,8 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant MofN from mempool");
if ( (assetoshis= IsMofNvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
return eval->Invalid("cant Heir from mempool");
if ( (assetoshis= IsHeirvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
@@ -74,7 +60,7 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsMofNvout(cp,tx,i)) != 0 )
if ( (assetoshis= IsHeirvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+txfee )
@@ -85,7 +71,7 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
else return(true);
}
bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
return(false);
@@ -105,9 +91,9 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
}
}
//fprintf(stderr,"check amounts\n");
if ( MofNExactAmounts(cp,eval,tx,1,10000) == false )
if ( HeirExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"mofnget invalid amount\n");
fprintf(stderr,"Heirget invalid amount\n");
return false;
}
else
@@ -116,8 +102,8 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
memcpy(hash,&txid,sizeof(hash));
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"mofnget validated\n");
else fprintf(stderr,"mofnget invalid\n");
fprintf(stderr,"Heirget validated\n");
else fprintf(stderr,"Heirget invalid\n");
return(retval);
}
}
@@ -126,8 +112,9 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
// helper functions for rpc calls in rpcwallet.cpp
int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
int64_t AddHeirInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
@@ -139,7 +126,7 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsMofNvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsHeirvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
@@ -154,27 +141,27 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
return(totalinputs);
}
std::string MofNGet(uint64_t txfee,int64_t nValue)
std::string HeirGet(uint64_t txfee,int64_t nValue)
{
CMutableTransaction mtx,tmpmtx; CPubKey mypk,mofnpk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
cp = CCinit(&C,EVAL_MOFN);
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Heirpk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
cp = CCinit(&C,EVAL_HEIR);
if ( txfee == 0 )
txfee = 10000;
mofnpk = GetUnspendable(cp,0);
Heirpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,nValue+txfee,60)) > 0 )
if ( (inputs= AddHeirInputs(cp,mtx,Heirpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,CCchange,mofnpk));
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR,CCchange,Heirpk));
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
j = rand() & 0xfffffff;
for (i=0; i<1000000; i++,j++)
{
tmpmtx = mtx;
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_MOFN << (uint8_t)'G' << j));
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'G' << j));
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
{
len >>= 1;
@@ -190,35 +177,35 @@ std::string MofNGet(uint64_t txfee,int64_t nValue)
}
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
return("");
} else fprintf(stderr,"cant find mofn inputs\n");
} else fprintf(stderr,"cant find Heir inputs\n");
return("");
}
std::string MofNFund(uint64_t txfee,int64_t funds)
std::string HeirFund(uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx; CPubKey mypk,mofnpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_MOFN);
CMutableTransaction mtx; CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_HEIR);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mofnpk = GetUnspendable(cp,0);
Heirpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,funds,mofnpk));
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR,funds,Heirpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return("");
}
UniValue MofNInfo()
UniValue HeirInfo()
{
UniValue result(UniValue::VOBJ); char numstr[64];
CMutableTransaction mtx; CPubKey mofnpk; struct CCcontract_info *cp,C; int64_t funding;
CMutableTransaction mtx; CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
result.push_back(Pair("result","success"));
result.push_back(Pair("name","MofN"));
cp = CCinit(&C,EVAL_MOFN);
mofnpk = GetUnspendable(cp,0);
funding = AddMofNInputs(cp,mtx,mofnpk,0,0);
result.push_back(Pair("name","Heir"));
cp = CCinit(&C,EVAL_HEIR);
Heirpk = GetUnspendable(cp,0);
funding = AddHeirInputs(cp,mtx,Heirpk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr));
return(result);

View File

@@ -162,6 +162,7 @@ bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
@@ -291,10 +292,11 @@ std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t tic
sbits = stringbits(planstr);
if ( AddNormalinputs(mtx,mypk,funding+txfee,60) > 0 )
{
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,funding,lottopk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_LOTTO << (uint8_t)'F' << sbits << ticketsize << odds << firstheight << period << hentropy)));
}
return("");
}
std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets)

View File

@@ -133,10 +133,11 @@ uint8_t DecodeOraclesOpRet(const CScript &scriptPubKey,uint256 &oracletxid,CPubK
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey,vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 1 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> oracletxid; ss >> pk; ss >> num) != 0 )
if ( vopret.size() > 1 && script[0] == EVAL_ORACLES )
{
if ( e == EVAL_ORACLES && (f == 'R' || f == 'S') )
if (script[0] == EVAL_ORACLES && (script[1]== 'R' || script[1] == 'S') && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> oracletxid; ss >> pk; ss >> num)!=0)
return(f);
else return(script[1]);
}
return(0);
}
@@ -440,6 +441,7 @@ int64_t correlate_price(int32_t height,int64_t *prices,int32_t n)
for (i=0; i<n; i++)
fprintf(stderr,"%llu ",(long long)prices[i]);
fprintf(stderr,"-> %llu ht.%d\n",(long long)price,height);
return(price);
}
int64_t OracleCorrelatedPrice(int32_t height,std::vector <int64_t> origprices)
@@ -566,9 +568,6 @@ bool OraclesDataValidate(struct CCcontract_info *cp,Eval* eval,const CTransactio
}
}
}
else if ( i != 0 )
return eval->Invalid("vin0 not normal");
}
for (i=0; i<numvouts; i++)
{
@@ -650,8 +649,12 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
}
return eval->Invalid("unexpected OraclesValidate 'D' tx invalid");
break;
default:
fprintf(stderr,"illegal oracles funcid.(%c)\n",script[1]);
return eval->Invalid("unexpected OraclesValidate funcid");
break;
}
}
} else return eval->Invalid("unexpected oracles missing funcid");
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}
return(true);
@@ -660,10 +663,10 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
// helper functions for rpc calls in rpcwallet.cpp
int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,uint256 oracletxid,CPubKey pk,int64_t total,int32_t maxinputs)
{
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
char coinaddr[64],funcid; int64_t nValue,price,totalinputs = 0; uint256 tmporacletxid,tmpbatontxid,txid,hashBlock; std::vector<uint8_t> origpubkey,data; CTransaction vintx; int32_t numvouts,vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; CPubKey tmppk; int64_t tmpnum;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
//fprintf(stderr,"addoracleinputs from (%s)\n",coinaddr);
@@ -672,19 +675,27 @@ int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//char str[65]; fprintf(stderr,"oracle check %s/v%d\n",uint256_str(str,txid),vout);
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts=vintx.vout.size()-1)>0)
{
// get valid CC payments
if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ((funcid=DecodeOraclesOpRet(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmppk,tmpnum))!=0 && (funcid=='S' || funcid=='D'))
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} //else fprintf(stderr,"nValue %.8f or utxo memspent\n",(double)nValue/COIN);
if (funcid=='D' && DecodeOraclesData(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmpbatontxid,tmppk,data)==0)
fprintf(stderr,"invalid oraclesdata transaction \n");
else if (tmporacletxid==oracletxid)
{
// get valid CC payments
if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
nValue = it->second.satoshis;
totalinputs += nValue;
n++;
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
break;
} //else fprintf(stderr,"nValue %.8f or utxo memspent\n",(double)nValue/COIN);
}
}
} else fprintf(stderr,"couldnt find transaction\n");
}
return(totalinputs);
@@ -797,7 +808,7 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> da
if ( batontxid != zeroid ) // not impossible to fail, but hopefully a very rare event
mtx.vin.push_back(CTxIn(batontxid,1,CScript()));
else fprintf(stderr,"warning: couldnt find baton utxo %s\n",batonaddr);
if ( (inputs= AddOracleInputs(cp,mtx,mypk,datafee,60)) > 0 )
if ( (inputs= AddOracleInputs(cp,mtx,oracletxid,mypk,datafee,60)) > 0 )
{
if ( inputs > datafee )
CCchange = (inputs - datafee);
@@ -893,7 +904,7 @@ UniValue OracleInfo(uint256 origtxid)
funding = LifetimeOraclesFunds(cp,oracletxid,pk);
sprintf(numstr,"%.8f",(double)funding/COIN);
obj.push_back(Pair("lifetime",numstr));
funding = AddOracleInputs(cp,mtx,pk,0,0);
funding = AddOracleInputs(cp,mtx,oracletxid,pk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
obj.push_back(Pair("funds",numstr));
sprintf(numstr,"%.8f",(double)datafee/COIN);

View File

@@ -115,6 +115,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -122,6 +122,7 @@ bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -129,6 +129,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,uint256 tolenid,int64_t total,int32_t maxinputs)
{
// add threshold check
int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,destaddr);

View File

@@ -287,8 +287,12 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
return eval->Invalid("unlock tx vout.2 isnt 0");
preventCCvouts = 1;
break;
default:
fprintf(stderr,"illegal rewards funcid.(%c)\n",funcid);
return eval->Invalid("unexpected rewards funcid");
break;
}
}
} else return eval->Invalid("unexpected rewards missing funcid");
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}
return(true);
@@ -325,15 +329,16 @@ static uint64_t myIs_unlockedtx_inmempool(uint256 &txid,int32_t &vout,uint64_t r
// 'L' vs 'F' and 'A'
int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,uint64_t refsbits,uint256 reffundingtxid)
{
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t numblocks,j,vout,n = 0; uint8_t funcid;
char coinaddr[64],str[65]; uint64_t threshold,sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t numblocks,j,vout,n = 0; uint8_t funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/maxinputs;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < 1000000 )
if ( it->second.satoshis < threshold )
continue;
//fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
for (j=0; j<mtx.vin.size(); j++)

View File

@@ -114,6 +114,7 @@ bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
int64_t AddTriggersInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -69,6 +69,7 @@ int CurrentEpoch(int nHeight, const Consensus::Params& params) {
return idxInt;
}
}
return(0); // jl777 seems the right value to return
}
uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params) {

View File

@@ -9,8 +9,8 @@ const int CROSSCHAIN_STAKED = 3;
typedef struct CrosschainAuthority {
uint8_t notaries[64][33];
size_t size;
size_t requiredSigs;
int8_t size;
int8_t requiredSigs;
} CrosschainAuthority;
int GetSymbolAuthority(const char* symbol);

View File

@@ -42,10 +42,14 @@ bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth)
if (!seen[i]) {
if (memcmp(pk, auth.notaries[i], 33) == 0) {
seen[i] = 1;
printf("seennotary.%i\n",i);
goto found;
} else {
//printf("notary.%i is not valid!\n",i);
}
}
}
return false;
found:;
}

View File

@@ -1,9 +1,9 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -255,7 +255,8 @@ EOF
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
@@ -339,9 +340,9 @@ exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -113,7 +113,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char
errs++;
if ( fread(&MoMdepth,1,sizeof(MoMdepth),fp) != sizeof(MoMdepth) )
errs++;
if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d CCid.%u\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff);
}
else
@@ -258,7 +258,7 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long
errs++;
if ( memread(&MoMdepth,sizeof(MoMdepth),filedata,&fpos,datalen) != sizeof(MoMdepth) )
errs++;
if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d CCid.%u\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff);
}
else
@@ -811,9 +811,11 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
return;
}
//fprintf(stderr,"%s connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight);
if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || IS_STAKED_NOTARY != -1 ) {
if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 || IS_STAKED_NOTARY > -1 )
{
staked_era = STAKED_era(pindex->GetBlockTime());
if ( staked_era != lastStakedEra ) {
if ( staked_era != lastStakedEra )
{
uint8_t tmp_pubkeys[64][33];
int8_t numSN = numStakedNotaries(tmp_pubkeys,staked_era);
UpdateNotaryAddrs(tmp_pubkeys,numSN);

View File

@@ -1107,30 +1107,41 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
*/
extern int32_t ASSETCHAINS_STREAM;
uint64_t komodo_commission(const CBlock *pblock)
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
uint64_t komodo_commission(const CBlock *pblock,int32_t height)
{
int32_t i,j,n=0,txn_count; uint64_t commission,total = 0;
int32_t i,j,n=0,txn_count; int64_t nSubsidy; uint64_t commission,total = 0;
txn_count = pblock->vtx.size();
if ( ASSETCHAINS_STREAM == 0 )
{
txn_count = pblock->vtx.size();
for (i=0; i<txn_count; i++)
{
n = pblock->vtx[i].vout.size();
for (j=0; j<n; j++)
{
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
if ( i != 0 || j != 1 )
total += pblock->vtx[i].vout[j].nValue;
}
}
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
commission = ((total * ASSETCHAINS_COMMISSION) / COIN);
if ( commission < 10000 )
commission = 0;
if ( ASSETCHAINS_FOUNDERS != 0 )
{
nSubsidy = GetBlockSubsidy(height,Params().GetConsensus());
//fprintf(stderr,"ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
return((nSubsidy * ASSETCHAINS_COMMISSION) / COIN);
n = pblock->vtx[0].vout.size();
for (j=0; j<n; j++)
if ( j != 1 )
total += pblock->vtx[0].vout[j].nValue;
}
else
{
for (i=0; i<txn_count; i++)
{
n = pblock->vtx[i].vout.size();
for (j=0; j<n; j++)
{
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
if ( i != 0 || j != 1 )
total += pblock->vtx[i].vout[j].nValue;
}
}
}
}
else
{
commission = 10000;
commission = 10000;
}
return(commission);
}
@@ -1172,7 +1183,7 @@ int8_t komodo_segid(int32_t nocache,int32_t height)
return(segid);
}
int32_t komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
void komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
{
static uint8_t prevhashbuf[100]; static int32_t prevheight;
int32_t i;
@@ -1471,17 +1482,39 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
{
int64_t checktoshis=0; uint8_t *script;
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0)
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0;
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0 )
{
checktoshis = komodo_commission(pblock);
if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 )
checktoshis = komodo_commission(pblock,height);
//fprintf(stderr,"height.%d commission %.8f\n",height,(double)checktoshis/COIN);
/*if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 ) jl777: not sure why this was here
return(-1);
else if ( checktoshis != 0 )
else*/ if ( checktoshis != 0 )
{
script = (uint8_t *)pblock->vtx[0].vout[1].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
scriptlen = (int32_t)pblock->vtx[0].vout[1].scriptPubKey.size();
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
if ( ASSETCHAINS_SCRIPTPUB.size()/2 == scriptlen && scriptlen < sizeof(scripthex) )
{
decode_hex(scripthex,scriptlen,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
if ( memcmp(scripthex,script,scriptlen) == 0 )
matched = scriptlen;
}
}
else if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) == 0 )
matched = 35;
else if ( scriptlen == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG && memcmp(script+3,ASSETCHAINS_OVERRIDE_PUBKEYHASH,20) == 0 )
matched = 25;
if ( matched == 0 )
{
//int32_t i;
//for (i=0; i<25; i++)
// fprintf(stderr,"%02x",script[i]);
//fprintf(stderr," payment to wrong pubkey scriptlen.%d, scriptpub[%d]\n",scriptlen,(int32_t)ASSETCHAINS_SCRIPTPUB.size()/2);
return(-1);
}
if ( pblock->vtx[0].vout[1].nValue != checktoshis )
{
fprintf(stderr,"ht.%d checktoshis %.8f vs actual vout[1] %.8f\n",height,dstr(checktoshis),dstr(pblock->vtx[0].vout[1].nValue));
@@ -1573,13 +1606,25 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
return(-1);
}
}
if ( failed == 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
{
if ( height == 1 )
{
script = (uint8_t *)pblock->vtx[0].vout[0].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 ) {
return(-1);
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
int32_t scriptlen; uint8_t scripthex[10000];
if ( ASSETCHAINS_SCRIPTPUB.size()/2 == pblock->vtx[0].vout[0].scriptPubKey.size() && scriptlen < sizeof(scripthex) )
{
decode_hex(scripthex,scriptlen,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
if ( memcmp(scripthex,script,scriptlen) != 0 )
return(-1);
} else return(-1);
}
else
{
script = (uint8_t *)pblock->vtx[0].vout[0].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
return(-1);
}
}
else
@@ -1590,19 +1635,15 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
if ( ASSETCHAINS_STREAM != 0 && height > 128 )
{
int lasttx = ( pblock->vtx.size() -1 );
printf("ABOUT TO CHECK LAST TX: %d\n",lasttx);
if ( lasttx == 0 )
return(-1);
uint256 hash; CTransaction tx;
if (GetTransaction(pblock->vtx[lasttx].vin[0].prevout.hash,tx,hash,false))
{
printf("CHECKING THE script pubkey\n");
script = (uint8_t *)tx.vout[pblock->vtx[lasttx].vin[0].prevout.n].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 ) {
printf("THE PUBKEY IS WRONG!\n");
return(-1);
}
printf("THE PUBKEY IS RIGHT! \n");
}
}
}

View File

@@ -1380,8 +1380,9 @@ void komodo_passport_iteration()
}
if ( komodo_chainactive_timestamp() > lastinterest )
{
komodo_interestsum();
komodo_longestchain();
if ( ASSETCHAINS_SYMBOL[0] == 0 )
komodo_interestsum();
//komodo_longestchain();
lastinterest = komodo_chainactive_timestamp();
}
refsp = komodo_stateptr(symbol,dest);

View File

@@ -44,21 +44,20 @@ struct komodo_state KOMODO_STATES[34];
#define _COINBASE_MATURITY 100
int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,IS_STAKED_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,IS_STAKED_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1,KOMODO_DEALERNODE,KOMODO_EXTRASATOSHI;
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;
std::string ASSETCHAINS_OVERRIDE_ADDRESS,NOTARY_ADDRESS,NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,WHITELIST_ADDRESS;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,NUM_NOTARIES;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,WHITELIST_ADDRESS;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,NUM_NOTARIES,ASSETCHAINS_FOUNDERS;
char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096],NOTARYADDRS[64][36];
uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1;
uint32_t ASSETCHAINS_MAGIC = 2387029918;
uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE;
uint64_t ASSETCHAINS_FOUNDERS_REWARD,ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS;
uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS;
uint32_t KOMODO_INITDONE;
char KMDUSERPASS[8192],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771;
char KMDUSERPASS[8192+512+1],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771;
uint64_t PENDING_KOMODO_TX;
extern int32_t KOMODO_LOADINGBLOCKS;
unsigned int MAX_BLOCK_SIGOPS = 20000;

View File

@@ -1520,7 +1520,8 @@ void komodo_args(char *argv0)
fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n");
DONATION_PUBKEY = GetArg("-donation", "");
NOTARY_PUBKEY = GetArg("-pubkey", "");
if ( strlen(NOTARY_PUBKEY.c_str()) == 66 )
KOMODO_DEALERNODE = GetArg("-dealer",0);
if ( strlen(NOTARY_PUBKEY.c_str()) == 66 )
{
USE_EXTERNAL_PUBKEY = 1;
if ( IS_KOMODO_NOTARY == 0 )
@@ -1563,6 +1564,7 @@ void komodo_args(char *argv0)
{
MAX_BLOCK_SIGOPS = 60000;
ASSETCHAINS_TXPOW = GetArg("-ac_txpow",0) & 3;
ASSETCHAINS_FOUNDERS = GetArg("-ac_founders",0) & 1;
ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10);
ASSETCHAINS_ENDSUBSIDY = GetArg("-ac_end",0);
ASSETCHAINS_REWARD = GetArg("-ac_reward",0);
@@ -1570,8 +1572,7 @@ void komodo_args(char *argv0)
ASSETCHAINS_DECAY = GetArg("-ac_decay",0);
ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0);
ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey","");
ASSETCHAINS_FOUNDERS_REWARD = GetArg("-ac_freward",0);
ASSETCHAINS_OVERRIDE_ADDRESS = GetArg("-ac_address","");
ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script","");
ASSETCHAINS_STREAM = GetArg("-ac_stream",0);
if ( ASSETCHAINS_STREAM != 0 && ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_PRIVATE != 0 )) {
@@ -1600,23 +1601,48 @@ void komodo_args(char *argv0)
ASSETCHAINS_DECAY = 0;
printf("ASSETCHAINS_DECAY cant be more than 100000000\n");
}
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 )
decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
else if ( ASSETCHAINS_COMMISSION != 0 )
{
ASSETCHAINS_COMMISSION = 0;
printf("ASSETCHAINS_COMMISSION needs an ASETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
} else if ( ASSETCHAINS_STREAM != 0) {
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) != 66 && ASSETCHAINS_STREAM != 0 )
{
printf("ASSETCHAINS_STREAM needs ASSETCHAINS_OVERRIDE_PUBKEY! \n");
exit(0);
}
if ( ASSETCHAINS_STREAM != 0 && ASSETCHAINS_SUPPLY == 10 ) {
ASSETCHAINS_SUPPLY = 1000000;
printf("ASSETCHAINS_STREAM is set with no supply, setting supply at 1,000,000 coins. \n");
}
if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_STREAM != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 )
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 || ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
fprintf(stderr,"end.%llu blocks, reward %.8f halving.%llu blocks, decay.%llu perc %.4f%% ac_pub=[%02x...]\n",(long long)ASSETCHAINS_ENDSUBSIDY,dstr(ASSETCHAINS_REWARD),(long long)ASSETCHAINS_HALVING,(long long)ASSETCHAINS_DECAY,dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0]);
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 )
{
decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
calc_rmd160_sha256(ASSETCHAINS_OVERRIDE_PUBKEYHASH,ASSETCHAINS_OVERRIDE_PUBKEY33,33);
}
if ( ASSETCHAINS_COMMISSION == 0 )
{
if (ASSETCHAINS_FOUNDERS != 0 )
{
ASSETCHAINS_COMMISSION = 53846154; // maps to 35%
printf("ASSETCHAINS_COMMISSION defaulted to 35%% when founders reward active\n");
}
else if ( ASSETCHAINS_STREAM == 0 )
{
ASSETCHAINS_OVERRIDE_PUBKEY.clear();
printf("-ac_perc or -ac_stream must be set with -ac_pubkey\n");
}
}
}
else
{
if ( ASSETCHAINS_COMMISSION != 0 )
{
ASSETCHAINS_COMMISSION = 0;
printf("ASSETCHAINS_COMMISSION needs an ASSETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
}
if ( ASSETCHAINS_FOUNDERS != 0 )
{
ASSETCHAINS_FOUNDERS = 0;
printf("ASSETCHAINS_FOUNDERS needs an ASSETCHAINS_OVERRIDE_PUBKEY or ASSETCHAINS_SCRIPTPUB\n");
}
}
if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
fprintf(stderr,"end.%llu blocks, reward %.8f halving.%llu blocks, decay.%llu perc %.4f%% ac_pub=[%02x%02x%02x...]\n",(long long)ASSETCHAINS_ENDSUBSIDY,dstr(ASSETCHAINS_REWARD),(long long)ASSETCHAINS_HALVING,(long long)ASSETCHAINS_DECAY,dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2]);
extraptr = extrabuf;
memcpy(extraptr,ASSETCHAINS_OVERRIDE_PUBKEY33,33), extralen = 33;
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_ENDSUBSIDY),(void *)&ASSETCHAINS_ENDSUBSIDY);
@@ -1625,6 +1651,10 @@ void komodo_args(char *argv0)
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY);
val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffff) << 40) | ((ASSETCHAINS_PUBLIC != 0) << 7) | ((ASSETCHAINS_PRIVATE != 0) << 6) | ASSETCHAINS_TXPOW;
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val);
if ( ASSETCHAINS_FOUNDERS != 0 )
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS),(void *)&ASSETCHAINS_FOUNDERS);
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
extralen += iguana_rwnum(1,&extraptr[extralen],(int32_t)ASSETCHAINS_SCRIPTPUB.size(),(void *)ASSETCHAINS_SCRIPTPUB.c_str());
}
addn = GetArg("-seednode","");
if ( strlen(addn.c_str()) > 0 )
@@ -1636,8 +1666,11 @@ void komodo_args(char *argv0)
MAX_MONEY = (ASSETCHAINS_SUPPLY+100) * SATOSHIDEN;
else MAX_MONEY = (ASSETCHAINS_SUPPLY+100) * SATOSHIDEN + ASSETCHAINS_REWARD * (ASSETCHAINS_ENDSUBSIDY==0 ? 10000000 : ASSETCHAINS_ENDSUBSIDY);
MAX_MONEY += (MAX_MONEY * ASSETCHAINS_COMMISSION) / SATOSHIDEN;
if ( ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID && MAX_MONEY < 1000000LL*SATOSHIDEN )
if ( ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID && MAX_MONEY < 1000000LL*SATOSHIDEN )
MAX_MONEY = 1000000LL*SATOSHIDEN;
if ( MAX_MONEY <= 0 || MAX_MONEY > 10000100000LL*SATOSHIDEN )
MAX_MONEY = 10000100000LL*SATOSHIDEN;
//fprintf(stderr,"MAX_MONEY %llu %.8f\n",(long long)MAX_MONEY,(double)MAX_MONEY/SATOSHIDEN);
//printf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,ASSETCHAINS_SYMBOL,(double)MAX_MONEY/SATOSHIDEN);
ASSETCHAINS_P2PPORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen);
while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 )
@@ -1740,6 +1773,8 @@ void komodo_args(char *argv0)
dpowconfs = 0;
} else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort());
KOMODO_DPOWCONFS = GetArg("-dpowconfs",dpowconfs);
if ( ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"SUPERNET") == 0 || strcmp(ASSETCHAINS_SYMBOL,"DEX") == 0 || strcmp(ASSETCHAINS_SYMBOL,"COQUI") == 0 || strcmp(ASSETCHAINS_SYMBOL,"PIRATE") == 0 || strcmp(ASSETCHAINS_SYMBOL,"KMDICE") == 0 )
KOMODO_EXTRASATOSHI = 1;
}
void komodo_nameset(char *symbol,char *dest,char *source)

View File

@@ -58,7 +58,7 @@ using namespace std;
CCriticalSection cs_main;
extern uint8_t NOTARY_PUBKEY33[33];
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING;
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING,KOMODO_EXTRASATOSHI;
int32_t KOMODO_NEWBLOCKS;
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
void komodo_broadcast(CBlock *pblock,int32_t limit);
@@ -95,6 +95,7 @@ unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
CTxMemPool mempool(::minRelayTxFee);
CTxMemPool tmpmempool(::minRelayTxFee);
struct COrphanTx {
CTransaction tx;
@@ -1365,7 +1366,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
auto verifier = libzcash::ProofVerifier::Strict();
if ( komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
{
//fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
return error("AcceptToMemoryPool: komodo_validate_interest failed");
@@ -1716,8 +1717,10 @@ bool myAddtomempool(CTransaction &tx)
{
CValidationState state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
{
//fprintf(stderr,"call AcceptToMemoryPool\n");
return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
else return(true);
} else return(true);
}
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
@@ -3149,7 +3152,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
}
//if ( ASSETCHAINS_SYMBOL[0] == 0 )
// komodo_earned_interest(pindex->nHeight,sum);
// komod0o_earned_interest(pindex->nHeight,sum);
CTxUndo undoDummy;
if (i > 0) {
blockundo.vtxundo.push_back(CTxUndo());
@@ -3178,18 +3181,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) )
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 &&
{
uint64_t checktoshis;
if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
if ( (checktoshis= komodo_commission((CBlock *)&block,(int32_t)pindex->nHeight)) != 0 )
{
if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
if ( block.vtx[0].vout.size() >= 2 && block.vtx[0].vout[1].nValue == checktoshis )
blockReward += checktoshis;
else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
}
}
if ( block.vtx[0].GetValueOut() > blockReward+1 )
if ( block.vtx[0].GetValueOut() > blockReward+KOMODO_EXTRASATOSHI )
{
if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
{
@@ -3636,7 +3638,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->nHeight >= KOMODO_LONGESTCHAIN )
KOMODO_INSYNC = 1;
KOMODO_INSYNC = (int32_t)pindexNew->nHeight;
else KOMODO_INSYNC = 0;
//fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->nHeight,KOMODO_INSYNC);
if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
@@ -4303,6 +4305,22 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
{
CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
//fprintf(stderr,"put block's tx into mempool\n");
// Copy all non Z-txs in mempool to temporary mempool because there can be tx in local mempool that make the block invalid.
LOCK(mempool.cs);
list<CTransaction> transactionsToRemove;
BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) {
const CTransaction &tx = e.GetTx();
const uint256 &hash = tx.GetHash();
if ( tx.vjoinsplit.size() == 0 ) {
transactionsToRemove.push_back(tx);
tmpmempool.addUnchecked(hash,e,!IsInitialBlockDownload());
}
}
BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
list<CTransaction> removed;
mempool.remove(tx, removed, false);
}
// add all the txs in the block to the empty mempool.
while ( 1 )
{
for (i=0; i<block.vtx.size(); i++)
@@ -4351,6 +4369,24 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
LogPrintf("CheckBlockHeader komodo_check_deposit error");
return(false);
}
if ( ASSETCHAINS_CC != 0 )
{
// here we add back all txs from the temp mempool to the main mempool.
// which removes any tx locally that were invalid after the block arrives.
int invalidtxs = 0;
BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) {
CTransaction tx = e.GetTx();
CValidationState state; bool fMissingInputs,fOverrideFees = false;
if (AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees) == false )
invalidtxs++;
//else fprintf(stderr, "added mempool tx back to mempool\n");
}
if ( 0 && invalidtxs > 0 )
fprintf(stderr, "number of invalid txs: %d\n",invalidtxs );
// empty the temp mempool for next time.
tmpmempool.clear();
}
return true;
}
@@ -4481,7 +4517,15 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat
if (ppindex)
*ppindex = pindex;
if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
{
if ( ASSETCHAINS_CC == 0 )
return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
else
{
fprintf(stderr,"reconsider block %s\n",hash.GetHex().c_str());
pindex->nStatus &= ~BLOCK_FAILED_MASK;
}
}
/*if ( pindex != 0 && hash == komodo_requestedhash )
{
fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());

View File

@@ -109,7 +109,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
extern uint64_t ASSETCHAINS_REWARD,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],NOTARYADDRS[64][36];
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTPUB;
void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],NUM_NOTARIES;
@@ -119,9 +119,10 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,
int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize);
int32_t komodo_baseid(char *origbase);
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
uint64_t komodo_commission(const CBlock *block);
uint64_t komodo_commission(const CBlock *block,int32_t height);
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_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
{
@@ -355,6 +356,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
//fprintf(stderr,"dont have inputs\n");
continue;
}
if ( 0 )
{
CValidationState state;
auto verifier = libzcash::ProofVerifier::Disabled();
@@ -457,18 +459,30 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = txNew;
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block,(int32_t)nHeight)) != 0 )
{
int32_t i; uint8_t *ptr;
txNew.vout.resize(2);
txNew.vout[1].nValue = commission;
txNew.vout[1].scriptPubKey.resize(35);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
ptr[0] = 33;
for (i=0; i<33; i++)
ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
ptr[34] = OP_CHECKSIG;
//printf("autocreate commission vout\n");
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
//txNew.vout[1].scriptPubKey = CScript() << ParseHex();
int32_t len = strlen(ASSETCHAINS_SCRIPTPUB.c_str());
len >>= 1;
txNew.vout[1].scriptPubKey.resize(len);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
decode_hex(ptr,len,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
}
else
{
txNew.vout[1].scriptPubKey.resize(35);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
ptr[0] = 33;
for (i=0; i<33; i++)
ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
ptr[34] = OP_CHECKSIG;
}
//printf("autocreate commision vout\n");
pblock->vtx[0] = txNew;
}
pblocktemplate->vTxFees[0] = -nFees;
@@ -654,10 +668,19 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey,int32_t nHeight,int32_t gpucount)
{
CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i;
if ( nHeight == 1 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
CPubKey pubkey; CScript scriptPubKey; uint8_t *script,*ptr; int32_t i,len;
if ( nHeight == 1 && ASSETCHAINS_COMMISSION != 0 )
{
scriptPubKey = CScript() << ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY) << OP_CHECKSIG;
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
scriptPubKey = CScript() << ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY) << OP_CHECKSIG;
else
{
len = strlen(ASSETCHAINS_SCRIPTPUB.c_str());
len >>= 1;
scriptPubKey.resize(len);
ptr = (uint8_t *)scriptPubKey.data();
decode_hex(ptr,len,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
}
}
else if ( ASSETCHAINS_STREAM != 0 )
{
@@ -794,7 +817,7 @@ void static BitcoinMiner()
unsigned int n = chainparams.EquihashN();
unsigned int k = chainparams.EquihashK();
uint8_t *script; uint64_t total,checktoshis; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1;
uint8_t *script; uint64_t total; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1;
while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) )
{
sleep(1);
@@ -990,7 +1013,7 @@ void static BitcoinMiner()
{
fprintf(stderr,"Mining when blockchain might not be in sync longest.%d vs %d\n",KOMODO_LONGESTCHAIN,Mining_height);
if ( KOMODO_LONGESTCHAIN != 0 && Mining_height >= KOMODO_LONGESTCHAIN )
KOMODO_INSYNC = 1;
KOMODO_INSYNC = Mining_height;
sleep(3);
}
// Hash state

View File

@@ -10,129 +10,30 @@ extern int32_t STAKED_ERA,IS_STAKED_NOTARY,IS_KOMODO_NOTARY;
extern pthread_mutex_t staked_mutex;
extern uint8_t NOTARY_PUBKEY33[33],NUM_NOTARIES;
// Era 1 set of pubkeys
const char *notaries_STAKED1[][2] =
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"Bar_F1sh_Rel", "0395f2d9dd9ccb78caf74bff49b6d959afb95af746462e1b35f4a167d8e82b3666" }, // RBbLxJagCA9QHDazQvfnDZe874V1K4Gu8t
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
};
int num_notaries_STAKED1 = (sizeof(notaries_STAKED1)/sizeof(*notaries_STAKED1));
// Era 2 set of pubkeys
const char *notaries_STAKED2[][2] =
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
};
int num_notaries_STAKED2 = (sizeof(notaries_STAKED2)/sizeof(*notaries_STAKED2));
// Era 3 set of pubkeys
const char *notaries_STAKED3[][2] =
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
};
int num_notaries_STAKED3 = (sizeof(notaries_STAKED3)/sizeof(*notaries_STAKED3));
// Era 4 set of pubkeys
const char *notaries_STAKED4[][2] =
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
};
int num_notaries_STAKED4 = (sizeof(notaries_STAKED4)/sizeof(*notaries_STAKED4));
int8_t is_STAKED(const char *chain_name) {
int STAKED = 0;
if ( (strcmp(chain_name, "STAKED") == 0) || (strncmp(chain_name, "STAKED", 6) == 0) )
if ( (strcmp(chain_name, "LABS") == 0) || (strncmp(chain_name, "LABS", 4) == 0) )
STAKED = 1;
else if ( (strcmp(chain_name, "STKD") == 0) || (strncmp(chain_name, "STKD", 4) == 0) )
else if ( (strcmp(chain_name, "LAB") == 0) || (strncmp(chain_name, "LAB", 3) == 0) )
STAKED = 2;
else if ( (strcmp(chain_name, "CFEK") == 0) || (strncmp(chain_name, "CFEK", 4) == 0) )
STAKED = 3;
//fprintf(stderr, "This chains is: %s which is: %d\n", chain_name,STAKED);
//fprintf(stderr, "This chain is: %s which is: %d\n", chain_name,STAKED);
return(STAKED);
};
int32_t STAKED_era(int timestamp)
{
int8_t era = 0;
if (timestamp <= STAKED_NOTARIES_TIMESTAMP1)
era = 1;
else if (timestamp <= STAKED_NOTARIES_TIMESTAMP2 && timestamp >= (STAKED_NOTARIES_TIMESTAMP1 + STAKED_ERA_GAP))
era = 2;
else if (timestamp <= STAKED_NOTARIES_TIMESTAMP3 && timestamp >= (STAKED_NOTARIES_TIMESTAMP2 + STAKED_ERA_GAP))
era = 3;
else if (timestamp <= STAKED_NOTARIES_TIMESTAMP4 && timestamp >= (STAKED_NOTARIES_TIMESTAMP3 + STAKED_ERA_GAP))
era = 4;
else
era = 0;
int8_t era = 0;
if (timestamp <= STAKED_NOTARIES_TIMESTAMP[0])
return(1);
for (int32_t i = 1; i < NUM_STAKED_ERAS; i++)
{
if (timestamp <= STAKED_NOTARIES_TIMESTAMP[i] && timestamp >= (STAKED_NOTARIES_TIMESTAMP[i-1] + STAKED_ERA_GAP))
return(i+1);
}
// if we are in a gap, return era 0, this allows to invalidate notarizations when in GAP.
return(era);
return(0);
};
#ifdef SERVER
@@ -152,24 +53,16 @@ int8_t updateStakedNotary() {
#endif
int8_t StakedNotaryID(std::string &notaryname, char *Raddress) {
int8_t notaryID = -1;
if ( STAKED_ERA != 0 ) {
switch (STAKED_ERA) {
case 1:
notaryID = ScanStakedArray(notaries_STAKED1,num_notaries_STAKED1,Raddress,notaryname);
break;
case 2:
notaryID = ScanStakedArray(notaries_STAKED2,num_notaries_STAKED2,Raddress,notaryname);
break;
case 3:
notaryID = ScanStakedArray(notaries_STAKED3,num_notaries_STAKED3,Raddress,notaryname);
break;
case 4:
notaryID = ScanStakedArray(notaries_STAKED4,num_notaries_STAKED4,Raddress,notaryname);
break;
}
if ( STAKED_ERA != 0 )
{
for (int8_t i = 0; i < num_notaries_STAKED[STAKED_ERA-1]; i++) {
if ( strcmp(Raddress,NOTARYADDRS[i]) == 0 ) {
notaryname.assign(notaries_STAKED[STAKED_ERA-1][i][0]);
return(i);
}
}
}
return(notaryID);
return(-1);
}
int8_t numStakedNotaries(uint8_t pubkeys[64][33],int8_t era) {
@@ -191,50 +84,50 @@ int8_t numStakedNotaries(uint8_t pubkeys[64][33],int8_t era) {
case 1:
if ( didstaked1 == 0 )
{
for (i=0; i<num_notaries_STAKED1; i++) {
decode_hex(staked_pubkeys1[i],33,(char *)notaries_STAKED1[i][1]);
for (i=0; i<num_notaries_STAKED[0]; i++) {
decode_hex(staked_pubkeys1[i],33,(char *)notaries_STAKED[0][i][1]);
}
didstaked1 = 1;
printf("%s is a STAKED chain in era 1 \n",ChainName);
}
memcpy(pubkeys,staked_pubkeys1,num_notaries_STAKED1 * 33);
retval = num_notaries_STAKED1;
memcpy(pubkeys,staked_pubkeys1,num_notaries_STAKED[0] * 33);
retval = num_notaries_STAKED[0];
break;
case 2:
if ( didstaked2 == 0 )
{
for (i=0; i<num_notaries_STAKED2; i++) {
decode_hex(staked_pubkeys2[i],33,(char *)notaries_STAKED2[i][1]);
for (i=0; i<num_notaries_STAKED[1]; i++) {
decode_hex(staked_pubkeys2[i],33,(char *)notaries_STAKED[1][i][1]);
}
didstaked2 = 1;
printf("%s is a STAKED chain in era 2 \n",ChainName);
}
memcpy(pubkeys,staked_pubkeys2,num_notaries_STAKED2 * 33);
retval = num_notaries_STAKED2;
memcpy(pubkeys,staked_pubkeys2,num_notaries_STAKED[1] * 33);
retval = num_notaries_STAKED[1];
break;
case 3:
if ( didstaked3 == 0 )
{
for (i=0; i<num_notaries_STAKED3; i++) {
decode_hex(staked_pubkeys3[i],33,(char *)notaries_STAKED3[i][1]);
for (i=0; i<num_notaries_STAKED[2]; i++) {
decode_hex(staked_pubkeys3[i],33,(char *)notaries_STAKED[2][i][1]);
}
didstaked3 = 1;
printf("%s is a STAKED chain in era 3 \n",ChainName);
}
memcpy(pubkeys,staked_pubkeys3,num_notaries_STAKED3 * 33);
retval = num_notaries_STAKED3;
memcpy(pubkeys,staked_pubkeys3,num_notaries_STAKED[2] * 33);
retval = num_notaries_STAKED[2];
break;
case 4:
if ( didstaked4 == 0 )
{
for (i=0; i<num_notaries_STAKED4; i++) {
decode_hex(staked_pubkeys4[i],33,(char *)notaries_STAKED4[i][1]);
for (i=0; i<num_notaries_STAKED[3]; i++) {
decode_hex(staked_pubkeys4[i],33,(char *)notaries_STAKED[3][i][1]);
}
didstaked4 = 1;
printf("%s is a STAKED chain in era 4 \n",ChainName);
}
memcpy(pubkeys,staked_pubkeys4,num_notaries_STAKED4 * 33);
retval = num_notaries_STAKED4;
memcpy(pubkeys,staked_pubkeys4,num_notaries_STAKED[3] * 33);
retval = num_notaries_STAKED[3];
break;
}
}
@@ -252,6 +145,7 @@ void UpdateNotaryAddrs(uint8_t pubkeys[64][33],int8_t numNotaries) {
static int didinit;
if ( didinit == 0 ) {
pthread_mutex_init(&staked_mutex,NULL);
didinit = 1;
}
if ( pubkeys[0][0] == 0 )
{
@@ -277,43 +171,12 @@ void UpdateNotaryAddrs(uint8_t pubkeys[64][33],int8_t numNotaries) {
}
}
int8_t ScanStakedArray(const char *notaries_chosen[][2],int num_notaries,char *Raddress,std::string &notaryname) {
for (size_t i = 0; i < num_notaries; i++) {
//fprintf(stderr, "address [%ld]: %s\n",i,NOTARYADDRS[i]);
if ( strcmp(Raddress,NOTARYADDRS[i]) == 0 ) {
notaryname.assign(notaries_chosen[i][0]);
//printf("notary number: %ld\n",i );
return(i);
}
}
return(-1);
}
CrosschainAuthority Choose_auth_STAKED(int32_t chosen_era) {
CrosschainAuthority auth;
switch (chosen_era) {
case 1:
auth = auth_STAKED_chosen(notaries_STAKED1,num_notaries_STAKED1);
break;
case 2:
auth = auth_STAKED_chosen(notaries_STAKED2,num_notaries_STAKED2);
break;
case 3:
auth = auth_STAKED_chosen(notaries_STAKED3,num_notaries_STAKED3);
break;
case 4:
auth = auth_STAKED_chosen(notaries_STAKED4,num_notaries_STAKED4);
break;
}
return(auth);
};
CrosschainAuthority auth_STAKED_chosen(const char *notaries_chosen[][2],int num_notaries) {
CrosschainAuthority auth;
auth.requiredSigs = (num_notaries / 5);
auth.size = num_notaries;
for (int n=0; n<auth.size; n++)
for (size_t i=0; i<33; i++)
sscanf(notaries_chosen[n][1]+(i*2), "%2hhx", auth.notaries[n]+i);
return auth;
auth.requiredSigs = (num_notaries_STAKED[chosen_era-1] / 5);
auth.size = num_notaries_STAKED[chosen_era-1];
for (int n=0; n<auth.size; n++)
for (size_t i=0; i<33; i++)
sscanf(notaries_STAKED[chosen_era-1][n][1]+(i*2), "%2hhx", auth.notaries[n]+i);
return auth;
};

View File

@@ -5,24 +5,116 @@
#include "crosschain.h"
#include "cc/CCinclude.h"
static const int32_t iguanaPort = 9997;
static const int8_t BTCminsigs = 13;
static const int8_t overrideMinSigs = 0;
static const char *iguanaSeeds[8][1] =
{
{"80.240.17.222"},
{"103.6.12.112"},
{"18.224.176.46"},
{"45.76.120.247"},
{"103.6.12.112"},
{"103.6.12.112"},
{"103.6.12.112"},
{"103.6.12.112"},
};
static const int STAKED_ERA_GAP = 777;
static const int STAKED_NOTARIES_TIMESTAMP1 = 1604211111;
static const int STAKED_NOTARIES_TIMESTAMP2 = 1604222222;
static const int STAKED_NOTARIES_TIMESTAMP3 = 1604233333;
static const int STAKED_NOTARIES_TIMESTAMP4 = 1604244444;
static const int NUM_STAKED_ERAS = 4;
static const int STAKED_NOTARIES_TIMESTAMP[NUM_STAKED_ERAS] = {1604111111, 1604222222, 1604233333, 1604244444};
extern const char *notaries_STAKED1[][2];
extern int num_notaries_STAKED1;
// Era array of pubkeys.
static const char *notaries_STAKED[NUM_STAKED_ERAS][64][2] =
{
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"Bar_F1sh_Rel", "0395f2d9dd9ccb78caf74bff49b6d959afb95af746462e1b35f4a167d8e82b3666" }, // RBbLxJagCA9QHDazQvfnDZe874V1K4Gu8t
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
},
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "024d19acf0d5de212cdd50326cd143292545d366a71b2b9c6df9f2110de2dfa1f2" }, //RKtAD2kyRRMx4EiG1eeTNprF5h2nmGbzzu
{"smk762", "0330e8fbdb6d560095d33da86a139c755b7896eb5b85239966fa7b235db16d4037" }, // RFB8zewwMNcLMPuQ84B6PofxJBBsuYxiN8
{"jorian", "0288e682c1ac449f1b85c4acb2d0bcd216d5df34c15fd18b8a8dd5fa64b8ece8ef" }, // RR1yT5aB19VwFoUCGTW4q4pk4qmhHEEE4t
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"greentea", "02054c14ae81838a063d22a75eaa3c961415f6825a57c8b8e4148d19dad64f128e" }, // REF7R76WpL1v7nSXjjiNHtRa2xYtq5qk1p
{"CMaurice", "025830ce81bd1301fb67d5872344efa7a9ff99ae85fe1234f18c085db9072b740f" }, // RX7pXUaV24xFn6DVKV8t3PrRF3gKw6TBjf
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"Bar_F1sh_Rel", "0395f2d9dd9ccb78caf74bff49b6d959afb95af746462e1b35f4a167d8e82b3666" }, // RBbLxJagCA9QHDazQvfnDZe874V1K4Gu8t
{"zatJUM", "030fff499b6dc0215344b28a0b6b4becdfb00cd34cd1b36b983ec14f47965fd4bc" }, // RSoEDLBasth7anxS8gbkg6KgeGiz8rhqv1
{"dwy", "03669457b2934d98b5761121dd01b243aed336479625b293be9f8c43a6ae7aaeff" }, // RKhZMqRF361FSGFAzstP5AhozekPjoVh5q
{"dukeleto", "03e4322510ee46d417b8382fe124f5a381a3cef6aef08f8a4e90c66a42a04b4015" }, // RB8vS1fkGuttoNYkA2B1ivNn8vhqbCEqbe
{"gcharang", "03336ca9db27cb6e882830e20dc525884e27dc94d557a5e68b972a5cbf9e8c62a8" }, // RJYiWn3FRCSSLf9Pe5RJcbrKQYosaMburP
{"ca333", "03a18a33313ccdbf3c9778776e33c423e073ff5833fa1de092ce9e921de52f22f6" }, // RX333A56jWdeW15MwZsaW3mHxGaDu2Yutp
{"computergenie", "03448ce28fb21748e8b05bbe32d6b1e758b589ac1eb359e5d552f8868f2b75dc92" }, // RGeniexxkjnR34hg7ZnCf36kmfuJusf6rE
{"daemonfox", "0383484bdc745b2b953c85b5a0c496a1f27bc42ae971f15779ed1532421b3dd943" }, //
{"SHossain", "02791f5c215b8a19c143a98e3371ff03b5613df9ac430c4a331ca55fed5761c800" }, // RKdLoHkyeorXmMtj91B1AAnAGiwsdt9MdF
{"Nabob", "03ee91c20b6d26e3604022f42df6bb8de6f669da4591f93b568778cba13d9e9ddf" }, // RRwCLPZDzpHEFJnLev4phy51e2stHRUAaU
},
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
},
{
{"blackjok3r", "021914947402d936a89fbdd1b12be49eb894a1568e5e17bb18c8a6cffbd3dc106e" }, // RTVti13NP4eeeZaCCmQxc2bnPdHxCJFP9x
{"alright", "0285657c689b903218c97f5f10fe1d10ace2ed6595112d9017f54fb42ea1c1dda8" }, //RXmXeQ8LfJK6Y1aTM97cRz9Gu5f6fmR3sg
{"webworker01", "031d1fb39ae4dca28965c3abdbd21faa0f685f6d7b87a60561afa7c448343fef6d" }, //RGsQiArk5sTmjXZV9UzGMW5njyvtSnsTN8
{"CrisF", "03f87f1bccb744d90fdbf7fad1515a98e9fc7feb1800e460d2e7565b88c3971bf3" }, //RMwEpnaVe3cesWbMqqKYPPkaLcDkooTDgZ
{"smk762", "02eacef682d2f86e0103c18f4da46116e17196f3fb8f73ed931acb78e81d8e1aa5" }, // RQVvzJ8gepCDVjhqCAc5Tia1kTmt8KDPL9
{"jorian", "02150c410a606b898bcab4f083e48e0f98a510e0d48d4db367d37f318d26ae72e3" }, // RFgzxZe2P4RWKx6E9QGPK3rx3TXeWxSqa8
{"TonyL", "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" }, // RHq3JsvLxU45Z8ufYS6RsDpSG4wi6ucDev
{"Emman", "038f642dcdacbdf510b7869d74544dbc6792548d9d1f8d73a999dd9f45f513c935" }, //RN2KsQGW36Ah4NorJDxLJp2xiYJJEzk9Y6
{"CHMEX", "03ed125d1beb118d12ff0a052bdb0cee32591386d718309b2924f2c36b4e7388e6" }, // RF4HiVeuYpaznRPs7fkRAKKYqT5tuxQQTL
{"metaphilibert", "0344182c376f054e3755d712361672138660bda8005abb64067eb5aa98bdb40d10" }, // RG28QSnYFADBg1dAVkH1uPGYS6F8ioEUM2
{"jusoaresf", "02dfb7ed72a23f6d07f0ea2f28192ee174733cc8412ec0f97b073007b78fab6346" }, // RBQGfE5Hxsjm1BPraTxbneRuNasPDuoLnu
{"mylo", "03f6b7fcaf0b8b8ec432d0de839a76598b78418dadd50c8e5594c0e557d914ec09" }, // RXN4hoZkhUkkrnef9nTUDw3E3vVALAD8Kx
{"blackjok3r2", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"blackjok3r3", "03c3e4c0206551dbf3a4b24d18e5d2737080541184211e3bfd2b1092177410b9c2" }, // RMMav2AVse5XHPvDfTzRpMbFhK3GqFmtSN
{"kmdkrazy", "02f7597468703c1c5c8465dd6d43acaae697df9df30bed21494d193412a1ea193e" }, // RWHGbrLSP89fTzNVF9U9xiekDYJqcibTca
{"alrighttest", "02e9dfe248f453b499315a90375e58a1c9ad79f5f3932ecb2205399a0f262d65fc" }, // RBevSstS8JtDXMEFNcJws4QTYN4PcE2VL5
{"alrighttest1", "03527c7ecd6a8c5db6d685a64e6e18c1edb49e2f057a434f56c3f1253a26e9c6a2" }, // RBw2jNU3dnGk86ZLqPMadJwRwg3NU8eC6s
}
};
extern const char *notaries_STAKED2[][2];
extern int num_notaries_STAKED2;
extern const char *notaries_STAKED3[][2];
extern int num_notaries_STAKED3;
extern const char *notaries_STAKED4[][2];
extern int num_notaries_STAKED4;
static const int32_t num_notaries_STAKED[NUM_STAKED_ERAS] = { 17, 25, 17, 17 };
int8_t is_STAKED(const char *chain_name);
int32_t STAKED_era(int timestamp);
@@ -30,9 +122,7 @@ int8_t updateStakedNotary();
int8_t numStakedNotaries(uint8_t pubkeys[64][33],int8_t era);
int8_t StakedNotaryID(std::string &notaryname, char *Raddress);
void UpdateNotaryAddrs(uint8_t pubkeys[64][33],int8_t numNotaries);
int8_t ScanStakedArray(const char *notaries_chosen[][2],int num_notaries,char *Raddress,std::string &notaryname);
CrosschainAuthority Choose_auth_STAKED(int32_t chosen_era);
CrosschainAuthority auth_STAKED_chosen(const char *notaries_chosen[][2],int num_notaries);
#endif

View File

@@ -50,6 +50,7 @@ NotarisationsInBlock ScanBlockNotarisations(const CBlock &block, int nHeight)
// pass era slection off to notaries_staked.cpp file
auth_STAKED = Choose_auth_STAKED(staked_era);
}
printf("minsigs.%i era.%i authsize.%i\n",auth_STAKED.requiredSigs,staked_era,auth_STAKED.size);
if (!CheckTxAuthority(tx, auth_STAKED))
continue;
printf("Authorised notarisation data for %s \n",data.symbol);

View File

@@ -24,35 +24,31 @@ extern int32_t ASSETCHAINS_STREAM;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
if ( ASSETCHAINS_STREAM == 0)
{
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
// Genesis block
if (pindexLast == NULL )
return nProofOfWorkLimit;
// Find the first block in the averaging interval
const CBlockIndex* pindexFirst = pindexLast;
arith_uint256 bnTot {0};
for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
arith_uint256 bnTmp;
bnTmp.SetCompact(pindexFirst->nBits);
bnTot += bnTmp;
pindexFirst = pindexFirst->pprev;
}
// Check we have enough blocks
if (pindexFirst == NULL)
return nProofOfWorkLimit;
arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
}
else
{
if ( ASSETCHAINS_STREAM == 2 )
return 537857807;
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
// Genesis block
if (pindexLast == NULL )
return nProofOfWorkLimit;
// Find the first block in the averaging interval
const CBlockIndex* pindexFirst = pindexLast;
arith_uint256 bnTot {0};
for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) {
arith_uint256 bnTmp;
bnTmp.SetCompact(pindexFirst->nBits);
bnTot += bnTmp;
pindexFirst = pindexFirst->pprev;
}
// Check we have enough blocks
if (pindexFirst == NULL)
return nProofOfWorkLimit;
arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
}
unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,

View File

@@ -33,6 +33,7 @@ extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue&
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
int32_t komodo_longestchain();
int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
extern int32_t KOMODO_LONGESTCHAIN;
double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
{
@@ -590,6 +591,18 @@ bool myIsutxo_spentinmempool(uint256 txid,int32_t vout)
return(false);
}
bool mytxid_inmempool(uint256 txid)
{
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
const CTransaction &tx = e.GetTx();
const uint256 &hash = tx.GetHash();
if ( txid == hash )
return(true);
}
return(false);
}
UniValue mempoolToJSON(bool fVerbose = false)
{
if (fVerbose)
@@ -1529,7 +1542,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
progress = Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.LastTip());
} else {
int32_t longestchain = komodo_longestchain();
int32_t longestchain = KOMODO_LONGESTCHAIN;//komodo_longestchain();
progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
}
UniValue obj(UniValue::VOBJ);

View File

@@ -50,7 +50,9 @@ UniValue assetchainproof(const UniValue& params, bool fHelp)
UniValue crosschainproof(const UniValue& params, bool fHelp)
{
UniValue ret(UniValue::VOBJ);
//fprintf(stderr,"crosschainproof needs to be implemented\n");
return(ret);
}

View File

@@ -756,6 +756,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
return result;
}
class submitblock_StateCatcher : public CValidationInterface
{
public:

View File

@@ -64,6 +64,70 @@ extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY;
extern std::string NOTARY_PUBKEY,NOTARY_ADDRESS; extern uint8_t NOTARY_PUBKEY33[];
int32_t getera(int now)
{
for (int32_t i = 0; i < NUM_STAKED_ERAS; i++) {
if ( now <= STAKED_NOTARIES_TIMESTAMP[i] ) {
return(i);
}
}
}
UniValue getiguanajson(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error("getiguanajson\nreturns json for iguana, for the current ERA.");
UniValue json(UniValue::VOBJ);
UniValue seeds(UniValue::VARR);
UniValue notaries(UniValue::VARR);
// get the current era, use local time for now.
// should ideally take blocktime of last known block.
int now = time(NULL);
int32_t era = getera(now);
// loop over seeds array and push back to json array for seeds
for (int8_t i = 0; i < 8; i++) {
seeds.push_back(iguanaSeeds[i][0]);
}
// loop over era's notaries and push back each pair to the notary array
for (int8_t i = 0; i < num_notaries_STAKED[era]; i++) {
UniValue notary(UniValue::VOBJ);
notary.push_back(Pair(notaries_STAKED[era][i][0],notaries_STAKED[era][i][1]));
notaries.push_back(notary);
}
// get the min sigs
int minsigs;
if ( num_notaries_STAKED[era]/5 > overrideMinSigs )
minsigs = (num_notaries_STAKED[era] + 4) / 5;
else
minsigs = overrideMinSigs;
json.push_back(Pair("port",iguanaPort));
json.push_back(Pair("BTCminsigs",BTCminsigs));
json.push_back(Pair("minsigs",minsigs));
json.push_back(Pair("seeds", seeds));
json.push_back(Pair("notaries",notaries));
return json;
}
UniValue getnotarysendmany(const UniValue& params, bool fHelp)
{
int era = getera(time(NULL));
UniValue ret(UniValue::VOBJ);
for (int i = 0; i<num_notaries_STAKED[era]; i++)
{
char Raddress[18]; uint8_t pubkey33[33];
decode_hex(pubkey33,33,(char *)notaries_STAKED[era][i][1]);
pubkey2addr((char *)Raddress,(uint8_t *)pubkey33);
ret.push_back(Pair(Raddress,(int)10);
}
return ret;
}
UniValue getinfo(const UniValue& params, bool fHelp)
{
uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,longestchain,kmdnotarized_height,txid_height;
@@ -124,9 +188,15 @@ UniValue getinfo(const UniValue& params, bool fHelp)
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
if ( ASSETCHAINS_SYMBOL[0] == 0 )
obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM))); //komodo_interestsum()
{
obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM)));
obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
}
else
{
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); //
}
}
#endif
//fprintf(stderr,"after wallet %u\n",(uint32_t)time(NULL));
@@ -168,13 +238,13 @@ UniValue getinfo(const UniValue& params, bool fHelp)
if ( ASSETCHAINS_CC != 0 )
obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC));
obj.push_back(Pair("name", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL));
obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT));
obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT));
if ( ASSETCHAINS_SYMBOL[0] != 0 )
{
if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 )
obj.push_back(Pair("StakedEra", STAKED_ERA));
//obj.push_back(Pair("name", ASSETCHAINS_SYMBOL));
obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT));
obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT));
obj.push_back(Pair("magic", (int)ASSETCHAINS_MAGIC));
if ( ASSETCHAINS_SUPPLY != 0 )
obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY));

View File

@@ -168,42 +168,51 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
int32_t KOMODO_LONGESTCHAIN;
int32_t komodo_longestchain()
{
static int32_t depth;
int32_t ht,n=0,num=0,maxheight=0,height = 0;
vector<CNodeStats> vstats;
if ( depth < 0 )
depth = 0;
if ( depth == 0 )
{
LOCK(cs_main);
CopyNodeStats(vstats);
depth++;
vector<CNodeStats> vstats;
{
//LOCK(cs_main);
CopyNodeStats(vstats);
}
BOOST_FOREACH(const CNodeStats& stats, vstats)
{
//fprintf(stderr,"komodo_longestchain iter.%d\n",n);
CNodeStateStats statestats;
bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
if ( statestats.nSyncHeight < 0 )
continue;
ht = 0;
if ( stats.nStartingHeight > ht )
ht = stats.nStartingHeight;
if ( statestats.nSyncHeight > ht )
ht = statestats.nSyncHeight;
if ( statestats.nCommonHeight > ht )
ht = statestats.nCommonHeight;
if ( maxheight == 0 || ht > maxheight*1.01 )
maxheight = ht, num = 1;
else if ( ht > maxheight*0.99 )
num++;
if ( ht > height )
height = ht;
}
depth--;
if ( num > (n >> 1) )
{
extern char ASSETCHAINS_SYMBOL[];
if ( 0 && height != KOMODO_LONGESTCHAIN )
fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height);
KOMODO_LONGESTCHAIN = height;
return(height);
}
KOMODO_LONGESTCHAIN = 0;
}
BOOST_FOREACH(const CNodeStats& stats, vstats)
{
//fprintf(stderr,"komodo_longestchain iter.%d\n",n);
CNodeStateStats statestats;
bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
ht = 0;
if ( stats.nStartingHeight > ht )
ht = stats.nStartingHeight;
if ( statestats.nSyncHeight > ht )
ht = statestats.nSyncHeight;
if ( statestats.nCommonHeight > ht )
ht = statestats.nCommonHeight;
if ( maxheight == 0 || ht > maxheight*1.01 )
maxheight = ht, num = 1;
else if ( ht > maxheight*0.99 )
num++;
n++;
if ( ht > height )
height = ht;
}
if ( num > (n >> 1) )
{
extern char ASSETCHAINS_SYMBOL[];
if ( 0 && height != KOMODO_LONGESTCHAIN )
fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height);
KOMODO_LONGESTCHAIN = height;
return(height);
}
KOMODO_LONGESTCHAIN = 0;
return(0);
return(KOMODO_LONGESTCHAIN);
}
UniValue addnode(const UniValue& params, bool fHelp)

View File

@@ -242,7 +242,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
UniValue stop(const UniValue& params, bool fHelp)
{
char buf[64];
char buf[66+128];
// Accept the deprecated and ignored 'detach' boolean argument
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -263,6 +263,8 @@ static const CRPCCommand vRPCCommands[] =
/* Overall control/query calls */
{ "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */
{ "control", "help", &help, true },
{ "control", "getiguanajson", &getiguanajson, true },
{ "control", "getnotarysendmany", &getnotarysendmany, true },
{ "control", "stop", &stop, true },
/* P2P networking */
@@ -376,8 +378,8 @@ static const CRPCCommand vRPCCommands[] =
{ "faucet", "faucetget", &faucetget, true },
{ "faucet", "faucetaddress", &faucetaddress, true },
/* MofN */
{ "MofN", "mofnaddress", &mofnaddress, true },
/* Heir */
{ "heir", "heiraddress", &heiraddress, true },
/* Channels */
{ "channels", "channelsaddress", &channelsaddress, true },
@@ -427,6 +429,7 @@ static const CRPCCommand vRPCCommands[] =
{ "gateways", "gatewayspending", &gatewayspending, true },
{ "gateways", "gatewaysmultisig", &gatewaysmultisig, true },
{ "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
{ "gateways", "gatewayspartialsign", &gatewayspartialsign, true },
/* dice */
{ "dice", "dicelist", &dicelist, true },
@@ -494,7 +497,7 @@ static const CRPCCommand vRPCCommands[] =
{ "wallet", "getaccountaddress", &getaccountaddress, true },
{ "wallet", "getaccount", &getaccount, true },
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true },
{ "wallet", "cleanwalletnotarisations", &cleanwalletnotarisations, false },
{ "wallet", "cleanwallettransactions", &cleanwallettransactions, false },
{ "wallet", "getbalance", &getbalance, false },
{ "wallet", "getbalance64", &getbalance64, false },
{ "wallet", "getnewaddress", &getnewaddress, true },

View File

@@ -222,7 +222,7 @@ extern UniValue tokenask(const UniValue& params, bool fHelp);
extern UniValue tokencancelask(const UniValue& params, bool fHelp);
extern UniValue tokenfillask(const UniValue& params, bool fHelp);
extern UniValue tokenconvert(const UniValue& params, bool fHelp);
extern UniValue mofnaddress(const UniValue& params, bool fHelp);
extern UniValue heiraddress(const UniValue& params, bool fHelp);
extern UniValue channelsaddress(const UniValue& params, bool fHelp);
extern UniValue oraclesaddress(const UniValue& params, bool fHelp);
extern UniValue oracleslist(const UniValue& params, bool fHelp);
@@ -253,6 +253,7 @@ extern UniValue gatewayswithdraw(const UniValue& params, bool fHelp);
extern UniValue gatewayspending(const UniValue& params, bool fHelp);
extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp);
extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp);
extern UniValue gatewayspartialsign(const UniValue& params, bool fHelp);
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
extern UniValue channelsopen(const UniValue& params, bool fHelp);
extern UniValue channelspayment(const UniValue& params, bool fHelp);
@@ -299,7 +300,7 @@ extern UniValue signmessage(const UniValue& params, bool fHelp);
extern UniValue verifymessage(const UniValue& params, bool fHelp);
extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp);
extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp);
extern UniValue cleanwalletnotarisations(const UniValue& params, bool fHelp);
extern UniValue cleanwallettransactions(const UniValue& params, bool fHelp);
extern UniValue getbalance(const UniValue& params, bool fHelp);
extern UniValue getbalance64(const UniValue& params, bool fHelp);
extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp);
@@ -323,6 +324,8 @@ extern UniValue walletlock(const UniValue& params, bool fHelp);
extern UniValue encryptwallet(const UniValue& params, bool fHelp);
extern UniValue validateaddress(const UniValue& params, bool fHelp);
extern UniValue getinfo(const UniValue& params, bool fHelp);
extern UniValue getiguanajson(const UniValue& params, bool fHelp);
extern UniValue getnotarysendmany(const UniValue& params, bool fHelp);
extern UniValue setpubkey(const UniValue& params, bool fHelp);
extern UniValue getwalletinfo(const UniValue& params, bool fHelp);
extern UniValue getblockchaininfo(const UniValue& params, bool fHelp);

View File

@@ -246,7 +246,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
CPubKey pubKey(vSolutions[0]);
if (!pubKey.IsValid())
{
fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
//fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
return false;
}

View File

@@ -49,8 +49,10 @@ extern std::string ASSETCHAINS_OVERRIDE_PUBKEY;
extern int32_t ASSETCHAINS_STREAM;
extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
extern uint8_t ASSETCHAINS_PRIVATE;
extern int32_t USE_EXTERNAL_PUBKEY;
uint32_t komodo_segid32(char *coinaddr);
int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only
int64_t nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime;
@@ -1001,15 +1003,15 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef
return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
}
UniValue cleanwalletnotarisations(const UniValue& params, bool fHelp)
UniValue cleanwallettransactions(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() > 1 )
throw runtime_error(
"cleanwalletnotarisations \"txid\"\n"
"\nRemove all txs which are totally spent and all notarisations created from them, you can clear all txs bar one, by specifiying a txid.\n"
"cleanwallettransactions \"txid\"\n"
"\nRemove all txs that are spent. You can clear all txs bar one, by specifiying a txid.\n"
"\nPlease backup your wallet.dat before running this command.\n"
"\nArguments:\n"
"1. \"txid\" (string, optional) The transaction id to keep.\n"
@@ -1020,10 +1022,10 @@ UniValue cleanwalletnotarisations(const UniValue& params, bool fHelp)
" \"removed_transactons\" : n, (numeric) The number of transactions removed.\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("cleanoldtxs", "")
+ HelpExampleCli("cleanoldtxs","\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ HelpExampleRpc("cleanoldtxs", "")
+ HelpExampleRpc("cleanoldtxs","\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ HelpExampleCli("cleanwallettransactions", "")
+ HelpExampleCli("cleanwallettransactions","\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ HelpExampleRpc("cleanwallettransactions", "")
+ HelpExampleRpc("cleanwallettransactions","\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -1044,7 +1046,6 @@ UniValue cleanwalletnotarisations(const UniValue& params, bool fHelp)
{
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
txs++;
const CWalletTx& wtx = (*it).second;
if ( wtx.GetHash() != exception )
{
@@ -1060,65 +1061,33 @@ UniValue cleanwalletnotarisations(const UniValue& params, bool fHelp)
}
else
{
std::vector<CWalletTx> NotarisationTxs;
// get all locked utxos to relock them later.
vector<COutPoint> vLockedUTXO;
pwalletMain->ListLockedCoins(vLockedUTXO);
// unlock all coins so that the following call containes all utxos.
pwalletMain->UnlockAllCoins();
// listunspent call... this gets us all the txids that are unspent, we search this list for the oldest tx,
vector<COutput> vecOutputs;
assert(pwalletMain != NULL);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
int32_t oldestTxDepth = 0;
BOOST_FOREACH(const COutput& out, vecOutputs)
{
if ( out.nDepth > oldestTxDepth )
oldestTxDepth = out.nDepth;
}
oldestTxDepth = oldestTxDepth + 1; // add extra block just for safety.
// lock all the previouly locked coins.
BOOST_FOREACH(COutPoint &outpt, vLockedUTXO) {
pwalletMain->LockCoin(outpt);
}
// then add all txs in the wallet before this block to the list to remove.
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 360 )
continue;
CCoins coins;
if (!pcoinsTip->GetCoins(wtx.GetHash(), coins))
{
int spents = 0; int mine = 0;
for (unsigned int n = 0; n < wtx.vout.size() ; n++)
{
if ( pwalletMain->IsMine(wtx.vout[n]) )
mine++;
if ( ((unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() ) )
spents++;
}
if ( spents == mine )
{
for (unsigned int n = 0; n < wtx.vin.size() ; n++)
{
CTransaction vintx; uint256 hashBlock;
if ( GetTransaction(wtx.vin[n].prevout.hash,vintx,hashBlock,false) != 0 )
{
for (unsigned int z = 0; z < vintx.vin.size() ; z++)
{
TxToRemove.push_back(vintx.vin[z].prevout.hash);
}
}
TxToRemove.push_back(wtx.vin[n].prevout.hash);
}
TxToRemove.push_back(wtx.GetHash());
}
}
CTxDestination address;
// get all notarisations
if ( ExtractDestination(wtx.vout[0].scriptPubKey, address) )
{
if ( strcmp(CBitcoinAddress(address).ToString().c_str(),CRYPTO777_KMDADDR) == 0 )
NotarisationTxs.push_back(wtx);
}
}
// Erase notarisations spending from fully spent splits.
BOOST_FOREACH (CWalletTx& tx, NotarisationTxs)
{
for (int n = 0; n < tx.vin.size(); n++)
{
BOOST_FOREACH (uint256& SpentHash, TxToRemove)
{
if ( SpentHash == tx.vin[n].prevout.hash )
{
pwalletMain->EraseFromWallet(tx.GetHash());
LogPrintf("ERASED Notarisation: %s\n",tx.GetHash().ToString().c_str());
}
}
}
if (wtx.GetDepthInMainChain() > oldestTxDepth)
TxToRemove.push_back(wtx.GetHash());
}
}
@@ -1126,7 +1095,7 @@ UniValue cleanwalletnotarisations(const UniValue& params, bool fHelp)
BOOST_FOREACH (uint256& hash, TxToRemove)
{
pwalletMain->EraseFromWallet(hash);
LogPrintf("ERASED spent Tx: %s\n",hash.ToString().c_str());
LogPrintf("Erased %s from wallet.\n",hash.ToString().c_str());
}
// build return JSON for stats.
@@ -2887,7 +2856,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
uint64_t komodo_interestsum()
{
#ifdef ENABLE_WALLET
if ( GetBoolArg("-disablewallet", false) == 0 )
if ( ASSETCHAINS_SYMBOL[0] == 0 && GetBoolArg("-disablewallet", false) == 0 )
{
uint64_t interest,sum = 0; int32_t txheight; uint32_t locktime;
vector<COutput> vecOutputs;
@@ -3559,6 +3528,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
" \"txid\": xxxxx, (string) the transaction id\n"
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
" \"jsindex\": xxxxx, (numeric) the JoinSplit index\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
@@ -3600,6 +3570,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value))));
std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end());
obj.push_back(Pair("memo", HexStr(data)));
obj.push_back(Pair("jsindex", entry.jsop.js));
result.push_back(obj);
}
return result;
@@ -3937,7 +3908,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
}
}
else if ( ASSETCHAINS_PRIVATE != 0 )
else if ( ASSETCHAINS_PRIVATE != 0 && komodo_isnotaryvout((char *)address.c_str()) == 0 )
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain");
if (setAddress.count(address))
@@ -4692,7 +4663,7 @@ int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
extern std::string NOTARY_PUBKEY;
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);
int8_t komodo_stakehash(uint256 *hashp,char *address,uint8_t *hashbuf,uint256 txid,int32_t vout);
int32_t komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n);
void komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n);
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33)
{
@@ -5082,10 +5053,10 @@ extern std::string NOTARY_PUBKEY,NOTARY_ADDRESS;
UniValue setpubkey(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ);
if ( fHelp || params.size() != 1 )
if ( fHelp || params.size() > 1 )
throw runtime_error(
"setpubkey\n"
"\nSets the -pubkey if the daemon was not started with it, if it was already set, it returns the pubkey.\n"
"\nSets the -pubkey if the daemon was not started with it, if it was already set, it returns the pubkey, and its Raddress.\n"
"\nArguments:\n"
"1. \"pubkey\" (string) pubkey to set.\n"
"\nResult:\n"
@@ -5117,26 +5088,31 @@ UniValue setpubkey(const UniValue& params, bool fHelp)
CTxDestination dest = address.Get();
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
if ( mine == ISMINE_NO ) {
result.push_back(Pair("error", "privkey for this pubkey is not imported to wallet!"));
result.push_back(Pair("WARNING", "privkey for this pubkey is not imported to wallet!"));
} else {
result.push_back(Pair("ismine", "true"));
NOTARY_ADDRESS = address.ToString();
std::string notaryname;
if ( (IS_STAKED_NOTARY= StakedNotaryID(notaryname, Raddress)) > -1 ) {
result.push_back(Pair("IsNotary", notaryname));
IS_KOMODO_NOTARY = 0;
USE_EXTERNAL_PUBKEY = 1;
}
NOTARY_PUBKEY = params[0].get_str();
decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str());
}
} else
NOTARY_PUBKEY = params[0].get_str();
decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str());
USE_EXTERNAL_PUBKEY = 1;
NOTARY_ADDRESS = address.ToString();
} else {
result.push_back(Pair("error", "pubkey entered is invalid."));
}
}
} else {
result.push_back(Pair("error", "pubkey is wrong length, must be 66 char hex string."));
}
} else {
if ( NOTARY_ADDRESS.empty() ) {
pubkey2addr((char *)Raddress,(uint8_t *)NOTARY_PUBKEY33);
NOTARY_ADDRESS.assign(Raddress);
}
result.push_back(Pair("error", "Can only set pubkey once, to change it you need to restart your daemon."));
}
if ( NOTARY_PUBKEY33[0] != 0 && !NOTARY_ADDRESS.empty() ) {
@@ -5262,17 +5238,17 @@ UniValue gatewaysaddress(const UniValue& params, bool fHelp)
return(CCaddress(cp,(char *)"Gateways",pubkey));
}
UniValue mofnaddress(const UniValue& params, bool fHelp)
UniValue heiraddress(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
cp = CCinit(&C,EVAL_MOFN);
cp = CCinit(&C,EVAL_HEIR);
if ( fHelp || params.size() > 1 )
throw runtime_error("mofnaddress [pubkey]\n");
throw runtime_error("heiraddress [pubkey]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
if ( params.size() == 1 )
pubkey = ParseHex(params[0].get_str().c_str());
return(CCaddress(cp,(char *)"MofN",pubkey));
return(CCaddress(cp,(char *)"Heir",pubkey));
}
UniValue lottoaddress(const UniValue& params, bool fHelp)
@@ -5503,7 +5479,7 @@ UniValue rewardscreatefunding(const UniValue& params, bool fHelp)
minseconds = maxseconds = 60 * 3600 * 24;
mindeposit = 100 * COIN;
name = (char *)params[0].get_str().c_str();
funds = atof(params[1].get_str().c_str()) * COIN;
funds = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999;
if (!VALID_PLAN_NAME(name)) {
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
@@ -5541,7 +5517,7 @@ UniValue rewardscreatefunding(const UniValue& params, bool fHelp)
return result;
}
if ( params.size() > 5 )
mindeposit = atof(params[5].get_str().c_str()) * COIN;
mindeposit = atof(params[5].get_str().c_str()) * COIN + 0.00000000499999;
if ( mindeposit <= 0 ) {
ERR_RESULT("mindeposit must be positive");
return result;
@@ -5569,7 +5545,7 @@ UniValue rewardslock(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
name = (char *)params[0].get_str().c_str();
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = RewardsLock(0,name,fundingtxid,amount);
if (!VALID_PLAN_NAME(name)) {
@@ -5599,7 +5575,7 @@ UniValue rewardsaddfunding(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
name = (char *)params[0].get_str().c_str();
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = RewardsAddfunding(0,name,fundingtxid,amount);
if (!VALID_PLAN_NAME(name)) {
@@ -5742,7 +5718,7 @@ UniValue gatewaysdeposit(const UniValue& params, bool fHelp)
deposithex = params[5].get_str();
proof = ParseHex(params[6].get_str());
destpub = ParseHex(params[7].get_str());
amount = atof((char *)params[8].get_str().c_str()) * COIN;
amount = atof((char *)params[8].get_str().c_str()) * COIN + 0.00000000499999;
if ( amount <= 0 || claimvout < 0 )
throw runtime_error("invalid param: amount, numpks or claimvout\n");
hex = GatewaysDeposit(0,bindtxid,height,coin,cointxid,claimvout,deposithex,proof,pubkey2pk(destpub),amount);
@@ -5767,7 +5743,7 @@ UniValue gatewaysclaim(const UniValue& params, bool fHelp)
coin = params[1].get_str();
deposittxid = Parseuint256((char *)params[2].get_str().c_str());
destpub = ParseHex(params[3].get_str());
amount = atof((char *)params[4].get_str().c_str()) * COIN;
amount = atof((char *)params[4].get_str().c_str()) * COIN + 0.00000000499999;
hex = GatewaysClaim(0,bindtxid,coin,deposittxid,pubkey2pk(destpub),amount);
if ( hex.size() > 0 )
{
@@ -5789,8 +5765,8 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp)
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
withdrawpub = ParseHex(params[2].get_str());
amount = atof((char *)params[3].get_str().c_str()) * COIN;
hex = GatewaysWithdraw(0,bindtxid,coin,withdrawpub,amount);
amount = atof((char *)params[3].get_str().c_str()) * COIN + 0.00000000499999;
hex = GatewaysWithdraw(0,bindtxid,coin,pubkey2pk(withdrawpub),amount);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
@@ -5834,18 +5810,30 @@ UniValue gatewayspending(const UniValue& params, bool fHelp)
UniValue gatewaysmultisig(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint256 bindtxid,withtxid; std::string coin,hex; char *txidaddr;
if ( fHelp || params.size() != 2 )
throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\n");
UniValue result(UniValue::VOBJ); std::string hex; char *txidaddr;
if ( fHelp || params.size() != 1 )
throw runtime_error("gatewaysmultisig txidaddr\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
txidaddr = (char *)params[0].get_str().c_str();
return(GatewaysMultisig(txidaddr));
}
UniValue gatewayspartialsign(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string coin,parthex,hex; uint256 txid;
if ( fHelp || params.size() != 3 )
throw runtime_error("gatewayspartialsign txidaddr refcoin hex\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
withtxid = Parseuint256((char *)params[2].get_str().c_str());
txidaddr = (char *)params[3].get_str().c_str();
hex = GatewaysMultisig(0,coin,bindtxid,withtxid,txidaddr);
parthex = params[2].get_str();
hex = GatewaysPartialSign(0,txid,coin,parthex);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
@@ -5884,7 +5872,8 @@ UniValue oraclesregister(const UniValue& params, bool fHelp)
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str());
datafee = atol((char *)params[1].get_str().c_str());
if ( (datafee= atol((char *)params[1].get_str().c_str())) == 0 )
datafee = atof((char *)params[1].get_str().c_str()) * COIN + 0.00000000499999;
hex = OracleRegister(0,txid,datafee);
if ( hex.size() > 0 )
{
@@ -5905,7 +5894,7 @@ UniValue oraclessubscribe(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str());
pubkey = ParseHex(params[1].get_str().c_str());
amount = atof((char *)params[2].get_str().c_str()) * COIN;
amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = OracleSubscribe(0,txid,pubkey2pk(pubkey),amount);
if ( hex.size() > 0 )
{
@@ -6062,7 +6051,7 @@ UniValue faucetfund(const UniValue& params, bool fHelp)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
funds = atof(params[0].get_str().c_str()) * COIN;
funds = atof(params[0].get_str().c_str()) * COIN + 0.00000000499999;
if (funds > 0) {
hex = FaucetFund(0,(uint64_t) funds);
if ( hex.size() > 0 )
@@ -6127,7 +6116,7 @@ UniValue pricescreate(const UniValue& params, bool fHelp)
longtoken = Parseuint256((char *)params[4].get_str().c_str());
shorttoken = Parseuint256((char *)params[5].get_str().c_str());
maxleverage = atol(params[6].get_str().c_str());
funding = atof(params[7].get_str().c_str()) * COIN;
funding = atof(params[7].get_str().c_str()) * COIN + 0.00000000499999;
n = atoi(params[8].get_str().c_str());
if ( n > 0 )
{
@@ -6163,7 +6152,7 @@ UniValue pricesaddfunding(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
bettoken = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = PricesAddFunding(0,bettoken,fundingtxid,amount);
if ( hex.size() > 0 )
{
@@ -6188,7 +6177,7 @@ UniValue pricesbet(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
fundingtxid = Parseuint256((char *)params[0].get_str().c_str());
bettoken = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
leverage = atoi(params[3].get_str().c_str());
hex = PricesBet(0,bettoken,fundingtxid,amount,leverage);
if ( hex.size() > 0 )
@@ -6251,9 +6240,9 @@ UniValue dicefund(const UniValue& params, bool fHelp)
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
name = (char *)params[0].get_str().c_str();
funds = atof(params[1].get_str().c_str()) * COIN;
minbet = atof(params[2].get_str().c_str()) * COIN;
maxbet = atof(params[3].get_str().c_str()) * COIN;
funds = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999;
minbet = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
maxbet = atof(params[3].get_str().c_str()) * COIN + 0.00000000499999;
maxodds = atol(params[4].get_str().c_str());
timeoutblocks = atol(params[5].get_str().c_str());
@@ -6285,7 +6274,7 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
name = (char *)params[0].get_str().c_str();
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
if (!VALID_PLAN_NAME(name)) {
ERR_RESULT(strprintf("Plan name can be at most %d ASCII characters",PLAN_NAME_MAX));
return(result);
@@ -6304,7 +6293,7 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp)
UniValue dicebet(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid; int64_t amount,odds; char *name;
UniValue result(UniValue::VOBJ); std::string hex,error; uint256 fundingtxid; int64_t amount,odds; char *name;
if ( fHelp || params.size() != 4 )
throw runtime_error("dicebet name fundingtxid amount odds\n");
if ( ensure_CCrequirements() < 0 )
@@ -6313,7 +6302,7 @@ UniValue dicebet(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
name = (char *)params[0].get_str().c_str();
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
amount = atof(params[2].get_str().c_str()) * COIN;
amount = atof(params[2].get_str().c_str()) * COIN + 0.00000000499999;
odds = atol(params[3].get_str().c_str());
if (!VALID_PLAN_NAME(name)) {
@@ -6322,14 +6311,12 @@ UniValue dicebet(const UniValue& params, bool fHelp)
}
if (amount > 0 && odds > 0) {
hex = DiceBet(0,name,fundingtxid,amount,odds);
if ( CCerror != "" )
{
ERR_RESULT(CCerror);
} else if ( hex.size() > 0 )
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt create dice bet transaction. make sure your address has funds");
}
} else {
ERR_RESULT("amount and odds must be positive");
}
@@ -6338,7 +6325,7 @@ UniValue dicebet(const UniValue& params, bool fHelp)
UniValue dicefinish(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string hex; int32_t r;
UniValue result(UniValue::VOBJ); uint8_t funcid; char *name; uint256 entropyused,fundingtxid,bettxid; std::string hex; int32_t r,entropyvout;
if ( fHelp || params.size() != 3 )
throw runtime_error("dicefinish name fundingtxid bettxid\n");
if ( ensure_CCrequirements() < 0 )
@@ -6352,7 +6339,7 @@ UniValue dicefinish(const UniValue& params, bool fHelp)
}
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
bettxid = Parseuint256((char *)params[2].get_str().c_str());
hex = DiceBetFinish(&r,0,name,fundingtxid,bettxid,1);
hex = DiceBetFinish(funcid,entropyused,entropyvout,&r,0,name,fundingtxid,bettxid,1,zeroid,-1);
if ( CCerror != "" )
{
ERR_RESULT(CCerror);
@@ -6360,13 +6347,20 @@ UniValue dicefinish(const UniValue& params, bool fHelp)
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
if ( funcid != 0 )
{
char funcidstr[2];
funcidstr[0] = funcid;
funcidstr[1] = 0;
result.push_back(Pair("funcid", funcidstr));
}
} else ERR_RESULT( "couldnt create dicefinish transaction");
return(result);
}
UniValue dicestatus(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string status; double winnings;
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string status,error; double winnings;
if ( fHelp || (params.size() != 2 && params.size() != 3) )
throw runtime_error("dicestatus name fundingtxid bettxid\n");
if ( ensure_CCrequirements() < 0 )
@@ -6383,10 +6377,8 @@ UniValue dicestatus(const UniValue& params, bool fHelp)
if ( params.size() == 3 )
bettxid = Parseuint256((char *)params[2].get_str().c_str());
winnings = DiceStatus(0,name,fundingtxid,bettxid);
if (CCerror != "") {
ERR_RESULT(CCerror);
return result;
}
RETURN_IF_ERROR(CCerror);
result.push_back(Pair("result", "success"));
if ( winnings >= 0. )
{
@@ -6499,7 +6491,7 @@ UniValue tokencreate(const UniValue& params, bool fHelp)
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
name = params[0].get_str();
supply = atof(params[1].get_str().c_str()) * COIN;
supply = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999;
if ( name.size() == 0 || name.size() > 32)
{
ERR_RESULT("Token name must not be empty and up to 32 characters");

View File

@@ -1208,4 +1208,6 @@ public:
/** Error status printout */
#define ERR_RESULT(x) result.push_back(Pair("result", "error")) , result.push_back(Pair("error", x));
#define RETURN_IF_ERROR(CCerror) if ( CCerror != "" ) { ERR_RESULT(CCerror); return(result); }
#endif // BITCOIN_WALLET_WALLET_H