Merge branch 'dev' of https://github.com/blackjok3rtt/komodo into dev
p
This commit is contained in:
@@ -261,7 +261,6 @@ BITCOIN_CORE_H = \
|
||||
wallet/wallet.h \
|
||||
wallet/wallet_ismine.h \
|
||||
wallet/walletdb.h \
|
||||
veruslaunch.h \
|
||||
zmq/zmqabstractnotifier.h \
|
||||
zmq/zmqconfig.h\
|
||||
zmq/zmqnotificationinterface.h \
|
||||
@@ -483,7 +482,6 @@ libbitcoin_common_a_SOURCES = \
|
||||
script/script_error.cpp \
|
||||
script/sign.cpp \
|
||||
script/standard.cpp \
|
||||
veruslaunch.cpp \
|
||||
transaction_builder.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
@@ -10,7 +10,6 @@ komodo_test_SOURCES = \
|
||||
test-komodo/test_coinimport.cpp \
|
||||
test-komodo/test_eval_bet.cpp \
|
||||
test-komodo/test_eval_notarisation.cpp \
|
||||
test-komodo/test_crosschain.cpp \
|
||||
test-komodo/test_parse_notarisation.cpp
|
||||
|
||||
komodo_test_CPPFLAGS = $(komodod_CPPFLAGS)
|
||||
|
||||
@@ -11,7 +11,7 @@ if [ -z "$delay" ]; then delay=20; fi
|
||||
./listassetchainparams | while read args; do
|
||||
gen=""
|
||||
if [ $[RANDOM % 10] == 1 ]; then
|
||||
gen=" -gen"
|
||||
gen=" -gen -genproclimit=1"
|
||||
fi
|
||||
|
||||
./komodod $gen $args $overide_args -pubkey=$pubkey -addnode=$seed_ip &
|
||||
|
||||
@@ -94,7 +94,8 @@
|
||||
},
|
||||
{
|
||||
"ac_name": "OOT",
|
||||
"ac_supply": "216000000"
|
||||
"ac_supply": "216000000",
|
||||
"ac_sapling": "5000000"
|
||||
},
|
||||
{
|
||||
"ac_name": "BNTN",
|
||||
@@ -177,18 +178,6 @@
|
||||
"190.114.254.104"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ac_name": "KMDICE",
|
||||
"ac_supply": "10500000",
|
||||
"ac_reward": "2500000000",
|
||||
"ac_halving": "210000",
|
||||
"ac_cc": "2",
|
||||
"addressindex": "1",
|
||||
"spentindex": "1",
|
||||
"addnode": [
|
||||
"144.76.217.232"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ac_name": "DION",
|
||||
"ac_supply": "3900000000",
|
||||
|
||||
@@ -27,7 +27,7 @@ echo $pubkey
|
||||
./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=PIZZA -ac_supply=100000000 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=NINJA -ac_supply=100000000 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -addnode=174.138.107.226 &
|
||||
./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -ac_saplinig=5000000 -addnode=174.138.107.226 &
|
||||
./komodod -pubkey=$pubkey -ac_name=BNTN -ac_supply=500000000 -addnode=94.130.169.205 &
|
||||
./komodod -pubkey=$pubkey -ac_name=CHAIN -ac_supply=999999 -addnode=78.47.146.222 &
|
||||
./komodod -pubkey=$pubkey -ac_name=PRLPAY -ac_supply=500000000 -addnode=13.250.226.125 &
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/keyvalq_struct.h>
|
||||
#include "support/events.h"
|
||||
uint16_t BITCOIND_RPCPORT = 7771;
|
||||
char ASSETCHAINS_SYMBOL[65];
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
@@ -64,27 +66,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#define FROM_CLI
|
||||
#include "uint256.h"
|
||||
#include "arith_uint256.h"
|
||||
|
||||
#include "komodo_structs.h"
|
||||
|
||||
#include "komodo_globals.h"
|
||||
#include "komodo_utils.h"
|
||||
#include "komodo_cJSON.c"
|
||||
#include "komodo_notary.h"
|
||||
|
||||
void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t komodo_heightstamp(int32_t height)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
//
|
||||
// This function returns either one of EXIT_ codes when it's expected to stop the process or
|
||||
// CONTINUE_EXECUTION when it's expected to continue further.
|
||||
@@ -99,7 +80,11 @@ static int AppInitRPC(int argc, char* argv[])
|
||||
// Parameters
|
||||
//
|
||||
ParseParameters(argc, argv);
|
||||
komodo_args(argv[0]);
|
||||
std:string name;
|
||||
name = GetArg("-ac_name","");
|
||||
if ( !name.empty() )
|
||||
strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1);
|
||||
|
||||
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) {
|
||||
std::string strUsage = _("Komodo RPC client version") + " " + FormatFullVersion() + "\n" + PrivacyInfo();
|
||||
if (!mapArgs.count("-version")) {
|
||||
|
||||
@@ -35,7 +35,7 @@ CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t
|
||||
bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description);
|
||||
uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector<uint8_t> &origpubkey);
|
||||
bool SetAssetOrigpubkey(std::vector<uint8_t> &origpubkey,int64_t &price,const CTransaction &tx);
|
||||
int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid);
|
||||
int64_t IsAssetvout(int32_t maxAssetExactAmountDepth, struct CCcontract_info *cp, Eval* eval, int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid);
|
||||
bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
||||
bool ValidateAskRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
||||
bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice);
|
||||
@@ -44,7 +44,8 @@ bool SetAskFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValu
|
||||
bool SetSwapFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice);
|
||||
int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid);
|
||||
int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector<uint8_t> &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid);
|
||||
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid);
|
||||
bool AssetExactAmounts(int32_t maxDepth, struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid);
|
||||
//bool AssetExactAmounts(bool doValidateTx, struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid, std::vector<CTransaction> &ccVinsTxs);
|
||||
|
||||
// CCassetstx
|
||||
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid);
|
||||
|
||||
@@ -342,25 +342,54 @@ bool GetAssetorigaddrs(struct CCcontract_info *cp,char *CCaddr,char *destaddr,co
|
||||
else return(false);
|
||||
}
|
||||
|
||||
int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid)
|
||||
|
||||
// Checks if the vout is a really Asset CC vout
|
||||
// if maxAssetExactAmountDepth > 0, it also validates the vin transaction itself:
|
||||
// it should be either sum(cc vins) == sum(cc vouts) or the transaction is the 'tokenbase' ('c') tx
|
||||
int64_t IsAssetvout(int32_t maxAssetExactAmountDepth, struct CCcontract_info *cp, Eval* eval, int64_t &price,std::vector<uint8_t> &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid)
|
||||
{
|
||||
uint256 assetid,assetid2; int64_t nValue=0; int32_t n; uint8_t funcid;
|
||||
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // maybe check address too?
|
||||
{
|
||||
n = tx.vout.size();
|
||||
|
||||
if (maxAssetExactAmountDepth > 0) {
|
||||
//validate all tx
|
||||
int64_t myCCVinsAmount = 0, myCCVoutsAmount = 0;
|
||||
std::vector<CTransaction> ccVinsTxs;
|
||||
|
||||
//std::cerr << "IsAssetvout() validate=yes" << std::endl;
|
||||
const bool validateVinTxs = false;
|
||||
bool isEqualAmounts = AssetExactAmounts(maxAssetExactAmountDepth, cp, myCCVinsAmount, 0, myCCVoutsAmount, eval, tx, refassetid);
|
||||
|
||||
// if ccInputs != ccOutputs and it is not the tokenbase tx means it is possibly fake tx (dimxy):
|
||||
if (!isEqualAmounts && refassetid != tx.GetHash()) { // checking that this is the true tokenbase tx, by verifying that funcid=c, is done further in this function (dimxy)
|
||||
std::cerr << "IsAssetvout() detected bad tx=" << tx.GetHash().GetHex() << ": cc inputs != cc outputs and not the 'tokenbase' tx" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
n = tx.vout.size();
|
||||
if (v >= n - 1) { // just moved this up (dimxy)
|
||||
std::cerr << "isAssetVout() internal err: (v >= n - 1), returning 0" << std::endl;
|
||||
return(0);
|
||||
}
|
||||
nValue = tx.vout[v].nValue;
|
||||
//fprintf(stderr,"CC vout v.%d of n.%d %.8f\n",v,n,(double)nValue/COIN);
|
||||
if ( v >= n-1 )
|
||||
return(0);
|
||||
|
||||
// fprintf(stderr,"IsAssetvout() CC vout v.%d of n=%d amount=%.8f\n",v,n,(double)nValue/COIN);
|
||||
|
||||
if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"null decodeopret v.%d\n",v);
|
||||
fprintf(stderr,"IsAssetvout() null decodeopret v.%d\n",v);
|
||||
return(0);
|
||||
}
|
||||
else if ( funcid == 'c' )
|
||||
{
|
||||
if ( refassetid == tx.GetHash() && v == 0 )
|
||||
return(nValue);
|
||||
if (refassetid == tx.GetHash() && v == 0) {
|
||||
std::cerr << "isAssetVout() this is the tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " returning nValue=" << nValue << std::endl;
|
||||
return(nValue);
|
||||
}
|
||||
}
|
||||
else if ( (funcid == 'b' || funcid == 'B') && v == 0 ) // critical! 'b'/'B' vout0 is NOT asset
|
||||
return(0);
|
||||
@@ -368,7 +397,7 @@ int64_t IsAssetvout(int64_t &price,std::vector<uint8_t> &origpubkey,const CTrans
|
||||
{
|
||||
if ( assetid == refassetid )
|
||||
{
|
||||
//fprintf(stderr,"returning %.8f\n",(double)nValue/COIN);
|
||||
fprintf(stderr,"IsAssetvout() returning %.8f\n",(double)nValue/COIN);
|
||||
return(nValue);
|
||||
}
|
||||
}
|
||||
@@ -443,29 +472,37 @@ int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpp
|
||||
fprintf(stderr,"AssetValidateSellvin\n");
|
||||
if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 )
|
||||
return(0);
|
||||
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 )
|
||||
if ( (assetoshis= IsAssetvout(1, cp, NULL, tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 )
|
||||
return eval->Invalid("invalid missing CC vout0 for sellvin");
|
||||
else return(assetoshis);
|
||||
}
|
||||
|
||||
bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid)
|
||||
|
||||
// overload with additional params for deep tx validation (dimxy)
|
||||
bool AssetExactAmounts(int maxDepth, struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid)
|
||||
{
|
||||
CTransaction vinTx; uint256 hashBlock,id,id2; int32_t i,flag,numvins,numvouts; int64_t assetoshis; std::vector<uint8_t> tmporigpubkey; int64_t tmpprice;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
inputs = outputs = 0;
|
||||
|
||||
maxDepth--;
|
||||
|
||||
for (i=starti; i<numvins; i++)
|
||||
{
|
||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
||||
{
|
||||
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
|
||||
{
|
||||
//std::cerr << "AssetExactAmounts() eval is true=" << (eval != NULL) << " ismyvin=ok for_i=" << i << std::endl;
|
||||
// we are really not inside validation! -- dimxy
|
||||
if ( (eval && eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0) || (!eval && !myGetTransaction(tx.vin[i].prevout.hash, vinTx, hashBlock)) )
|
||||
{
|
||||
fprintf(stderr,"i.%d starti.%d numvins.%d\n",i,starti,numvins);
|
||||
return eval->Invalid("always should find vin, but didnt");
|
||||
}
|
||||
else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 )
|
||||
fprintf(stderr,"AssetExactAmounts() cannot read vintx i.%d starti.%d numvins.%d\n", i,starti,numvins);
|
||||
return (!eval) ? false : eval->Invalid("always should find vin, but didnt");
|
||||
|
||||
} // false means 'don't go deeper' -- dimxy
|
||||
else if ( (assetoshis= IsAssetvout( maxDepth, cp, eval, tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 )
|
||||
{
|
||||
fprintf(stderr,"vin%d %llu, ",i,(long long)assetoshis);
|
||||
fprintf(stderr,"AssetExactAmounts() vin%d %llu, ",i,(long long)assetoshis);
|
||||
inputs += assetoshis;
|
||||
}
|
||||
else
|
||||
@@ -473,33 +510,47 @@ bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti
|
||||
if ( vinTx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 && DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
|
||||
{
|
||||
assetoshis = vinTx.vout[i].nValue;
|
||||
fprintf(stderr,"vin%d %llu special case, ",i,(long long)assetoshis);
|
||||
fprintf(stderr,"AssetExactAmounts() vin%d assetoshis=%llu special case, ",i,(long long)assetoshis);
|
||||
inputs += assetoshis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid )
|
||||
flag = 1;
|
||||
else flag = 0;
|
||||
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,tx,i,assetid)) != 0 )
|
||||
{ // 'false' means 'dont go deep' -- dimxy
|
||||
if ( (assetoshis= IsAssetvout(maxDepth, cp, eval, tmpprice,tmporigpubkey,tx,i,assetid)) != 0 )
|
||||
{
|
||||
fprintf(stderr,"vout%d %llu, ",i,(long long)assetoshis);
|
||||
fprintf(stderr,"AssetExactAmounts() vout%d assetoshis=%llu, ",i,(long long)assetoshis);
|
||||
outputs += assetoshis;
|
||||
}
|
||||
// Note: account it only if this is 'transfer' tx -- dimxy
|
||||
else if ( flag != 0 && tx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
assetoshis = tx.vout[i].nValue;
|
||||
fprintf(stderr,"vout%d %llu special case, ",i,(long long)assetoshis);
|
||||
fprintf(stderr,"AssetExactAmounts() vout%d assetoshis=%llu special case, ",i,(long long)assetoshis);
|
||||
outputs += assetoshis;
|
||||
}
|
||||
}
|
||||
|
||||
//std::cerr << "AssetExactAmounts() inputs=" << inputs << " outputs=" << outputs << " for txid=" << tx.GetHash().GetHex() << std::endl;
|
||||
|
||||
if ( inputs != outputs )
|
||||
{
|
||||
fprintf(stderr,"inputs %.8f vs %.8f outputs\n",(double)inputs/COIN,(double)outputs/COIN);
|
||||
std::cerr << "AssetExactAmounts() incorrect inputs=" << (double)inputs / COIN << " vs outputs=" << (double)outputs/COIN << " for txid=" << tx.GetHash().GetHex() << std::endl;
|
||||
return(false);
|
||||
}
|
||||
else return(true);
|
||||
}
|
||||
|
||||
// overload for existing calls of this function (dimxy)
|
||||
/*bool AssetExactAmounts(struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid) {
|
||||
std::vector<CTransaction> ccVinsTxs;
|
||||
|
||||
return AssetExactAmounts(true, cp, inputs, starti, outputs, eval, tx, assetid);
|
||||
}*/
|
||||
@@ -38,25 +38,29 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
Getscriptaddress(destaddr,vintx.vout[vout].scriptPubKey);
|
||||
if ( strcmp(destaddr,coinaddr) != 0 && strcmp(destaddr,cp->unspendableCCaddr) != 0 && strcmp(destaddr,cp->unspendableaddr2) != 0 )
|
||||
continue;
|
||||
fprintf(stderr,"check %s %.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN);
|
||||
if ( (nValue= IsAssetvout(price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
fprintf(stderr,"AddAssetInputs() check destaddress=%s vout amount=%.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN);
|
||||
if ( (nValue= IsAssetvout(1, cp, NULL, price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
//std::cerr << "AddAssetInputs() adding input nValue=" << nValue << std::endl;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//std::cerr << "AddAssetInputs() found totalinputs=" << totalinputs << std::endl;
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
int64_t GetAssetBalance(CPubKey pk,uint256 tokenid)
|
||||
{
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
return(AddAssetInputs(cp,mtx,pk,tokenid,0,0));
|
||||
}
|
||||
@@ -186,7 +190,8 @@ UniValue AssetOrders(uint256 refassetid)
|
||||
|
||||
std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
if ( assetsupply < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply);
|
||||
@@ -212,7 +217,8 @@ std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::
|
||||
|
||||
std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
if ( total < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative total %lld\n",(long long)total);
|
||||
@@ -232,6 +238,11 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 )
|
||||
{
|
||||
|
||||
if (inputs < total) { //added dimxy
|
||||
std::cerr << "AssetTransfer(): insufficient funds" << std::endl;
|
||||
return ("");
|
||||
}
|
||||
if ( inputs > total )
|
||||
CCchange = (inputs - total);
|
||||
//for (i=0; i<n; i++)
|
||||
@@ -247,7 +258,8 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector<uint8_t> des
|
||||
|
||||
std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> destpubkey,int64_t total,int32_t evalcode)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C;
|
||||
if ( total < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative total %lld\n",(long long)total);
|
||||
@@ -273,7 +285,8 @@ std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector<uint8_t> dest
|
||||
|
||||
std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector<uint8_t> origpubkey; std::string name,description;
|
||||
if ( bidamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal);
|
||||
@@ -303,7 +316,11 @@ std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64
|
||||
|
||||
std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
|
||||
//std::cerr << "CreateSell() askamount=" << askamount << " pricetotal=" << pricetotal << std::endl;
|
||||
|
||||
if ( askamount < 0 || pricetotal < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount);
|
||||
@@ -318,8 +335,12 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,askamount,60)) > 0 )
|
||||
{
|
||||
if ( inputs < askamount )
|
||||
askamount = inputs;
|
||||
if (inputs < askamount) {
|
||||
//askamount = inputs;
|
||||
std::cerr << "CreateSell(): insufficient tokens for ask" << std::endl;
|
||||
return ("");
|
||||
}
|
||||
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0)));
|
||||
if ( inputs > askamount )
|
||||
CCchange = (inputs - askamount);
|
||||
@@ -327,15 +348,21 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk));
|
||||
opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey());
|
||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
|
||||
} else fprintf(stderr,"need some assets to place ask\n");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "need some assets to place ask\n");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"need some native coins to place ask\n");
|
||||
else { // dimxy added 'else', because it was misleading message before
|
||||
fprintf(stderr, "need some native coins to place ask\n");
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C;
|
||||
fprintf(stderr,"asset swaps disabled\n");
|
||||
return("");
|
||||
if ( askamount < 0 || pricetotal < 0 )
|
||||
@@ -366,15 +393,22 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
||||
opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey());
|
||||
}
|
||||
return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret));
|
||||
} else fprintf(stderr,"need some assets to place ask\n");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "need some assets to place ask\n");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"need some native coins to place ask\n");
|
||||
else { // dimxy added 'else', because it was misleading message before
|
||||
fprintf(stderr,"need some native coins to place ask\n");
|
||||
}
|
||||
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -395,7 +429,8 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
|
||||
std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ASSETS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -416,7 +451,8 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
|
||||
std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount)
|
||||
{
|
||||
CTransaction vintx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx; uint256 hashBlock; CPubKey mypk; std::vector<uint8_t> origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
if ( fillamount < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount);
|
||||
@@ -456,7 +492,8 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
|
||||
std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillunits)
|
||||
{
|
||||
CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction vintx,filltx; uint256 hashBlock; CPubKey mypk; std::vector<uint8_t> origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
if ( fillunits < 0 )
|
||||
{
|
||||
CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits);
|
||||
|
||||
@@ -105,6 +105,7 @@ extern CWallet* pwalletMain;
|
||||
#endif
|
||||
bool GetAddressUnspent(uint160 addressHash, int type,std::vector<std::pair<CAddressUnspentKey,CAddressUnspentValue> > &unspentOutputs);
|
||||
CBlockIndex *komodo_getblockindex(uint256 hash);
|
||||
int32_t komodo_nextheight();
|
||||
|
||||
static const uint256 zeroid;
|
||||
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
|
||||
@@ -177,6 +178,7 @@ std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTr
|
||||
void SetCCunspents(std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs,char *coinaddr);
|
||||
void SetCCtxids(std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,char *coinaddr);
|
||||
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs);
|
||||
int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs);
|
||||
int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout);
|
||||
|
||||
// curve25519 and sha256
|
||||
|
||||
127
src/cc/CCtx.cpp
127
src/cc/CCtx.cpp
@@ -62,8 +62,26 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
GetCCaddress(cp,myaddr,mypk);
|
||||
mycond = MakeCCcond1(cp->evalcode,mypk);
|
||||
GetCCaddress(cp,unspendable,unspendablepk);
|
||||
othercond = MakeCCcond1(cp->evalcode,unspendablepk);
|
||||
//fprintf(stderr,"myCCaddr.(%s) %p vs unspendable.(%s) %p\n",myaddr,mycond,unspendable,othercond);
|
||||
othercond = MakeCCcond1(cp->evalcode,unspendablepk);
|
||||
//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.
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
|
||||
{
|
||||
if ( vintx.vout[mtx.vin[i].prevout.n].scriptPubKey.IsPayToCryptoCondition() == 0 && ccvins==0)
|
||||
normalvins++;
|
||||
else ccvins++;
|
||||
}
|
||||
}
|
||||
if (normalvins>1 && ccvins)
|
||||
{
|
||||
for(i=1;i<normalvins;i++)
|
||||
{
|
||||
mtx.vin.push_back(mtx.vin[1]);
|
||||
mtx.vin.erase(mtx.vin.begin() + 1);
|
||||
}
|
||||
}
|
||||
memset(utxovalues,0,sizeof(utxovalues));
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
@@ -74,14 +92,12 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
totalinputs += utxovalues[i];
|
||||
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||
{
|
||||
//fprintf(stderr,"vin.%d is normal %.8f\n",i,(double)utxovalues[i]/COIN);
|
||||
if (ccvins==0) normalvins++;
|
||||
//fprintf(stderr,"vin.%d is normal %.8f\n",i,(double)utxovalues[i]/COIN);
|
||||
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());
|
||||
@@ -98,16 +114,6 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
mtx.vout.push_back(CTxOut(0,opret));
|
||||
PrecomputedTransactionData txdata(mtx);
|
||||
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 )
|
||||
@@ -431,3 +437,92 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs)
|
||||
{
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=64; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > maxutxos )
|
||||
maxutxos = maxinputs;
|
||||
sum = 0;
|
||||
Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG);
|
||||
SetCCunspents(unspentOutputs,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;
|
||||
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++)
|
||||
if ( txid == mtx.vin[i].prevout.hash && vout == mtx.vin[i].prevout.n )
|
||||
break;
|
||||
if ( i != mtx.vin.size() )
|
||||
continue;
|
||||
}
|
||||
if ( n > 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
if ( txid == utxos[i].txid && vout == utxos[i].vout )
|
||||
break;
|
||||
if ( i != n )
|
||||
continue;
|
||||
}
|
||||
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||
{
|
||||
up = &utxos[n++];
|
||||
up->txid = txid;
|
||||
up->nValue = it->second.satoshis;
|
||||
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 || sum >= total )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
remains = total;
|
||||
for (i=0; i<maxinputs && n>0; i++)
|
||||
{
|
||||
below = above = 0;
|
||||
abovei = belowi = -1;
|
||||
if ( CC_vinselect(&abovei,&above,&belowi,&below,utxos,n,remains) < 0 )
|
||||
{
|
||||
printf("error finding unspent i.%d of %d, %.8f vs %.8f\n",i,n,(double)remains/COIN,(double)total/COIN);
|
||||
free(utxos);
|
||||
return(0);
|
||||
}
|
||||
if ( belowi < 0 || abovei >= 0 )
|
||||
ind = abovei;
|
||||
else ind = belowi;
|
||||
if ( ind < 0 )
|
||||
{
|
||||
printf("error finding unspent i.%d of %d, %.8f vs %.8f, abovei.%d belowi.%d ind.%d\n",i,n,(double)remains/COIN,(double)total/COIN,abovei,belowi,ind);
|
||||
free(utxos);
|
||||
return(0);
|
||||
}
|
||||
up = &utxos[ind];
|
||||
mtx.vin.push_back(CTxIn(up->txid,up->vout,CScript()));
|
||||
totalinputs += up->nValue;
|
||||
remains -= up->nValue;
|
||||
utxos[ind] = utxos[--n];
|
||||
memset(&utxos[n],0,sizeof(utxos[n]));
|
||||
//fprintf(stderr,"totalinputs %.8f vs total %.8f i.%d vs max.%d\n",(double)totalinputs/COIN,(double)total/COIN,i,maxinputs);
|
||||
if ( totalinputs >= total || (i+1) >= maxinputs )
|
||||
break;
|
||||
}
|
||||
free(utxos);
|
||||
if ( totalinputs >= total )
|
||||
{
|
||||
//fprintf(stderr,"return totalinputs %.8f\n",(double)totalinputs/COIN);
|
||||
return(totalinputs);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -129,6 +129,10 @@
|
||||
vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
// tx validation
|
||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
static uint256 zero;
|
||||
@@ -155,9 +159,11 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
||||
else starti = 1;
|
||||
if ( assetid == zero )
|
||||
return eval->Invalid("illegal assetid");
|
||||
else if ( AssetExactAmounts(cp,inputs,starti,outputs,eval,tx,assetid) == false )
|
||||
else if ( AssetExactAmounts(2, cp,inputs,starti,outputs,eval,tx,assetid) == false )
|
||||
return eval->Invalid("asset inputs != outputs");
|
||||
}
|
||||
|
||||
|
||||
switch ( funcid )
|
||||
{
|
||||
case 'c': // create wont be called to be verified as it has no CC inputs
|
||||
@@ -321,7 +327,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
||||
}
|
||||
fprintf(stderr,"fill validated\n");
|
||||
break;
|
||||
case 'E': // fillexchange
|
||||
case 'E': // fillexchange
|
||||
return eval->Invalid("unexpected assets fillexchange funcid");
|
||||
break; // disable asset swaps
|
||||
//vin.0: normal input
|
||||
@@ -333,7 +339,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
||||
//vout.3: CC output for asset2 change (if any)
|
||||
//vout.3/4: normal output for change (if any)
|
||||
//vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey]
|
||||
if ( AssetExactAmounts(cp,inputs,1,outputs,eval,tx,assetid2) == false )
|
||||
if ( AssetExactAmounts(1, cp,inputs,1,outputs,eval,tx,assetid2) == false )
|
||||
eval->Invalid("asset2 inputs != outputs");
|
||||
if ( (assetoshis= AssetValidateSellvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 )
|
||||
return(false);
|
||||
|
||||
@@ -150,7 +150,8 @@ int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
|
||||
|
||||
std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_AUCTION);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -170,7 +171,8 @@ std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount)
|
||||
|
||||
std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_AUCTION);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -190,7 +192,8 @@ std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid)
|
||||
|
||||
std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_AUCTION);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "cc/utils.h"
|
||||
#include "primitives/transaction.h"
|
||||
|
||||
int32_t komodo_nextheight();
|
||||
|
||||
std::vector<CC*> BetProtocol::PlayerConditions()
|
||||
{
|
||||
@@ -53,7 +54,7 @@ CC* BetProtocol::MakeDisputeCond()
|
||||
*/
|
||||
CMutableTransaction BetProtocol::MakeSessionTx(CAmount spendFee)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
CC *disputeCond = MakeDisputeCond();
|
||||
mtx.vout.push_back(CTxOut(spendFee, CCPubKey(disputeCond)));
|
||||
@@ -70,7 +71,7 @@ CMutableTransaction BetProtocol::MakeSessionTx(CAmount spendFee)
|
||||
|
||||
CMutableTransaction BetProtocol::MakeDisputeTx(uint256 signedSessionTxHash, uint256 vmResultHash)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
CC *disputeCond = MakeDisputeCond();
|
||||
mtx.vin.push_back(CTxIn(signedSessionTxHash, 0, CScript()));
|
||||
@@ -84,7 +85,7 @@ CMutableTransaction BetProtocol::MakeDisputeTx(uint256 signedSessionTxHash, uint
|
||||
CMutableTransaction BetProtocol::MakePostEvidenceTx(uint256 signedSessionTxHash,
|
||||
int playerIdx, std::vector<unsigned char> state)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
mtx.vin.push_back(CTxIn(signedSessionTxHash, playerIdx+1, CScript()));
|
||||
mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << state));
|
||||
@@ -115,7 +116,7 @@ CC* BetProtocol::MakePayoutCond(uint256 signedSessionTxHash)
|
||||
|
||||
CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signedSessionTxHash)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
|
||||
CC *payoutCond = MakePayoutCond(signedSessionTxHash);
|
||||
mtx.vout.push_back(CTxOut(totalPayout, CCPubKey(payoutCond)));
|
||||
@@ -128,7 +129,7 @@ CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signed
|
||||
CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector<CTxOut> payouts,
|
||||
uint256 signedStakeTxHash)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript()));
|
||||
mtx.vout = payouts;
|
||||
return mtx;
|
||||
@@ -138,7 +139,7 @@ CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector<CTxOut> payouts,
|
||||
CMutableTransaction BetProtocol::MakeImportPayoutTx(std::vector<CTxOut> payouts,
|
||||
CTransaction signedDisputeTx, uint256 signedStakeTxHash, MoMProof momProof)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript()));
|
||||
mtx.vout = payouts;
|
||||
CScript proofData;
|
||||
|
||||
@@ -430,7 +430,8 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
|
||||
|
||||
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment)
|
||||
{
|
||||
CMutableTransaction mtx; uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy;
|
||||
CPubKey mypk; struct CCcontract_info *cp,C;
|
||||
|
||||
if ( numpayments <= 0 || payment <= 0 || numpayments > CHANNELS_MAXPAYMENTS )
|
||||
@@ -464,7 +465,8 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
|
||||
|
||||
std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3;
|
||||
struct CCcontract_info *cp,C; int32_t i,funcid,prevdepth,numvouts,numpayments,totalnumpayments;
|
||||
int64_t payment,change,funds,param2;
|
||||
uint8_t hash[32],hashdest[32];
|
||||
@@ -569,7 +571,8 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
|
||||
|
||||
std::string ChannelClose(uint64_t txfee,uint256 opentxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C;
|
||||
CTransaction channelOpenTx;
|
||||
uint256 hashblock,tmp_txid,prevtxid,hashchain;
|
||||
int32_t numvouts,numpayments;
|
||||
@@ -616,7 +619,8 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
|
||||
|
||||
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2;
|
||||
int32_t i,numpayments,numvouts,param1;
|
||||
uint256 hashchain,hashblock,txid,prevtxid,param3,entropy,hentropy,secret;
|
||||
CTransaction channelOpenTx,channelCloseTx,prevTx;
|
||||
|
||||
@@ -98,7 +98,7 @@ What is needed is for the dealer node to track the entropy tx that was already b
|
||||
#include "../compat/endian.h"
|
||||
|
||||
#define MAX_ENTROPYUSED 8192
|
||||
#define DICE_MINUTXOS 10000
|
||||
#define DICE_MINUTXOS 15000
|
||||
extern int32_t KOMODO_INSYNC;
|
||||
|
||||
pthread_mutex_t DICE_MUTEX,DICEREVEALED_MUTEX;
|
||||
@@ -245,9 +245,12 @@ bool mySenddicetransaction(std::string res,uint256 entropyused,int32_t entropyvo
|
||||
{
|
||||
RelayTransaction(tx);
|
||||
fprintf(stderr,"rebroadcast.%c and clear [%d] and broadcast entropyused.%s bettxid.%s -> %s\n",funcid,i,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str());
|
||||
if ( ptr->rawtx.empty() == 0 )
|
||||
ptr->rawtx.clear();
|
||||
ptr->txid = zeroid;
|
||||
if ( ptr != 0 )
|
||||
{
|
||||
if ( ptr->rawtx.empty() == 0 )
|
||||
ptr->rawtx.clear();
|
||||
ptr->txid = zeroid;
|
||||
}
|
||||
//fprintf(stderr,"error adding funcid.%c E.%s bet.%s -> %s to mempool, probably Disable replacement feature size.%d\n",funcid,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str(),(int32_t)ptr->rawtx.size());
|
||||
}
|
||||
} else fprintf(stderr,"error duplicate entropyused different bettxid\n");
|
||||
@@ -1332,7 +1335,8 @@ UniValue DiceList()
|
||||
|
||||
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks)
|
||||
{
|
||||
CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C;
|
||||
if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 )
|
||||
{
|
||||
CCerror = "invalid parameter error";
|
||||
@@ -1366,7 +1370,8 @@ std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t
|
||||
|
||||
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
CCerror = "amount must be positive";
|
||||
@@ -1390,7 +1395,7 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
||||
}
|
||||
if ( scriptPubKey == fundingPubKey )
|
||||
{
|
||||
if ( AddNormalinputs(mtx,mypk,amount+2*txfee,1) > 0 )
|
||||
if ( AddNormalinputs2(mtx,amount+2*txfee,60) > 0 )
|
||||
{
|
||||
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,dicepk));
|
||||
@@ -1409,7 +1414,8 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6
|
||||
|
||||
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds)
|
||||
{
|
||||
CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C;
|
||||
if ( bet < 0 )
|
||||
{
|
||||
CCerror = "bet must be positive";
|
||||
@@ -1467,7 +1473,8 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet
|
||||
|
||||
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)
|
||||
{
|
||||
CMutableTransaction mtx,savemtx; CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits;
|
||||
CMutableTransaction savemtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits;
|
||||
entropyused = zeroid;
|
||||
*resultp = 0;
|
||||
funcid = 0;
|
||||
@@ -1501,7 +1508,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv
|
||||
{
|
||||
if ( vin0txid == zeroid || vin0vout < 0 )
|
||||
{
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) == 0 ) // must be a single vin!!
|
||||
if ( AddNormalinputs2(mtx,2*txfee,3) == 0 ) // must be a single vin!!
|
||||
{
|
||||
CCerror = "no txfee inputs for win/lose";
|
||||
fprintf(stderr,"%s\n", CCerror.c_str() );
|
||||
@@ -1648,22 +1655,32 @@ static uint256 dealer0_fundingtxid;
|
||||
void *dealer0_loop(void *_arg)
|
||||
{
|
||||
char *planstr = (char *)_arg;
|
||||
CTransaction tx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid; int32_t entropytxs,i,n,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000;
|
||||
CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 hashBlock,entropytxid,txid; int32_t height,lastht,numentropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000;
|
||||
if ( (cp= Diceinit(fundingPubKey,dealer0_fundingtxid,&C,planstr,txfee,mypk,dicepk,refsbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"error initializing dealer0_loop\n");
|
||||
exit(-1);
|
||||
}
|
||||
fprintf(stderr,"dealer0 node running\n");
|
||||
height = lastht = 0;
|
||||
entropytxs = (CTransaction *)calloc(sizeof(*entropytxs),DICE_MINUTXOS);
|
||||
while ( 1 )
|
||||
{
|
||||
DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,entropytxs,false);
|
||||
if ( entropytxs < DICE_MINUTXOS )
|
||||
while ( KOMODO_INSYNC == 0 || (height= KOMODO_INSYNC) == lastht )
|
||||
{
|
||||
n = sqrt(DICE_MINUTXOS - entropytxs) + 10;
|
||||
for (i=0; i<DICE_MINUTXOS - entropytxs && i<n; i++)
|
||||
sleep(3);
|
||||
}
|
||||
lastht = height;
|
||||
fprintf(stderr,"New height.%d\n",height);
|
||||
DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,numentropytxs,false);
|
||||
if ( numentropytxs < DICE_MINUTXOS )
|
||||
{
|
||||
n = sqrt(DICE_MINUTXOS - numentropytxs);
|
||||
//if ( n > 10 )
|
||||
// n = 10;
|
||||
for (i=m=0; i<DICE_MINUTXOS - numentropytxs && i<n; i++)
|
||||
{
|
||||
res = DiceAddfunding(txfee,planstr,dealer0_fundingtxid,COIN/100);
|
||||
res = DiceAddfunding(txfee,planstr,dealer0_fundingtxid,COIN);
|
||||
if ( res.empty() == 0 && res.size() > 64 && is_hexstr((char *)res.c_str(),0) > 64 )
|
||||
{
|
||||
if ( DecodeHexTx(tx,res) != 0 )
|
||||
@@ -1671,12 +1688,37 @@ void *dealer0_loop(void *_arg)
|
||||
LOCK(cs_main);
|
||||
if ( myAddtomempool(tx) != 0 )
|
||||
{
|
||||
fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - entropytxs);
|
||||
fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - numentropytxs);
|
||||
RelayTransaction(tx);
|
||||
entropytxs[m++] = tx;
|
||||
} else break;
|
||||
} else break;
|
||||
} else break;
|
||||
}
|
||||
for (i=0; i<m; i++)
|
||||
{
|
||||
tx = entropytxs[i];
|
||||
txid = tx.GetHash();
|
||||
fprintf(stderr,"check %d of %d: %s\n",i,m,txid.GetHex().c_str());
|
||||
while ( 1 )
|
||||
{
|
||||
if ( myGetTransaction(txid,entropytx,hashBlock) == 0 || hashBlock == zeroid )
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if ( myAddtomempool(tx) != 0 )
|
||||
{
|
||||
fprintf(stderr,"resend ENTROPY %s: %d of %d\n",txid.GetHex().c_str(),i,m);
|
||||
RelayTransaction(tx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"found %s in %s\n",txid.GetHex().c_str(),hashBlock.GetHex().c_str());
|
||||
break;
|
||||
}
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
pubkey2addr(coinaddr,Mypubkey().data());
|
||||
dicefinish_utxosget(num,0,0,coinaddr);
|
||||
|
||||
@@ -74,11 +74,11 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
|
||||
switch ( ecode )
|
||||
{
|
||||
case EVAL_IMPORTPAYOUT:
|
||||
//return ImportPayout(vparams, txTo, nIn);
|
||||
return ImportPayout(vparams, txTo, nIn);
|
||||
break;
|
||||
|
||||
case EVAL_IMPORTCOIN:
|
||||
//return ImportCoin(vparams, txTo, nIn);
|
||||
return ImportCoin(vparams, txTo, nIn);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -192,17 +192,6 @@ bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get MoMoM corresponding to a notarisation tx hash (on assetchain)
|
||||
*/
|
||||
bool Eval::GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const
|
||||
{
|
||||
std::pair<uint256,NotarisationData> out;
|
||||
if (!GetNextBacknotarisation(kmdNotarisationHash, out)) return false;
|
||||
momom = out.second.MoMoM;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Eval::GetAssetchainsCC() const
|
||||
{
|
||||
|
||||
@@ -104,7 +104,6 @@ public:
|
||||
virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const;
|
||||
virtual int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const;
|
||||
virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const;
|
||||
virtual bool GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const;
|
||||
virtual bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const;
|
||||
virtual uint32_t GetAssetchainsCC() const;
|
||||
virtual std::string GetAssetchainsSymbol() const;
|
||||
|
||||
@@ -174,7 +174,8 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
|
||||
std::string FaucetGet(uint64_t txfee)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; 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_FAUCET);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -214,7 +215,8 @@ std::string FaucetGet(uint64_t txfee)
|
||||
|
||||
std::string FaucetFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -231,7 +233,8 @@ std::string FaucetFund(uint64_t txfee,int64_t funds)
|
||||
UniValue FaucetInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Faucet"));
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
|
||||
@@ -157,7 +157,8 @@ std::string FSMList()
|
||||
|
||||
std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FSM);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -177,7 +178,8 @@ std::string FSMCreate(uint64_t txfee,std::string name,std::string states)
|
||||
|
||||
std::string FSMInfo(uint256 fsmtxid)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FSM);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
fsmpk = GetUnspendable(cp,0);
|
||||
|
||||
@@ -748,7 +748,8 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256
|
||||
|
||||
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)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr;
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
if ( strcmp((char *)"KMD",coin.c_str()) == 0 )
|
||||
{
|
||||
@@ -833,7 +834,8 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
|
||||
|
||||
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)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction bindtx; CPubKey mypk,gatewayspk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction bindtx; CPubKey mypk,gatewayspk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid;
|
||||
int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2; std::string coin; struct CCcontract_info *cp,C;
|
||||
std::vector<CPubKey> pubkeys,publishers; std::vector<uint256>txids; char str[67],depositaddr[64],txidaddr[64];
|
||||
|
||||
@@ -899,7 +901,8 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
|
||||
|
||||
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2;
|
||||
std::string coin, deposithex; std::vector<CPubKey> msigpubkeys,publishers; int64_t totalsupply,depositamount,tmpamount,inputs,CCchange=0;
|
||||
int32_t numvouts,claimvout,height; std::vector<uint8_t> proof;
|
||||
uint256 hashBlock,assetid,oracletxid,tmptxid,cointxid; char str[65],depositaddr[64],coinaddr[64],destaddr[64]; std::vector<uint256> txids;
|
||||
@@ -962,7 +965,8 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
|
||||
|
||||
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;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
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];
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
@@ -1001,7 +1005,8 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
||||
|
||||
std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string hex)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
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);
|
||||
@@ -1040,7 +1045,8 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin,
|
||||
|
||||
std::string GatewaysCompleteSigning(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,std::string hex)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65];
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
gatewayspk = GetUnspendable(cp,0);
|
||||
@@ -1054,7 +1060,8 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 withdrawtxid,std::str
|
||||
|
||||
std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string refcoin)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65];
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( txfee == 0 )
|
||||
@@ -1247,7 +1254,8 @@ UniValue GatewaysList()
|
||||
|
||||
UniValue GatewaysInfo(uint256 bindtxid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::string coin; 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; CMutableTransaction mtx; CPubKey Gatewayspk; struct CCcontract_info *cp,C; int32_t i; int64_t totalsupply,remaining;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::string coin; 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; struct CCcontract_info *cp,C; int32_t i; int64_t totalsupply,remaining;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Gateways"));
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
|
||||
@@ -143,7 +143,8 @@ int64_t AddHeirInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
|
||||
|
||||
std::string HeirGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
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;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
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;
|
||||
@@ -183,7 +184,8 @@ std::string HeirGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string HeirFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_HEIR);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -199,8 +201,9 @@ std::string HeirFund(uint64_t txfee,int64_t funds)
|
||||
|
||||
UniValue HeirInfo()
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Heir"));
|
||||
cp = CCinit(&C,EVAL_HEIR);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "cc/eval.h"
|
||||
#include "cc/utils.h"
|
||||
#include "importcoin.h"
|
||||
#include "crosschain.h"
|
||||
#include "primitives/transaction.h"
|
||||
|
||||
|
||||
@@ -75,12 +76,8 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
|
||||
|
||||
// Check proof confirms existance of burnTx
|
||||
{
|
||||
uint256 momom, target;
|
||||
if (!GetProofRoot(proof.first, momom))
|
||||
return Invalid("coudnt-load-momom");
|
||||
|
||||
target = proof.second.Exec(burnTx.GetHash());
|
||||
if (momom != proof.second.Exec(burnTx.GetHash()))
|
||||
uint256 target = proof.second.Exec(burnTx.GetHash());
|
||||
if (!CheckMoMoM(proof.first, target))
|
||||
return Invalid("momom-check-fail");
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +283,8 @@ UniValue LottoList()
|
||||
|
||||
std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t ticketsize,int32_t odds,int32_t firstheight,int32_t period)
|
||||
{
|
||||
CMutableTransaction mtx; uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_LOTTO);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -301,7 +302,8 @@ std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t tic
|
||||
|
||||
std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_LOTTO);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -321,7 +323,8 @@ std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets)
|
||||
|
||||
std::string LottoWinner(uint64_t txfee)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_LOTTO);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
|
||||
@@ -728,7 +728,8 @@ int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubK
|
||||
|
||||
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 )
|
||||
{
|
||||
@@ -749,7 +750,8 @@ std::string OracleCreate(int64_t txfee,std::string name,std::string description,
|
||||
|
||||
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,markerpubkey,batonpk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,markerpubkey,batonpk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64];
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -772,7 +774,8 @@ std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee)
|
||||
|
||||
std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64];
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -789,7 +792,8 @@ std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,i
|
||||
|
||||
std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> data)
|
||||
{
|
||||
CMutableTransaction mtx; CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector <uint8_t> prevdata;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector <uint8_t> prevdata;
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( data.size() > 8192 )
|
||||
@@ -879,7 +883,8 @@ UniValue OracleInfo(uint256 origtxid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR);
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
CMutableTransaction mtx; CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector <uint8_t> data;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector <uint8_t> data;
|
||||
cp = CCinit(&C,EVAL_ORACLES);
|
||||
CCtxidaddr(markeraddr,origtxid);
|
||||
if ( GetTransaction(origtxid,tx,hashBlock,false) == 0 )
|
||||
|
||||
@@ -144,7 +144,8 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
|
||||
std::string PaymentsGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Paymentspk; 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;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; 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_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -184,7 +185,8 @@ std::string PaymentsGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string PaymentsFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -201,7 +203,8 @@ std::string PaymentsFund(uint64_t txfee,int64_t funds)
|
||||
UniValue PaymentsInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Payments"));
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
|
||||
@@ -151,7 +151,8 @@ int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
|
||||
|
||||
std::string PegsGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Pegspk; 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;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Pegspk; 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_PEGS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -191,7 +192,8 @@ std::string PegsGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string PegsFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_PEGS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -208,7 +210,8 @@ std::string PegsFund(uint64_t txfee,int64_t funds)
|
||||
UniValue PegsInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Pegs"));
|
||||
cp = CCinit(&C,EVAL_PEGS);
|
||||
|
||||
@@ -182,7 +182,8 @@ UniValue PricesList()
|
||||
// bettoken
|
||||
std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector<CPubKey> pubkeys)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C;
|
||||
if ( funding < 100*COIN || maxleverage <= 0 || maxleverage > 10000 )
|
||||
{
|
||||
CCerror = "invalid parameter error";
|
||||
@@ -293,7 +294,8 @@ UniValue PricesInfo(uint256 fundingtxid)
|
||||
|
||||
std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
if ( amount < 10000 )
|
||||
{
|
||||
CCerror = "amount must be positive";
|
||||
@@ -343,7 +345,8 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt
|
||||
|
||||
std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount,int32_t leverage)
|
||||
{
|
||||
CMutableTransaction mtx; struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vector<CPubKey>pubkeys;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
amount = -amount;
|
||||
|
||||
@@ -500,7 +500,8 @@ UniValue RewardsList()
|
||||
|
||||
std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
if ( funds < COIN || mindeposit < 0 || minseconds < 0 || maxseconds < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative parameter error\n");
|
||||
@@ -534,7 +535,8 @@ std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int6
|
||||
|
||||
std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C;
|
||||
if ( amount < 0 )
|
||||
{
|
||||
fprintf(stderr,"negative parameter error\n");
|
||||
@@ -568,7 +570,8 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i
|
||||
|
||||
std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C;
|
||||
if ( deposit < txfee )
|
||||
{
|
||||
CCerror = "deposit amount less than txfee";
|
||||
@@ -611,7 +614,8 @@ std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t
|
||||
|
||||
std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid)
|
||||
{
|
||||
CMutableTransaction mtx,firstmtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction firstmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_REWARDS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
|
||||
@@ -143,7 +143,8 @@ int64_t AddTriggersInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
|
||||
std::string TriggersGet(uint64_t txfee,int64_t nValue)
|
||||
{
|
||||
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Triggerspk; 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;
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Triggerspk; 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_TRIGGERS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -183,7 +184,8 @@ std::string TriggersGet(uint64_t txfee,int64_t nValue)
|
||||
|
||||
std::string TriggersFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx; CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_TRIGGERS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -200,7 +202,8 @@ std::string TriggersFund(uint64_t txfee,int64_t funds)
|
||||
UniValue TriggersInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx; CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Triggers"));
|
||||
cp = CCinit(&C,EVAL_TRIGGERS);
|
||||
|
||||
@@ -557,7 +557,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& input)
|
||||
{
|
||||
assert(coins);
|
||||
if (coins->nHeight < 6400 && !strcmp(ASSETCHAINS_SYMBOL, "VRSC"))
|
||||
/*if (coins->nHeight < 6400 && !strcmp(ASSETCHAINS_SYMBOL, "VRSC"))
|
||||
{
|
||||
std::string hc = input.prevout.hash.ToString();
|
||||
if (LaunchMap().lmap.count(hc))
|
||||
@@ -568,7 +568,7 @@ const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& in
|
||||
return txData.scriptPubKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return coins->vout[input.prevout.n].scriptPubKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
#include "veruslaunch.h"
|
||||
//#include "veruslaunch.h"
|
||||
|
||||
/**
|
||||
* Pruned version of CTransaction: only retains metadata and unspent transaction outputs
|
||||
@@ -456,7 +456,7 @@ class CTransactionExceptionData
|
||||
CTransactionExceptionData() : scriptPubKey(), voutMask() {}
|
||||
};
|
||||
|
||||
class CLaunchMap
|
||||
/*class CLaunchMap
|
||||
{
|
||||
public:
|
||||
std::unordered_map<std::string, CTransactionExceptionData> lmap;
|
||||
@@ -477,7 +477,7 @@ class CLaunchMap
|
||||
}
|
||||
}
|
||||
};
|
||||
static CLaunchMap launchMap = CLaunchMap();
|
||||
static CLaunchMap launchMap = CLaunchMap();*/
|
||||
|
||||
/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
|
||||
class CCoinsViewCache : public CCoinsViewBacked
|
||||
@@ -507,7 +507,7 @@ public:
|
||||
~CCoinsViewCache();
|
||||
|
||||
// Standard CCoinsView methods
|
||||
static CLaunchMap &LaunchMap() { return launchMap; }
|
||||
//static CLaunchMap &LaunchMap() { return launchMap; }
|
||||
bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const;
|
||||
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
|
||||
bool GetNullifier(const uint256 &nullifier, ShieldedType type) const;
|
||||
|
||||
@@ -69,7 +69,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
||||
destNotarisationTxid = nota.first;
|
||||
else if (seenOwnNotarisations == 2)
|
||||
goto end;
|
||||
break;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,8 +96,9 @@ template <typename IsTarget>
|
||||
int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &found)
|
||||
{
|
||||
int limit = std::min(nHeight + NOTARISATION_SCAN_LIMIT_BLOCKS, chainActive.Height());
|
||||
|
||||
for (int h=nHeight; h<limit; h++) {
|
||||
int start = std::max(nHeight, 1);
|
||||
|
||||
for (int h=start; h<limit; h++) {
|
||||
NotarisationsInBlock notarisations;
|
||||
|
||||
if (!GetBlockNotarisations(*chainActive[h]->phashBlock, notarisations))
|
||||
@@ -125,7 +126,7 @@ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_
|
||||
*/
|
||||
EvalRef eval;
|
||||
uint256 MoM = assetChainProof.second.Exec(txid);
|
||||
|
||||
|
||||
// Get a kmd height for given notarisation Txid
|
||||
int kmdHeight;
|
||||
{
|
||||
@@ -157,7 +158,7 @@ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_
|
||||
uint256 MoMoM = CalculateProofRoot(targetSymbol, targetCCid, kmdHeight, moms, targetChainNotarisationTxid);
|
||||
if (MoMoM.IsNull())
|
||||
throw std::runtime_error("No MoMs found");
|
||||
|
||||
|
||||
// Find index of source MoM in MoMoM
|
||||
int nIndex;
|
||||
for (nIndex=0; nIndex<moms.size(); nIndex++) {
|
||||
@@ -246,6 +247,38 @@ bool GetNextBacknotarisation(uint256 kmdNotarisationTxid, Notarisation &out)
|
||||
}
|
||||
|
||||
|
||||
bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom)
|
||||
{
|
||||
/*
|
||||
* Given a notarisation hash and an MoMoM. Backnotarisations may arrive out of order
|
||||
* or multiple in the same block. So dereference the notarisation hash to the corresponding
|
||||
* backnotarisation and scan around the kmdheight to see if the MoMoM is a match.
|
||||
* This is a sledgehammer approach...
|
||||
*/
|
||||
|
||||
Notarisation bn;
|
||||
if (!GetBackNotarisation(kmdNotarisationHash, bn))
|
||||
return false;
|
||||
|
||||
// Need to get block height of that backnotarisation
|
||||
EvalRef eval;
|
||||
CBlockIndex block;
|
||||
CTransaction tx;
|
||||
if (!eval->GetTxConfirmed(bn.first, tx, block)){
|
||||
fprintf(stderr, "Can't get height of backnotarisation, this should not happen\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
Notarisation nota;
|
||||
auto checkMoMoM = [&](Notarisation ¬a) {
|
||||
return nota.second.MoMoM == momom;
|
||||
};
|
||||
|
||||
return (bool) ScanNotarisationsFromHeight(block.GetHeight()-100, checkMoMoM, nota);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* On assetchain
|
||||
* in: txid
|
||||
@@ -278,7 +311,7 @@ TxProof GetAssetchainProof(uint256 hash)
|
||||
};
|
||||
if (!ScanNotarisationsFromHeight(blockIndex->GetHeight(), isTarget, nota))
|
||||
throw std::runtime_error("backnotarisation not yet confirmed");
|
||||
|
||||
|
||||
// index of block in MoM leaves
|
||||
nIndex = nota.second.height - blockIndex->GetHeight();
|
||||
}
|
||||
@@ -292,7 +325,7 @@ TxProof GetAssetchainProof(uint256 hash)
|
||||
}
|
||||
bool fMutated;
|
||||
BuildMerkleTree(&fMutated, leaves, tree);
|
||||
branch = GetMerkleBranch(nIndex, leaves.size(), tree);
|
||||
branch = GetMerkleBranch(nIndex, leaves.size(), tree);
|
||||
|
||||
// Check branch
|
||||
uint256 ourResult = SafeCheckMerkleBranch(blockIndex->hashMerkleRoot, branch, nIndex);
|
||||
@@ -331,7 +364,7 @@ TxProof GetAssetchainProof(uint256 hash)
|
||||
}
|
||||
|
||||
// Check the proof
|
||||
if (nota.second.MoM != CBlock::CheckMerkleBranch(hash, branch, nIndex))
|
||||
if (nota.second.MoM != CBlock::CheckMerkleBranch(hash, branch, nIndex))
|
||||
throw std::runtime_error("Failed validating MoM");
|
||||
|
||||
// All done!
|
||||
|
||||
@@ -15,7 +15,7 @@ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_
|
||||
void CompleteImportTransaction(CTransaction &importTx);
|
||||
|
||||
/* On assetchain */
|
||||
bool GetNextBacknotarisation(uint256 txid, std::pair<uint256,NotarisationData> &bn);
|
||||
bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom);
|
||||
|
||||
|
||||
#endif /* CROSSCHAIN_H */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -291,7 +291,7 @@ TEST_F(ContextualCheckBlockTest, BlockOverwinterRulesRejectOtherTx) {
|
||||
|
||||
{
|
||||
SCOPED_TRACE("BlockOverwinterRulesRejectSaplingTx");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "bad-overwinter-tx-version-group-id");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 0, "bad-overwinter-tx-version-group-id");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,6 +319,6 @@ TEST_F(ContextualCheckBlockTest, BlockSaplingRulesRejectOtherTx) {
|
||||
|
||||
{
|
||||
SCOPED_TRACE("BlockSaplingRulesRejectOverwinterTx");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "bad-sapling-tx-version-group-id");
|
||||
ExpectInvalidBlockFromTx(CTransaction(mtx), 0, "bad-sapling-tx-version-group-id");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,7 +844,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
const CChainParams& chainparams = Params();
|
||||
|
||||
// Set this early so that experimental features are correctly enabled/disabled
|
||||
fExperimentalMode = GetBoolArg("-experimentalfeatures", false);
|
||||
fExperimentalMode = GetBoolArg("-experimentalfeatures", true);
|
||||
|
||||
// Fail early if user has set experimental options without the global flag
|
||||
if (!fExperimentalMode) {
|
||||
@@ -1486,7 +1486,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles);
|
||||
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
|
||||
pblocktree->ReadFlag("addressindex", checkval);
|
||||
if ( checkval != fAddressIndex )
|
||||
if ( checkval != fAddressIndex && fAddressIndex != 0 )
|
||||
{
|
||||
pblocktree->WriteFlag("addressindex", fAddressIndex);
|
||||
fprintf(stderr,"set addressindex, will reindex. could take a while.\n");
|
||||
@@ -1494,7 +1494,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
}
|
||||
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
|
||||
pblocktree->ReadFlag("spentindex", checkval);
|
||||
if ( checkval != fSpentIndex )
|
||||
if ( checkval != fSpentIndex && fSpentIndex != 0 )
|
||||
{
|
||||
pblocktree->WriteFlag("spentindex", fSpentIndex);
|
||||
fprintf(stderr,"set spentindex, will reindex. could take a while.\n");
|
||||
|
||||
@@ -1062,6 +1062,14 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t komodo_nextheight()
|
||||
{
|
||||
CBlockIndex *pindex; int32_t ht,longest = komodo_longestchain();
|
||||
if ( (pindex= chainActive.LastTip()) != 0 && (ht= pindex->GetHeight()) >= longest )
|
||||
return(ht+1);
|
||||
else return(longest + 1);
|
||||
}
|
||||
|
||||
int32_t komodo_isrealtime(int32_t *kmdheightp)
|
||||
{
|
||||
struct komodo_state *sp; CBlockIndex *pindex;
|
||||
@@ -1763,12 +1771,12 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
{
|
||||
if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget,bhash)) == 0 )
|
||||
{
|
||||
if ( slowflag == 0 ) // need all past 100 blocks to calculate PoW target
|
||||
return(0);
|
||||
if ( ASSETCHAINS_STAKED == 100 && height > 100 ) // only PoS allowed! POSTEST64
|
||||
return(-1);
|
||||
else
|
||||
{
|
||||
if ( slowflag == 0 ) // need all past 100 blocks to calculate PoW target
|
||||
return(0);
|
||||
if ( slowflag != 0 )
|
||||
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
|
||||
if ( bhash > bnTarget )
|
||||
@@ -1788,6 +1796,8 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
fprintf(stderr,"unexpected negative is_PoSblock.%d\n",is_PoSblock);
|
||||
return(-1);
|
||||
}
|
||||
else if ( ASSETCHAINS_STAKED != 0 )
|
||||
failed = 0;
|
||||
}
|
||||
if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
|
||||
{
|
||||
@@ -1816,12 +1826,28 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed);
|
||||
//fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed);
|
||||
if ( failed != 0 && possible == 0 && notaryid < 0 )
|
||||
return(-1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
int32_t komodo_acpublic(uint32_t tiptime)
|
||||
{
|
||||
int32_t acpublic = ASSETCHAINS_PUBLIC; CBlockIndex *pindex;
|
||||
if ( acpublic == 0 )
|
||||
{
|
||||
if ( tiptime == 0 )
|
||||
{
|
||||
if ( (pindex= chainActive.LastTip()) != 0 )
|
||||
tiptime = pindex->nTime;
|
||||
}
|
||||
if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE )
|
||||
acpublic = 1;
|
||||
}
|
||||
return(acpublic);
|
||||
}
|
||||
|
||||
int64_t komodo_newcoins(int64_t *zfundsp,int32_t nHeight,CBlock *pblock)
|
||||
{
|
||||
CTxDestination address; int32_t i,j,m,n,vout; uint8_t *script; uint256 txid,hashBlock; int64_t zfunds=0,vinsum=0,voutsum=0;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define KOMODO_FIRSTFUNGIBLEID 100
|
||||
#define KOMODO_SAPLING_ACTIVATION 1544832000 // Dec 15th, 2018
|
||||
#define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019
|
||||
|
||||
|
||||
extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC;
|
||||
int32_t MAX_BLOCK_SIZE(int32_t height);
|
||||
|
||||
|
||||
47
src/main.cpp
47
src/main.cpp
@@ -77,7 +77,7 @@ static int64_t nTimeBestReceived = 0;
|
||||
CWaitableCriticalSection csBestBlock;
|
||||
CConditionVariable cvBlockChange;
|
||||
int nScriptCheckThreads = 0;
|
||||
bool fExperimentalMode = false;
|
||||
bool fExperimentalMode = true;
|
||||
bool fImporting = false;
|
||||
bool fReindex = false;
|
||||
bool fTxIndex = false;
|
||||
@@ -1034,9 +1034,12 @@ bool ContextualCheckTransaction(
|
||||
}
|
||||
|
||||
// Reject transactions with non-Sapling version group ID
|
||||
if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
|
||||
return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),
|
||||
REJECT_INVALID, "bad-sapling-tx-version-group-id");
|
||||
if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID)
|
||||
{
|
||||
//return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),REJECT_INVALID, "bad-sapling-tx-version-group-id");
|
||||
return state.DoS(isInitBlockDownload() ? 0 : dosLevel,
|
||||
error("CheckTransaction(): invalid Sapling tx version"),
|
||||
REJECT_INVALID, "bad-sapling-tx-version-group-id");
|
||||
}
|
||||
|
||||
// Reject transactions with invalid version
|
||||
@@ -1058,9 +1061,12 @@ bool ContextualCheckTransaction(
|
||||
}
|
||||
|
||||
// Reject transactions with non-Overwinter version group ID
|
||||
if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
|
||||
return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),
|
||||
REJECT_INVALID, "bad-overwinter-tx-version-group-id");
|
||||
if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID)
|
||||
{
|
||||
//return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),REJECT_INVALID, "bad-overwinter-tx-version-group-id");
|
||||
return state.DoS(isInitBlockDownload() ? 0 : dosLevel,
|
||||
error("CheckTransaction(): invalid Overwinter tx version"),
|
||||
REJECT_INVALID, "bad-overwinter-tx-version-group-id");
|
||||
}
|
||||
|
||||
// Reject transactions with invalid version
|
||||
@@ -1253,10 +1259,12 @@ int32_t komodo_isnotaryvout(char *coinaddr) // from ac_private chains only
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t komodo_acpublic(uint32_t tiptime);
|
||||
|
||||
bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransaction& tx, CValidationState &state)
|
||||
{
|
||||
// Basic checks that don't depend on any context
|
||||
int32_t invalid_private_taddr=0,z_z=0,z_t=0,t_z=0,acpublic = ASSETCHAINS_PUBLIC;
|
||||
int32_t invalid_private_taddr=0,z_z=0,z_t=0,t_z=0,acpublic = komodo_acpublic(tiptime);
|
||||
/**
|
||||
* Previously:
|
||||
* 1. The consensus rule below was:
|
||||
@@ -1359,8 +1367,6 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio
|
||||
return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"),
|
||||
REJECT_INVALID, "bad-txns-valuebalance-nonzero");
|
||||
}
|
||||
if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE )
|
||||
acpublic = 1;
|
||||
if ( acpublic != 0 && (tx.vShieldedSpend.empty() == 0 || tx.vShieldedOutput.empty() == 0) )
|
||||
{
|
||||
return state.DoS(100, error("CheckTransaction(): this is a public chain, no sapling allowed"),
|
||||
@@ -1725,7 +1731,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
if (pfMissingInputs)
|
||||
*pfMissingInputs = true;
|
||||
//fprintf(stderr,"missing inputs\n");
|
||||
return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
|
||||
//return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1973,12 +1980,13 @@ bool myAddtomempool(CTransaction &tx, CValidationState *pstate)
|
||||
pstate = &state;
|
||||
CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
|
||||
if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
|
||||
return(AcceptToMemoryPool(mempool, *pstate, tx, false, &fMissingInputs, !fOverrideFees));
|
||||
return(AcceptToMemoryPool(mempool, *pstate, tx, true, &fMissingInputs, !fOverrideFees));
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
|
||||
{
|
||||
memset(&hashBlock,0,sizeof(hashBlock));
|
||||
// need a GetTransaction without lock so the validation code for assets can run without deadlock
|
||||
{
|
||||
//fprintf(stderr,"check mempool\n");
|
||||
@@ -2022,6 +2030,7 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
|
||||
{
|
||||
CBlockIndex *pindexSlow = NULL;
|
||||
memset(&hashBlock,0,sizeof(hashBlock));
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
@@ -4678,7 +4687,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
||||
const uint256 &hash = tx.GetHash();
|
||||
if ( tx.vjoinsplit.size() == 0 ) {
|
||||
transactionsToRemove.push_back(tx);
|
||||
tmpmempool.addUnchecked(hash,e,!IsInitialBlockDownload());
|
||||
tmpmempool.addUnchecked(hash,e,true);
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
|
||||
@@ -4756,6 +4765,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
||||
// 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;
|
||||
LOCK(mempool.cs);
|
||||
BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) {
|
||||
CTransaction tx = e.GetTx();
|
||||
CValidationState state; bool fMissingInputs,fOverrideFees = false;
|
||||
@@ -5201,11 +5211,11 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo
|
||||
CheckBlockIndex();
|
||||
if (!ret && futureblock == 0)
|
||||
{
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
||||
/*if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
||||
{
|
||||
//fprintf(stderr,"request headers from failed process block peer\n");
|
||||
pfrom->PushMessage("getheaders", chainActive.GetLocator(chainActive.LastTip()), uint256());
|
||||
}
|
||||
}*/
|
||||
komodo_longestchain();
|
||||
return error("%s: AcceptBlock FAILED", __func__);
|
||||
}
|
||||
@@ -5623,8 +5633,11 @@ bool static LoadBlockIndexDB()
|
||||
CBlockIndex *pindex;
|
||||
if ( (pindex= chainActive.LastTip()) != 0 )
|
||||
{
|
||||
fprintf(stderr,"set sapling height, if possible from ht.%d %u\n",(int32_t)pindex->GetHeight(),(uint32_t)pindex->nTime);
|
||||
komodo_activate_sapling(pindex);
|
||||
if ( ASSETCHAINS_SAPLING <= 0 )
|
||||
{
|
||||
fprintf(stderr,"set sapling height, if possible from ht.%d %u\n",(int32_t)pindex->GetHeight(),(uint32_t)pindex->nTime);
|
||||
komodo_activate_sapling(pindex);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -463,8 +463,6 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
||||
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr;
|
||||
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight);
|
||||
|
||||
//if ( blocktime > pindexPrev->GetMedianTimePast()+60 )
|
||||
// blocktime = pindexPrev->GetMedianTimePast() + 60;
|
||||
if (ASSETCHAINS_LWMAPOS != 0)
|
||||
{
|
||||
uint32_t nBitsPOS;
|
||||
@@ -479,6 +477,9 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
||||
}
|
||||
else
|
||||
{
|
||||
blocktime = GetAdjustedTime();
|
||||
//if ( blocktime > pindexPrev->GetMedianTimePast()+60 )
|
||||
// blocktime = pindexPrev->GetMedianTimePast() + 60;
|
||||
siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig);
|
||||
}
|
||||
|
||||
@@ -736,7 +737,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isStake)
|
||||
//if ( !isStake || ASSETCHAINS_STAKED != 0 )
|
||||
{
|
||||
if (!reservekey.GetReservedKey(pubkey))
|
||||
{
|
||||
|
||||
@@ -136,7 +136,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "z_shieldcoinbase", 3},
|
||||
{ "z_getoperationstatus", 0},
|
||||
{ "z_getoperationresult", 0},
|
||||
{ "z_importkey", 1 },
|
||||
{ "paxprice", 4 },
|
||||
{ "paxprices", 3 },
|
||||
{ "paxpending", 0 },
|
||||
|
||||
@@ -606,9 +606,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
|
||||
return BIP22ValidationResult(state);
|
||||
}
|
||||
}
|
||||
|
||||
if (strMode != "template")
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
||||
else
|
||||
{
|
||||
strMode = "template";
|
||||
}
|
||||
|
||||
bool fvNodesEmpty;
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
uint32_t komodo_segid32(char *coinaddr);
|
||||
int64_t komodo_coinsupply(int64_t *zfundsp,int32_t height);
|
||||
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
|
||||
#define KOMODO_VERSION "0.3.1"
|
||||
#define KOMODO_VERSION "0.3.0"
|
||||
#define VERUS_VERSION "0.4.0g"
|
||||
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
|
||||
extern uint32_t ASSETCHAINS_CC;
|
||||
|
||||
@@ -1274,7 +1274,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp)
|
||||
// push to local node and sync with wallets
|
||||
CValidationState state;
|
||||
bool fMissingInputs;
|
||||
if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
|
||||
if (!AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, !fOverrideFees)) {
|
||||
if (state.IsInvalid()) {
|
||||
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
|
||||
} else {
|
||||
|
||||
@@ -33,7 +33,10 @@ 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);
|
||||
<<<<<<< HEAD:src/rpcblockchain.old
|
||||
extern int32_t KOMODO_LONGESTCHAIN;
|
||||
=======
|
||||
>>>>>>> master:src/rpcblockchain.cpp
|
||||
|
||||
double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
|
||||
{
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
#include <zmq.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <cryptoconditions.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "cc/eval.h"
|
||||
#include "importcoin.h"
|
||||
#include "base58.h"
|
||||
#include "core_io.h"
|
||||
#include "crosschain.h"
|
||||
#include "key.h"
|
||||
#include "komodo_structs.h"
|
||||
#include "main.h"
|
||||
#include "notarisationdb.h"
|
||||
#include "primitives/block.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/cc.h"
|
||||
#include "script/interpreter.h"
|
||||
#include "script/serverchecker.h"
|
||||
#include "txmempool.h"
|
||||
#include "crosschain.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
extern uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth);
|
||||
extern bool KOMODO_TEST_ASSETCHAIN_SKIP_POW;
|
||||
|
||||
|
||||
/*
|
||||
* Tests for the whole process of creating and validating notary proofs
|
||||
* using proof roots (MoMoMs). This is to support coin imports.
|
||||
*/
|
||||
|
||||
namespace TestCrossChainProof {
|
||||
|
||||
|
||||
class TestCrossChain : public ::testing::Test, public Eval {
|
||||
public:
|
||||
bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
|
||||
{
|
||||
NotarisationData data(2);
|
||||
return ParseNotarisationOpReturn(tx, data); // If it parses it's valid
|
||||
}
|
||||
protected:
|
||||
static void SetUpTestCase() { }
|
||||
virtual void SetUp() {
|
||||
KOMODO_TEST_ASSETCHAIN_SKIP_POW = 1;
|
||||
ASSETCHAINS_CC = 1;
|
||||
EVAL_TEST = this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
uint256 endianHash(uint256 h)
|
||||
{
|
||||
uint256 out;
|
||||
for (int i=0; i<32; i++) {
|
||||
out.begin()[31-i] = h.begin()[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCrossChain, testCreateAndValidateImportProof)
|
||||
{
|
||||
/*
|
||||
* This tests the full process of creation of a cross chain proof.
|
||||
* For the purposes of the test we will use one assetchain and a KMD chain.
|
||||
*
|
||||
* In order to do this test, we need 2 blockchains, so we'll fork and make a socket
|
||||
* for IPC.
|
||||
*/
|
||||
|
||||
int childPid = fork();
|
||||
void *ctx = zmq_ctx_new();
|
||||
void *socket = zmq_socket(ctx, ZMQ_PAIR);
|
||||
if (!childPid)
|
||||
strcpy(ASSETCHAINS_SYMBOL, "PIZZA");
|
||||
setupChain();
|
||||
std::vector<CBlock> blocks;
|
||||
blocks.resize(1000);
|
||||
NotarisationData a2kmd(0), kmd2a(1);
|
||||
int numTestNotarisations = 10;
|
||||
|
||||
|
||||
auto SendIPC = [&] (std::vector<uint8_t> v) {
|
||||
assert(v.size() == zmq_send(socket, v.data(), v.size(), 0));
|
||||
};
|
||||
|
||||
auto RecvIPC = [&] () {
|
||||
std::vector<uint8_t> out;
|
||||
out.resize(100000);
|
||||
int len = zmq_recv(socket, out.data(), out.size(), 0);
|
||||
assert(len != -1);
|
||||
out.resize(len);
|
||||
return out;
|
||||
};
|
||||
|
||||
auto RecordNotarisation = [&] (CTransaction inputTx, NotarisationData data) {
|
||||
CMutableTransaction mtx = spendTx(inputTx);
|
||||
mtx.vout.resize(2);
|
||||
mtx.vout[0].scriptPubKey << VCH(notaryKey.GetPubKey().begin(), 33) << OP_CHECKSIG;
|
||||
mtx.vout[1].scriptPubKey << OP_RETURN << E_MARSHAL(ss << data);
|
||||
mtx.vout[1].nValue = 0;
|
||||
mtx.vin[0].scriptSig << getSig(mtx, inputTx.vout[0].scriptPubKey);
|
||||
|
||||
acceptTxFail(CTransaction(mtx));
|
||||
return mtx.GetHash();
|
||||
};
|
||||
|
||||
auto RunTestAssetchain = [&] ()
|
||||
{
|
||||
NotarisationData n(0), back(1);
|
||||
strcpy(n.symbol, "PIZZA");
|
||||
n.ccId = 2;
|
||||
int height = 0;
|
||||
|
||||
/*
|
||||
* Send notarisations and write backnotarisations
|
||||
*/
|
||||
for (int ni=0; ni<numTestNotarisations; ni++)
|
||||
{
|
||||
generateBlock(&blocks[++height]);
|
||||
generateBlock(&blocks[++height]);
|
||||
n.blockHash = blocks[height].GetHash();
|
||||
n.MoM = endianHash(komodo_calcMoM(n.height=height, n.MoMDepth=2));
|
||||
SendIPC(E_MARSHAL(ss << n));
|
||||
assert(E_UNMARSHAL(RecvIPC(), ss >> back));
|
||||
RecordNotarisation(blocks[height].vtx[0], back);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test a proof
|
||||
*/
|
||||
uint256 txid = blocks[7].vtx[0].GetHash();
|
||||
TxProof proof = GetAssetchainProof(txid);
|
||||
SendIPC(E_MARSHAL(ss << txid; ss << proof));
|
||||
E_UNMARSHAL(RecvIPC(), ss >> proof);
|
||||
|
||||
std::pair<uint256,NotarisationData> bn;
|
||||
if (!GetNextBacknotarisation(proof.first, bn)) {
|
||||
printf("GetNextBackNotarisation failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (proof.second.Exec(txid) != bn.second.MoMoM) {
|
||||
printf("MoMom incorrect\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
auto RunTestKmd = [&] ()
|
||||
{
|
||||
NotarisationData n(0);
|
||||
int height = 0;
|
||||
|
||||
/*
|
||||
* Write notarisations and send backnotarisations
|
||||
*/
|
||||
for (int ni=0; ni<numTestNotarisations; ni++)
|
||||
{
|
||||
n.IsBackNotarisation = 0;
|
||||
E_UNMARSHAL(RecvIPC(), ss >> n);
|
||||
// Grab a coinbase input to fund notarisation
|
||||
generateBlock(&blocks[++height]);
|
||||
n.txHash = RecordNotarisation(blocks[height].vtx[0], n);
|
||||
{
|
||||
std::vector<uint256> moms;
|
||||
uint256 destNotarisationTxid;
|
||||
n.MoMoM = CalculateProofRoot(n.symbol, 2, height, moms, destNotarisationTxid);
|
||||
}
|
||||
n.IsBackNotarisation = 1;
|
||||
SendIPC(E_MARSHAL(ss << n));
|
||||
}
|
||||
|
||||
/*
|
||||
* Extend proof
|
||||
*/
|
||||
TxProof proof;
|
||||
uint256 txid;
|
||||
// Extend proof to MoMoM
|
||||
assert(E_UNMARSHAL(RecvIPC(), ss >> txid; ss >> proof));
|
||||
proof = GetCrossChainProof(txid, (char*)"PIZZA", 2, proof);
|
||||
SendIPC(E_MARSHAL(ss << proof));
|
||||
};
|
||||
|
||||
const char endpoint[] = "ipc://tmpKomodoTestCrossChainSock";
|
||||
|
||||
if (!childPid) {
|
||||
assert(0 == zmq_connect(socket, endpoint));
|
||||
usleep(20000);
|
||||
int out = RunTestAssetchain();
|
||||
if (!out) printf("Assetchain success\n");
|
||||
exit(out);
|
||||
}
|
||||
else {
|
||||
assert(0 == zmq_bind(socket, endpoint));
|
||||
RunTestKmd();
|
||||
int returnStatus;
|
||||
waitpid(childPid, &returnStatus, 0);
|
||||
unlink("tmpKomodoTestCrossChainSock");
|
||||
ASSERT_EQ(0, returnStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} /* namespace TestCrossChainProof */
|
||||
@@ -670,7 +670,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
|
||||
pindexNew->nCachedBranchId = diskindex.nCachedBranchId;
|
||||
pindexNew->nTx = diskindex.nTx;
|
||||
pindexNew->nSproutValue = diskindex.nSproutValue;
|
||||
|
||||
pindexNew->nSaplingValue = diskindex.nSaplingValue;
|
||||
|
||||
// Consistency checks
|
||||
auto header = pindexNew->GetBlockHeader();
|
||||
if (header.GetHash() != pindexNew->GetBlockHash())
|
||||
|
||||
1424
src/veruslaunch.cpp
1424
src/veruslaunch.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
|
||||
// Copyright (c) 2018 The Verus developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef VERUS_LAUNCH_H
|
||||
#define VERUS_LAUNCH_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#define WHITELIST_COUNT 704
|
||||
|
||||
extern const char *whitelist_ids[WHITELIST_COUNT];
|
||||
extern const char *whitelist_address;
|
||||
extern uint64_t whitelist_masks[WHITELIST_COUNT];
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
||||
#include "asyncrpcoperation.h"
|
||||
#include "paymentdisclosure.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "transaction_builder.h"
|
||||
#include "wallet.h"
|
||||
#include "zcash/Address.hpp"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
@@ -24,11 +25,13 @@
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
// Input UTXO is a tuple of txid, vout, amount
|
||||
typedef std::tuple<COutPoint, CAmount> MergeToAddressInputUTXO;
|
||||
// Input UTXO is a tuple of txid, vout, amount, script
|
||||
typedef std::tuple<COutPoint, CAmount, CScript> MergeToAddressInputUTXO;
|
||||
|
||||
// Input JSOP is a tuple of JSOutpoint, note, amount, spending key
|
||||
typedef std::tuple<JSOutPoint, SproutNote, CAmount, SpendingKey> MergeToAddressInputNote;
|
||||
typedef std::tuple<JSOutPoint, SproutNote, CAmount, SproutSpendingKey> MergeToAddressInputSproutNote;
|
||||
|
||||
typedef std::tuple<SaplingOutPoint, SaplingNote, CAmount, SaplingExpandedSpendingKey> MergeToAddressInputSaplingNote;
|
||||
|
||||
// A recipient is a tuple of address, memo (optional if zaddr)
|
||||
typedef std::tuple<std::string, std::string> MergeToAddressRecipient;
|
||||
@@ -53,33 +56,36 @@ class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation
|
||||
{
|
||||
public:
|
||||
AsyncRPCOperation_mergetoaddress(
|
||||
CMutableTransaction contextualTx,
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs,
|
||||
std::vector<MergeToAddressInputNote> noteInputs,
|
||||
MergeToAddressRecipient recipient,
|
||||
CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE,
|
||||
UniValue contextInfo = NullUniValue);
|
||||
boost::optional<TransactionBuilder> builder,
|
||||
CMutableTransaction contextualTx,
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs,
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs,
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs,
|
||||
MergeToAddressRecipient recipient,
|
||||
CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE,
|
||||
UniValue contextInfo = NullUniValue);
|
||||
virtual ~AsyncRPCOperation_mergetoaddress();
|
||||
|
||||
|
||||
// We don't want to be copied or moved around
|
||||
AsyncRPCOperation_mergetoaddress(AsyncRPCOperation_mergetoaddress const&) = delete; // Copy construct
|
||||
AsyncRPCOperation_mergetoaddress(AsyncRPCOperation_mergetoaddress&&) = delete; // Move construct
|
||||
AsyncRPCOperation_mergetoaddress& operator=(AsyncRPCOperation_mergetoaddress const&) = delete; // Copy assign
|
||||
AsyncRPCOperation_mergetoaddress& operator=(AsyncRPCOperation_mergetoaddress&&) = delete; // Move assign
|
||||
|
||||
|
||||
virtual void main();
|
||||
|
||||
|
||||
virtual UniValue getStatus() const;
|
||||
|
||||
|
||||
bool testmode = false; // Set to true to disable sending txs and generating proofs
|
||||
|
||||
bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database.
|
||||
|
||||
|
||||
bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database.
|
||||
|
||||
private:
|
||||
friend class TEST_FRIEND_AsyncRPCOperation_mergetoaddress; // class for unit testing
|
||||
|
||||
|
||||
UniValue contextinfo_; // optional data to include in return value from getStatus()
|
||||
|
||||
|
||||
bool isUsingBuilder_; // Indicates that no Sprout addresses are involved
|
||||
uint32_t consensusBranchId_;
|
||||
CAmount fee_;
|
||||
int mindepth_;
|
||||
@@ -88,43 +94,45 @@ private:
|
||||
bool isToZaddr_;
|
||||
CTxDestination toTaddr_;
|
||||
PaymentAddress toPaymentAddress_;
|
||||
|
||||
|
||||
uint256 joinSplitPubKey_;
|
||||
unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES];
|
||||
|
||||
|
||||
// The key is the result string from calling JSOutPoint::ToString()
|
||||
std::unordered_map<std::string, MergeToAddressWitnessAnchorData> jsopWitnessAnchorMap;
|
||||
|
||||
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs_;
|
||||
std::vector<MergeToAddressInputNote> noteInputs_;
|
||||
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs_;
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs_;
|
||||
|
||||
TransactionBuilder builder_;
|
||||
CTransaction tx_;
|
||||
|
||||
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> get_memo_from_hex_string(std::string s);
|
||||
bool main_impl();
|
||||
|
||||
|
||||
// JoinSplit without any input notes to spend
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo&);
|
||||
|
||||
|
||||
// JoinSplit with input notes to spend (JSOutPoints))
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo&, std::vector<JSOutPoint>&);
|
||||
|
||||
|
||||
// JoinSplit where you have the witnesses and anchor
|
||||
UniValue perform_joinsplit(
|
||||
MergeToAddressJSInfo& info,
|
||||
std::vector<boost::optional<SproutWitness>> witnesses,
|
||||
uint256 anchor);
|
||||
|
||||
MergeToAddressJSInfo& info,
|
||||
std::vector<boost::optional<SproutWitness>> witnesses,
|
||||
uint256 anchor);
|
||||
|
||||
void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error
|
||||
|
||||
|
||||
void lock_utxos();
|
||||
|
||||
|
||||
void unlock_utxos();
|
||||
|
||||
|
||||
void lock_notes();
|
||||
|
||||
|
||||
void unlock_notes();
|
||||
|
||||
|
||||
// payment disclosure!
|
||||
std::vector<PaymentDisclosureKeyInfo> paymentDisclosureData_;
|
||||
};
|
||||
@@ -135,54 +143,54 @@ class TEST_FRIEND_AsyncRPCOperation_mergetoaddress
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<AsyncRPCOperation_mergetoaddress> delegate;
|
||||
|
||||
|
||||
TEST_FRIEND_AsyncRPCOperation_mergetoaddress(std::shared_ptr<AsyncRPCOperation_mergetoaddress> ptr) : delegate(ptr) {}
|
||||
|
||||
|
||||
CTransaction getTx()
|
||||
{
|
||||
return delegate->tx_;
|
||||
}
|
||||
|
||||
|
||||
void setTx(CTransaction tx)
|
||||
{
|
||||
delegate->tx_ = tx;
|
||||
}
|
||||
|
||||
|
||||
// Delegated methods
|
||||
|
||||
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> get_memo_from_hex_string(std::string s)
|
||||
{
|
||||
return delegate->get_memo_from_hex_string(s);
|
||||
}
|
||||
|
||||
|
||||
bool main_impl()
|
||||
{
|
||||
return delegate->main_impl();
|
||||
}
|
||||
|
||||
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo& info)
|
||||
{
|
||||
return delegate->perform_joinsplit(info);
|
||||
}
|
||||
|
||||
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo& info, std::vector<JSOutPoint>& v)
|
||||
{
|
||||
return delegate->perform_joinsplit(info, v);
|
||||
}
|
||||
|
||||
|
||||
UniValue perform_joinsplit(
|
||||
MergeToAddressJSInfo& info,
|
||||
std::vector<boost::optional<SproutWitness>> witnesses,
|
||||
uint256 anchor)
|
||||
MergeToAddressJSInfo& info,
|
||||
std::vector<boost::optional<SproutWitness>> witnesses,
|
||||
uint256 anchor)
|
||||
{
|
||||
return delegate->perform_joinsplit(info, witnesses, anchor);
|
||||
}
|
||||
|
||||
|
||||
void sign_send_raw_transaction(UniValue obj)
|
||||
{
|
||||
delegate->sign_send_raw_transaction(obj);
|
||||
}
|
||||
|
||||
|
||||
void set_state(OperationStatus state)
|
||||
{
|
||||
delegate->state_.store(state);
|
||||
|
||||
@@ -123,7 +123,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
||||
|
||||
|
||||
// Enable payment disclosure if requested
|
||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false);
|
||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true);
|
||||
}
|
||||
|
||||
AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() {
|
||||
@@ -1366,7 +1366,8 @@ void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CBitcoinAddress *
|
||||
}
|
||||
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> AsyncRPCOperation_sendmany::get_memo_from_hex_string(std::string s) {
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> memo = {{0x00}};
|
||||
// initialize to default memo (no_memo), see section 5.5 of the protocol spec
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}};
|
||||
|
||||
std::vector<unsigned char> rawMemo = ParseHex(s.c_str());
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
|
||||
bool testmode = false; // Set to true to disable sending txs and generating proofs
|
||||
|
||||
bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database.
|
||||
bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database.
|
||||
|
||||
private:
|
||||
friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing
|
||||
|
||||
@@ -93,7 +93,7 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
||||
lock_utxos();
|
||||
|
||||
// Enable payment disclosure if requested
|
||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false);
|
||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true);
|
||||
}
|
||||
|
||||
AsyncRPCOperation_shieldcoinbase::~AsyncRPCOperation_shieldcoinbase() {
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
bool testmode = false; // Set to true to disable sending txs and generating proofs
|
||||
bool cheatSpend = false; // set when this is shielding a cheating coinbase
|
||||
|
||||
bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database.
|
||||
bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database.
|
||||
|
||||
private:
|
||||
friend class ShieldToAddress;
|
||||
|
||||
@@ -42,7 +42,7 @@ UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp)
|
||||
return NullUniValue;
|
||||
|
||||
string enableArg = "paymentdisclosure";
|
||||
auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, false);
|
||||
auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, true);
|
||||
string strPaymentDisclosureDisabledMsg = "";
|
||||
if (!fEnablePaymentDisclosure) {
|
||||
strPaymentDisclosureDisabledMsg = experimentalDisabledHelpMsg("z_getpaymentdisclosure", enableArg);
|
||||
@@ -149,7 +149,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp)
|
||||
return NullUniValue;
|
||||
|
||||
string enableArg = "paymentdisclosure";
|
||||
auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, false);
|
||||
auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, true);
|
||||
string strPaymentDisclosureDisabledMsg = "";
|
||||
if (!fEnablePaymentDisclosure) {
|
||||
strPaymentDisclosureDisabledMsg = experimentalDisabledHelpMsg("z_validatepaymentdisclosure", enableArg);
|
||||
|
||||
@@ -111,7 +111,6 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
|
||||
entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
|
||||
entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight));
|
||||
} else entry.push_back(Pair("confirmations", confirms));
|
||||
|
||||
uint256 hash = wtx.GetHash();
|
||||
entry.push_back(Pair("txid", hash.GetHex()));
|
||||
UniValue conflicts(UniValue::VARR);
|
||||
@@ -1421,9 +1420,9 @@ UniValue sendmany(const UniValue& params, bool fHelp)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_);
|
||||
}
|
||||
|
||||
if (destinations.count(dest)) {
|
||||
/*if (destinations.count(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
|
||||
}
|
||||
}*/
|
||||
destinations.insert(dest);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
@@ -2444,6 +2443,7 @@ UniValue walletlock(const UniValue& params, bool fHelp)
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
int32_t komodo_acpublic(uint32_t tiptime);
|
||||
|
||||
UniValue encryptwallet(const UniValue& params, bool fHelp)
|
||||
{
|
||||
@@ -2451,7 +2451,8 @@ UniValue encryptwallet(const UniValue& params, bool fHelp)
|
||||
return NullUniValue;
|
||||
|
||||
string enableArg = "developerencryptwallet";
|
||||
auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, false);
|
||||
int32_t flag = (komodo_acpublic(0) || ASSETCHAINS_SYMBOL[0] == 0);
|
||||
auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, flag);
|
||||
|
||||
std::string strWalletEncryptionDisabledMsg = "";
|
||||
if (!fEnableWalletEncryption) {
|
||||
@@ -2951,8 +2952,8 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||
|
||||
"\nExamples\n"
|
||||
+ HelpExampleCli("z_listunspent", "")
|
||||
+ HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"")
|
||||
+ HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"")
|
||||
+ HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\",\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\"]\"")
|
||||
+ HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\",\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\"]\"")
|
||||
);
|
||||
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VBOOL)(UniValue::VARR));
|
||||
@@ -3788,8 +3789,8 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
||||
" \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
|
||||
+ HelpExampleRpc("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
|
||||
+ HelpExampleCli("z_listreceivedbyaddress", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"")
|
||||
+ HelpExampleRpc("z_listreceivedbyaddress", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"")
|
||||
);
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
@@ -4121,8 +4122,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||
"\nResult:\n"
|
||||
"\"operationid\" (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" '[{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]'")
|
||||
+ HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]")
|
||||
+ HelpExampleCli("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" '[{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]'")
|
||||
+ HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]")
|
||||
);
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
@@ -4212,15 +4213,10 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||
}
|
||||
// If we are sending from a shielded address, all recipient
|
||||
// shielded addresses must be of the same type.
|
||||
if (fromSprout && toSapling) {
|
||||
if ((fromSprout && toSapling) || (fromSapling && toSprout)) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send from a Sprout address to a Sapling address using z_sendmany");
|
||||
}
|
||||
if (fromSapling && toSprout) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send from a Sapling address to a Sprout address using z_sendmany");
|
||||
"Cannot send between Sprout and Sapling addresses using z_sendmany");
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
|
||||
@@ -4432,8 +4428,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
||||
" \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
|
||||
+ HelpExampleRpc("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
|
||||
+ HelpExampleCli("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"")
|
||||
+ HelpExampleRpc("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"")
|
||||
);
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
@@ -4621,160 +4617,159 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
#define MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT 50
|
||||
#define MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT 10
|
||||
#define MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT 10
|
||||
#define MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT 90
|
||||
|
||||
#define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION)
|
||||
#define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION)
|
||||
#define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION)
|
||||
|
||||
UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return NullUniValue;
|
||||
|
||||
|
||||
string enableArg = "zmergetoaddress";
|
||||
auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, false);
|
||||
auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, true);
|
||||
std::string strDisabledMsg = "";
|
||||
if (!fEnableMergeToAddress) {
|
||||
strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg);
|
||||
}
|
||||
|
||||
|
||||
if (fHelp || params.size() < 2 || params.size() > 6)
|
||||
throw runtime_error(
|
||||
"z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n"
|
||||
+ strDisabledMsg +
|
||||
"\nMerge multiple UTXOs and notes into a single UTXO or note. Coinbase UTXOs are ignored; use `z_shieldcoinbase`"
|
||||
"\nto combine those into a single note."
|
||||
"\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked. If there is an error, they"
|
||||
"\nare unlocked. The RPC call `listlockunspent` can be used to return a list of locked UTXOs."
|
||||
"\n\nThe number of UTXOs and notes selected for merging can be limited by the caller. If the transparent limit"
|
||||
"\nparameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit option will determine the"
|
||||
"\nnumber of UTXOs. Any limit is constrained by the consensus rule defining a maximum transaction size of"
|
||||
+ strprintf("\n%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE_AFTER_SAPLING)
|
||||
+ HelpRequiringPassphrase() + "\n"
|
||||
"\nArguments:\n"
|
||||
"1. fromaddresses (string, required) A JSON array with addresses.\n"
|
||||
" The following special strings are accepted inside the array:\n"
|
||||
" - \"*\": Merge both UTXOs and notes from all addresses belonging to the wallet.\n"
|
||||
" - \"ANY_TADDR\": Merge UTXOs from all t-addrs belonging to the wallet.\n"
|
||||
" - \"ANY_ZADDR\": Merge notes from all z-addrs belonging to the wallet.\n"
|
||||
" If a special string is given, any given addresses of that type will be ignored.\n"
|
||||
" [\n"
|
||||
" \"address\" (string) Can be a t-addr or a z-addr\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
"2. \"toaddress\" (string, required) The t-addr or z-addr to send the funds to.\n"
|
||||
"3. fee (numeric, optional, default="
|
||||
+ strprintf("%s", FormatMoney(MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
|
||||
"4. transparent_limit (numeric, optional, default="
|
||||
+ strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n"
|
||||
"4. shielded_limit (numeric, optional, default="
|
||||
+ strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n"
|
||||
"5. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"remainingUTXOs\": xxx (numeric) Number of UTXOs still available for merging.\n"
|
||||
" \"remainingTransparentValue\": xxx (numeric) Value of UTXOs still available for merging.\n"
|
||||
" \"remainingNotes\": xxx (numeric) Number of notes still available for merging.\n"
|
||||
" \"remainingShieldedValue\": xxx (numeric) Value of notes still available for merging.\n"
|
||||
" \"mergingUTXOs\": xxx (numeric) Number of UTXOs being merged.\n"
|
||||
" \"mergingTransparentValue\": xxx (numeric) Value of UTXOs being merged.\n"
|
||||
" \"mergingNotes\": xxx (numeric) Number of notes being merged.\n"
|
||||
" \"mergingShieldedValue\": xxx (numeric) Value of notes being merged.\n"
|
||||
" \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_mergetoaddress", "'[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf")
|
||||
+ HelpExampleRpc("z_mergetoaddress", "[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"], \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
|
||||
);
|
||||
|
||||
"z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n"
|
||||
+ strDisabledMsg +
|
||||
"\nMerge multiple UTXOs and notes into a single UTXO or note. Coinbase UTXOs are ignored; use `z_shieldcoinbase`"
|
||||
"\nto combine those into a single note."
|
||||
"\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked. If there is an error, they"
|
||||
"\nare unlocked. The RPC call `listlockunspent` can be used to return a list of locked UTXOs."
|
||||
"\n\nThe number of UTXOs and notes selected for merging can be limited by the caller. If the transparent limit"
|
||||
"\nparameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit option will determine the"
|
||||
"\nnumber of UTXOs. Any limit is constrained by the consensus rule defining a maximum transaction size of"
|
||||
+ strprintf("\n%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE_AFTER_SAPLING)
|
||||
+ HelpRequiringPassphrase() + "\n"
|
||||
"\nArguments:\n"
|
||||
"1. fromaddresses (string, required) A JSON array with addresses.\n"
|
||||
" The following special strings are accepted inside the array:\n"
|
||||
" - \"ANY_TADDR\": Merge UTXOs from any t-addrs belonging to the wallet.\n"
|
||||
" - \"ANY_SPROUT\": Merge notes from any Sprout z-addrs belonging to the wallet.\n"
|
||||
" - \"ANY_SAPLING\": Merge notes from any Sapling z-addrs belonging to the wallet.\n"
|
||||
" If a special string is given, any given addresses of that type will be ignored.\n"
|
||||
" [\n"
|
||||
" \"address\" (string) Can be a t-addr or a z-addr\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
"2. \"toaddress\" (string, required) The t-addr or z-addr to send the funds to.\n"
|
||||
"3. fee (numeric, optional, default="
|
||||
+ strprintf("%s", FormatMoney(MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
|
||||
"4. transparent_limit (numeric, optional, default="
|
||||
+ strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n"
|
||||
"4. shielded_limit (numeric, optional, default="
|
||||
+ strprintf("%d Sprout or %d Sapling Notes", MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT, MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n"
|
||||
"5. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"remainingUTXOs\": xxx (numeric) Number of UTXOs still available for merging.\n"
|
||||
" \"remainingTransparentValue\": xxx (numeric) Value of UTXOs still available for merging.\n"
|
||||
" \"remainingNotes\": xxx (numeric) Number of notes still available for merging.\n"
|
||||
" \"remainingShieldedValue\": xxx (numeric) Value of notes still available for merging.\n"
|
||||
" \"mergingUTXOs\": xxx (numeric) Number of UTXOs being merged.\n"
|
||||
" \"mergingTransparentValue\": xxx (numeric) Value of UTXOs being merged.\n"
|
||||
" \"mergingNotes\": xxx (numeric) Number of notes being merged.\n"
|
||||
" \"mergingShieldedValue\": xxx (numeric) Value of notes being merged.\n"
|
||||
" \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("z_mergetoaddress", "'[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf")
|
||||
+ HelpExampleRpc("z_mergetoaddress", "[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"], \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"")
|
||||
);
|
||||
|
||||
if (!fEnableMergeToAddress) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled.");
|
||||
}
|
||||
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
bool useAny = false;
|
||||
|
||||
bool useAnyUTXO = false;
|
||||
bool useAnyNote = false;
|
||||
bool useAnySprout = false;
|
||||
bool useAnySapling = false;
|
||||
std::set<CTxDestination> taddrs = {};
|
||||
std::set<libzcash::PaymentAddress> zaddrs = {};
|
||||
|
||||
uint32_t branchId = CurrentEpochBranchId(chainActive.Height(), Params().GetConsensus());
|
||||
|
||||
|
||||
UniValue addresses = params[0].get_array();
|
||||
if (addresses.size()==0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, fromaddresses array is empty.");
|
||||
|
||||
|
||||
// Keep track of addresses to spot duplicates
|
||||
std::set<std::string> setAddress;
|
||||
|
||||
|
||||
// Sources
|
||||
bool containsSaplingZaddrSource = false;
|
||||
for (const UniValue& o : addresses.getValues()) {
|
||||
if (!o.isStr())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string");
|
||||
|
||||
|
||||
std::string address = o.get_str();
|
||||
if (address == "*") {
|
||||
useAny = true;
|
||||
} else if (address == "ANY_TADDR") {
|
||||
|
||||
if (address == "ANY_TADDR") {
|
||||
useAnyUTXO = true;
|
||||
} else if (address == "ANY_ZADDR") {
|
||||
useAnyNote = true;
|
||||
} else if (address == "ANY_SPROUT") {
|
||||
useAnySprout = true;
|
||||
} else if (address == "ANY_SAPLING") {
|
||||
useAnySapling = true;
|
||||
} else {
|
||||
CTxDestination taddr = DecodeDestination(address);
|
||||
if (IsValidDestination(taddr)) {
|
||||
// Ignore any listed t-addrs if we are using all of them
|
||||
if (!(useAny || useAnyUTXO)) {
|
||||
taddrs.insert(taddr);
|
||||
}
|
||||
taddrs.insert(taddr);
|
||||
} else {
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
if (IsValidPaymentAddress(zaddr, branchId)) {
|
||||
// Ignore listed z-addrs if we are using all of them
|
||||
if (!(useAny || useAnyNote)) {
|
||||
zaddrs.insert(zaddr);
|
||||
}
|
||||
// Check if z-addr is Sapling
|
||||
bool isSapling = boost::get<libzcash::SaplingPaymentAddress>(&zaddr) != nullptr;
|
||||
containsSaplingZaddrSource |= isSapling;
|
||||
if (IsValidPaymentAddress(zaddr)) {
|
||||
zaddrs.insert(zaddr);
|
||||
} else {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
string("Invalid parameter, unknown address format: ") + address);
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unknown address format: ") + address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (setAddress.count(address))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + address);
|
||||
setAddress.insert(address);
|
||||
}
|
||||
|
||||
|
||||
if (useAnyUTXO && taddrs.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific t-addrs when using \"ANY_TADDR\"");
|
||||
}
|
||||
if ((useAnySprout || useAnySapling) && zaddrs.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SPROUT\" or \"ANY_SAPLING\"");
|
||||
}
|
||||
|
||||
const int nextBlockHeight = chainActive.Height() + 1;
|
||||
const bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
|
||||
const bool saplingActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
|
||||
|
||||
// Validate the destination address
|
||||
auto destaddress = params[1].get_str();
|
||||
bool isToZaddr = false;
|
||||
bool isToSproutZaddr = false;
|
||||
bool isToSaplingZaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(destaddress);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
if (IsValidPaymentAddressString(destaddress, branchId)) {
|
||||
isToZaddr = true;
|
||||
|
||||
// Is this a Sapling address?
|
||||
auto res = DecodePaymentAddress(destaddress);
|
||||
if (IsValidPaymentAddress(res)) {
|
||||
isToSaplingZaddr = boost::get<libzcash::SaplingPaymentAddress>(&res) != nullptr;
|
||||
auto decodeAddr = DecodePaymentAddress(destaddress);
|
||||
if (IsValidPaymentAddress(decodeAddr)) {
|
||||
if (boost::get<libzcash::SaplingPaymentAddress>(&decodeAddr) != nullptr) {
|
||||
isToSaplingZaddr = true;
|
||||
// If Sapling is not active, do not allow sending to a sapling addresses.
|
||||
if (!saplingActive) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
isToSproutZaddr = true;
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
}
|
||||
}
|
||||
else if ( ASSETCHAINS_PRIVATE != 0 )
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain");
|
||||
|
||||
|
||||
// Convert fee from currency format to zatoshis
|
||||
CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE;
|
||||
if (params.size() > 2) {
|
||||
@@ -4784,7 +4779,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
nFee = AmountFromValue( params[2] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int nUTXOLimit = MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT;
|
||||
if (params.size() > 3) {
|
||||
nUTXOLimit = params[3].get_int();
|
||||
@@ -4792,19 +4787,22 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of UTXOs cannot be negative");
|
||||
}
|
||||
}
|
||||
|
||||
int nNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT;
|
||||
|
||||
int sproutNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT;
|
||||
int saplingNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT;
|
||||
if (params.size() > 4) {
|
||||
nNoteLimit = params[4].get_int();
|
||||
int nNoteLimit = params[4].get_int();
|
||||
if (nNoteLimit < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of notes cannot be negative");
|
||||
}
|
||||
sproutNoteLimit = nNoteLimit;
|
||||
saplingNoteLimit = nNoteLimit;
|
||||
}
|
||||
|
||||
|
||||
std::string memo;
|
||||
if (params.size() > 5) {
|
||||
memo = params[5].get_str();
|
||||
if (!isToZaddr) {
|
||||
if (!(isToSproutZaddr || isToSaplingZaddr)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr.");
|
||||
} else if (!IsHex(memo)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format.");
|
||||
@@ -4813,75 +4811,56 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", ZC_MEMO_SIZE ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MergeToAddressRecipient recipient(destaddress, memo);
|
||||
|
||||
int nextBlockHeight = chainActive.Height() + 1;
|
||||
bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
|
||||
unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
|
||||
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
||||
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
|
||||
}
|
||||
|
||||
// This RPC does not support Sapling yet.
|
||||
if (isToSaplingZaddr || containsSaplingZaddrSource) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling is not supported yet by z_mergetoadress");
|
||||
}
|
||||
|
||||
// If this RPC does support Sapling...
|
||||
// If Sapling is not active, do not allow sending from or sending to Sapling addresses.
|
||||
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
||||
if (isToSaplingZaddr || containsSaplingZaddrSource) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Prepare to get UTXOs and notes
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs;
|
||||
std::vector<MergeToAddressInputNote> noteInputs;
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs;
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs;
|
||||
CAmount mergedUTXOValue = 0;
|
||||
CAmount mergedNoteValue = 0;
|
||||
CAmount remainingUTXOValue = 0;
|
||||
CAmount remainingNoteValue = 0;
|
||||
#ifdef __LP64__
|
||||
uint64_t utxoCounter = 0;
|
||||
uint64_t noteCounter = 0;
|
||||
#else
|
||||
size_t utxoCounter = 0;
|
||||
size_t noteCounter = 0;
|
||||
#endif
|
||||
bool maxedOutUTXOsFlag = false;
|
||||
bool maxedOutNotesFlag = false;
|
||||
size_t mempoolLimit = (nUTXOLimit != 0) ? nUTXOLimit : (overwinterActive ? 0 : (size_t)GetArg("-mempooltxinputlimit", 0));
|
||||
|
||||
|
||||
unsigned int max_tx_size = saplingActive ? MAX_TX_SIZE_AFTER_SAPLING : MAX_TX_SIZE_BEFORE_SAPLING;
|
||||
size_t estimatedTxSize = 200; // tx overhead + wiggle room
|
||||
if (isToZaddr) {
|
||||
if (isToSproutZaddr) {
|
||||
estimatedTxSize += JOINSPLIT_SIZE;
|
||||
} else if (isToSaplingZaddr) {
|
||||
estimatedTxSize += OUTPUTDESCRIPTION_SIZE;
|
||||
}
|
||||
|
||||
if (useAny || useAnyUTXO || taddrs.size() > 0) {
|
||||
|
||||
if (useAnyUTXO || taddrs.size() > 0) {
|
||||
// Get available utxos
|
||||
vector<COutput> vecOutputs;
|
||||
pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false);
|
||||
|
||||
|
||||
// Find unspent utxos and update estimated size
|
||||
for (const COutput& out : vecOutputs) {
|
||||
if (!out.fSpendable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
CScript scriptPubKey = out.tx->vout[out.i].scriptPubKey;
|
||||
|
||||
CTxDestination address;
|
||||
if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
|
||||
if (!ExtractDestination(scriptPubKey, address)) {
|
||||
continue;
|
||||
}
|
||||
// If taddr is not wildcard "*", filter utxos
|
||||
if (taddrs.size() > 0 && !taddrs.count(address)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
utxoCounter++;
|
||||
CAmount nValue = out.tx->vout[out.i].nValue;
|
||||
|
||||
|
||||
if (!maxedOutUTXOsFlag) {
|
||||
size_t increase = (boost::get<CScriptID>(&address) != nullptr) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE;
|
||||
if (estimatedTxSize + increase >= max_tx_size ||
|
||||
@@ -4891,34 +4870,51 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
} else {
|
||||
estimatedTxSize += increase;
|
||||
COutPoint utxo(out.tx->GetHash(), out.i);
|
||||
utxoInputs.emplace_back(utxo, nValue);
|
||||
utxoInputs.emplace_back(utxo, nValue, scriptPubKey);
|
||||
mergedUTXOValue += nValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (maxedOutUTXOsFlag) {
|
||||
remainingUTXOValue += nValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useAny || useAnyNote || zaddrs.size() > 0) {
|
||||
|
||||
if (useAnySprout || useAnySapling || zaddrs.size() > 0) {
|
||||
// Get available notes
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs);
|
||||
|
||||
|
||||
// If Sapling is not active, do not allow sending from a sapling addresses.
|
||||
if (!saplingActive && saplingEntries.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
||||
}
|
||||
// Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress
|
||||
if (sproutEntries.size() > 0 && saplingEntries.size() > 0) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress");
|
||||
}
|
||||
// If sending between shielded addresses, they must be the same type
|
||||
if ((saplingEntries.size() > 0 && isToSproutZaddr) || (sproutEntries.size() > 0 && isToSaplingZaddr)) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send between Sprout and Sapling addresses using z_mergetoaddress");
|
||||
}
|
||||
|
||||
// Find unspent notes and update estimated size
|
||||
for (CSproutNotePlaintextEntry& entry : sproutEntries) {
|
||||
for (const CSproutNotePlaintextEntry& entry : sproutEntries) {
|
||||
noteCounter++;
|
||||
CAmount nValue = entry.plaintext.value();
|
||||
|
||||
|
||||
if (!maxedOutNotesFlag) {
|
||||
// If we haven't added any notes yet and the merge is to a
|
||||
// z-address, we have already accounted for the first JoinSplit.
|
||||
size_t increase = (noteInputs.empty() && !isToZaddr) || (noteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0;
|
||||
size_t increase = (sproutNoteInputs.empty() && !isToSproutZaddr) || (sproutNoteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0;
|
||||
if (estimatedTxSize + increase >= max_tx_size ||
|
||||
(nNoteLimit > 0 && noteCounter > nNoteLimit))
|
||||
(sproutNoteLimit > 0 && noteCounter > sproutNoteLimit))
|
||||
{
|
||||
maxedOutNotesFlag = true;
|
||||
} else {
|
||||
@@ -4926,31 +4922,49 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
auto zaddr = entry.address;
|
||||
SproutSpendingKey zkey;
|
||||
pwalletMain->GetSproutSpendingKey(zaddr, zkey);
|
||||
noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey);
|
||||
sproutNoteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey);
|
||||
mergedNoteValue += nValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (maxedOutNotesFlag) {
|
||||
remainingNoteValue += nValue;
|
||||
}
|
||||
}
|
||||
|
||||
for (const SaplingNoteEntry& entry : saplingEntries) {
|
||||
noteCounter++;
|
||||
CAmount nValue = entry.note.value();
|
||||
if (!maxedOutNotesFlag) {
|
||||
size_t increase = SPENDDESCRIPTION_SIZE;
|
||||
if (estimatedTxSize + increase >= max_tx_size ||
|
||||
(saplingNoteLimit > 0 && noteCounter > saplingNoteLimit))
|
||||
{
|
||||
maxedOutNotesFlag = true;
|
||||
} else {
|
||||
estimatedTxSize += increase;
|
||||
libzcash::SaplingExtendedSpendingKey extsk;
|
||||
if (!pwalletMain->GetSaplingExtendedSpendingKey(entry.address, extsk)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find spending key for payment address.");
|
||||
}
|
||||
saplingNoteInputs.emplace_back(entry.op, entry.note, nValue, extsk.expsk);
|
||||
mergedNoteValue += nValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxedOutNotesFlag) {
|
||||
remainingNoteValue += nValue;
|
||||
}
|
||||
}
|
||||
// TODO: Add Sapling support
|
||||
}
|
||||
|
||||
#ifdef __LP64__
|
||||
uint64_t numUtxos = utxoInputs.size(); //ca333
|
||||
uint64_t numNotes = noteInputs.size();
|
||||
#else
|
||||
|
||||
size_t numUtxos = utxoInputs.size();
|
||||
size_t numNotes = noteInputs.size();
|
||||
#endif
|
||||
|
||||
|
||||
size_t numNotes = sproutNoteInputs.size() + saplingNoteInputs.size();
|
||||
|
||||
if (numUtxos == 0 && numNotes == 0) {
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge.");
|
||||
}
|
||||
|
||||
|
||||
// Sanity check: Don't do anything if:
|
||||
// - We only have one from address
|
||||
// - It's equal to toaddress
|
||||
@@ -4958,42 +4972,47 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
if (setAddress.size() == 1 && setAddress.count(destaddress) && (numUtxos + numNotes) == 1) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Destination address is also the only source address, and all its funds are already merged.");
|
||||
}
|
||||
|
||||
|
||||
CAmount mergedValue = mergedUTXOValue + mergedNoteValue;
|
||||
if (mergedValue < nFee) {
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
|
||||
strprintf("Insufficient funds, have %s, which is less than miners fee %s",
|
||||
FormatMoney(mergedValue), FormatMoney(nFee)));
|
||||
strprintf("Insufficient funds, have %s, which is less than miners fee %s",
|
||||
FormatMoney(mergedValue), FormatMoney(nFee)));
|
||||
}
|
||||
|
||||
|
||||
// Check that the user specified fee is sane (if too high, it can result in error -25 absurd fee)
|
||||
CAmount netAmount = mergedValue - nFee;
|
||||
if (nFee > netAmount) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the net amount to be shielded %s", FormatMoney(nFee), FormatMoney(netAmount)));
|
||||
}
|
||||
|
||||
|
||||
// Keep record of parameters in context object
|
||||
UniValue contextInfo(UniValue::VOBJ);
|
||||
contextInfo.push_back(Pair("fromaddresses", params[0]));
|
||||
contextInfo.push_back(Pair("toaddress", params[1]));
|
||||
contextInfo.push_back(Pair("fee", ValueFromAmount(nFee)));
|
||||
|
||||
|
||||
// Contextual transaction we will build on
|
||||
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
|
||||
Params().GetConsensus(),
|
||||
nextBlockHeight);
|
||||
bool isShielded = numNotes > 0 || isToZaddr;
|
||||
if (contextualTx.nVersion == 1 && isShielded) {
|
||||
Params().GetConsensus(),
|
||||
nextBlockHeight);
|
||||
bool isSproutShielded = sproutNoteInputs.size() > 0 || isToSproutZaddr;
|
||||
if (contextualTx.nVersion == 1 && isSproutShielded) {
|
||||
contextualTx.nVersion = 2; // Tx format should support vjoinsplit
|
||||
}
|
||||
|
||||
|
||||
// Builder (used if Sapling addresses are involved)
|
||||
boost::optional<TransactionBuilder> builder;
|
||||
if (isToSaplingZaddr || saplingNoteInputs.size() > 0) {
|
||||
builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
|
||||
}
|
||||
// Create operation and add to global queue
|
||||
std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
|
||||
std::shared_ptr<AsyncRPCOperation> operation(
|
||||
new AsyncRPCOperation_mergetoaddress(contextualTx, utxoInputs, noteInputs, recipient, nFee, contextInfo) );
|
||||
new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, sproutNoteInputs, saplingNoteInputs, recipient, nFee, contextInfo) );
|
||||
q->addOperation(operation);
|
||||
AsyncRPCOperationId operationId = operation->getId();
|
||||
|
||||
|
||||
// Return continuation information
|
||||
UniValue o(UniValue::VOBJ);
|
||||
o.push_back(Pair("remainingUTXOs", static_cast<uint64_t>(utxoCounter - numUtxos)));
|
||||
@@ -5161,8 +5180,10 @@ struct komodo_staking *komodo_addutxo(struct komodo_staking *array,int32_t *numk
|
||||
{
|
||||
*maxkp += 1000;
|
||||
array = (struct komodo_staking *)realloc(array,sizeof(*array) * (*maxkp));
|
||||
//fprintf(stderr,"realloc max.%d array.%p\n",*maxkp,array);
|
||||
}
|
||||
kp = &array[(*numkp)++];
|
||||
//fprintf(stderr,"kp.%p num.%d\n",kp,*numkp);
|
||||
memset(kp,0,sizeof(*kp));
|
||||
strcpy(kp->address,address);
|
||||
kp->txid = txid;
|
||||
@@ -5185,15 +5206,11 @@ arith_uint256 _komodo_eligible(struct komodo_staking *kp,arith_uint256 ratio,uin
|
||||
diff = 3600*24*30;
|
||||
if ( iter > 0 )
|
||||
diff += segid*2;
|
||||
coinage = ((uint64_t)kp->nValue/COIN * diff);
|
||||
coinage = ((uint64_t)kp->nValue * diff);
|
||||
if ( blocktime+iter+segid*2 > prevtime+480 )
|
||||
coinage *= ((blocktime+iter+segid*2) - (prevtime+400));
|
||||
//if ( nHeight >= 2500 && blocktime+iter+segid*2 > prevtime+180 )
|
||||
// coinage *= ((blocktime+iter+segid*2) - (prevtime+60));
|
||||
coinage256 = arith_uint256(coinage+1);
|
||||
hashval = ratio * (kp->hashval / coinage256);
|
||||
//if ( nHeight >= 900 && nHeight < 916 )
|
||||
// hashval = (hashval / coinage256);
|
||||
return(hashval);
|
||||
}
|
||||
|
||||
@@ -5223,7 +5240,7 @@ uint32_t komodo_eligible(arith_uint256 bnTarget,arith_uint256 ratio,struct komod
|
||||
return(blocktime);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else fprintf(stderr,"maxiters is not good enough\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -5250,10 +5267,10 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
if ( (minage= nHeight*3) > 6000 ) // about 100 blocks
|
||||
minage = 6000;
|
||||
komodo_segids(hashbuf,nHeight-101,100);
|
||||
if ( *blocktimep > tipindex->nTime+60 )
|
||||
if ( *blocktimep < tipindex->nTime+60 )
|
||||
*blocktimep = tipindex->nTime+60;
|
||||
//fprintf(stderr,"Start scan of utxo for staking %u ht.%d\n",(uint32_t)time(NULL),nHeight);
|
||||
if ( time(NULL) > lasttime+600 )
|
||||
if ( time(NULL) > lasttime+600 || array == 0 )
|
||||
{
|
||||
if ( array != 0 )
|
||||
{
|
||||
@@ -5272,7 +5289,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
counter++;
|
||||
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
|
||||
{
|
||||
//fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
|
||||
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
|
||||
continue;
|
||||
}
|
||||
CAmount nValue = out.tx->vout[out.i].nValue;
|
||||
@@ -5286,12 +5303,14 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
|
||||
{
|
||||
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
|
||||
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
|
||||
}
|
||||
}
|
||||
}
|
||||
lasttime = (uint32_t)time(NULL);
|
||||
//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp);
|
||||
//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp);
|
||||
}
|
||||
//fprintf(stderr,"numkp.%d blocktime.%u\n",numkp,*blocktimep);
|
||||
block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57;
|
||||
for (i=winners=0; i<numkp; i++)
|
||||
{
|
||||
@@ -5304,7 +5323,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
if ( (eligible2= komodo_eligible(bnTarget,ratio,kp,nHeight,*blocktimep,(uint32_t)tipindex->nTime+27,minage,hashbuf)) == 0 )
|
||||
continue;
|
||||
eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address);
|
||||
//fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible);
|
||||
//fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible);
|
||||
if ( eligible > 0 )
|
||||
{
|
||||
besttime = m = 0;
|
||||
@@ -5317,7 +5336,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
if ( eligible < block_from_future_rejecttime ) // nothing gained by going earlier
|
||||
break;
|
||||
m++;
|
||||
//fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u test prior\n",m,nHeight,*blocktimep,(double)kp->nValue/COIN,eligible);
|
||||
//fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u test prior\n",m,nHeight,*blocktimep,(double)kp->nValue/COIN,eligible);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5327,7 +5346,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
}
|
||||
eligible = besttime;
|
||||
winners++;
|
||||
//fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",nHeight,(int32_t)(eligible - tipindex->nTime),(double)kp->nValue/COIN,eligible);
|
||||
//fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",nHeight,(int32_t)(eligible - tipindex->nTime),(double)kp->nValue/COIN,eligible);
|
||||
if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || kp->nValue < *utxovaluep)) )
|
||||
{
|
||||
earliest = eligible;
|
||||
@@ -5340,7 +5359,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
fprintf(stderr,"ht.%d earliest.%u [%d].%d (%s) nValue %.8f locktime.%u counter.%d winners.%d\n",nHeight,earliest,(int32_t)(earliest - tipindex->nTime),m,kp->address,(double)kp->nValue/COIN,*txtimep,counter,winners);
|
||||
}
|
||||
} //else fprintf(stderr,"utxo not eligible\n");
|
||||
} //else fprintf(stderr,"no tipindex\n");
|
||||
}
|
||||
if ( numkp < 10000 && array != 0 )
|
||||
{
|
||||
free(array);
|
||||
@@ -5375,7 +5394,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
for (i=0; i<siglen; i++)
|
||||
utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
|
||||
//fprintf(stderr," siglen.%d\n",siglen);
|
||||
//fprintf(stderr,"best %u from %u, gap %d lag.%d\n",earliest,*blocktimep,(int32_t)(earliest - *blocktimep),(int32_t)(time(NULL) - *blocktimep));
|
||||
//fprintf(stderr,"best %u from %u, gap %d lag.%d\n",earliest,*blocktimep,(int32_t)(earliest - *blocktimep),(int32_t)(time(NULL) - *blocktimep));
|
||||
*blocktimep = earliest;
|
||||
}
|
||||
} //else fprintf(stderr,"no earliest utxo for staking\n");
|
||||
@@ -5412,6 +5431,7 @@ int32_t ensure_CCrequirements()
|
||||
#include "../cc/CCOracles.h"
|
||||
#include "../cc/CCGateways.h"
|
||||
#include "../cc/CCPrices.h"
|
||||
#include "../cc/CCHeir.h"
|
||||
|
||||
UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector<unsigned char> &pubkey)
|
||||
{
|
||||
@@ -5633,15 +5653,25 @@ UniValue gatewaysaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
UniValue heiraddress(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
|
||||
struct CCcontract_info *cp,C; std::vector<unsigned char> destPubkey;
|
||||
|
||||
cp = CCinit(&C,EVAL_HEIR);
|
||||
if ( fHelp || params.size() > 1 )
|
||||
throw runtime_error("heiraddress [pubkey]\n");
|
||||
if ( fHelp || (params.size() != 4 && params.size() != 3))
|
||||
throw runtime_error("heiraddress func txid amount [destpubkey]\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 *)"Heir",pubkey));
|
||||
//if ( params.size() == 1 )
|
||||
// pubkey = ParseHex(params[0].get_str().c_str());
|
||||
|
||||
char funcid = ((char *)params[0].get_str().c_str())[0];
|
||||
uint256 assetid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
int64_t funds = atof(params[2].get_str().c_str()) * COIN ;
|
||||
if(params.size() == 4)
|
||||
destPubkey = ParseHex(params[3].get_str().c_str());
|
||||
|
||||
//return HeirFundBad(funcid, assetid, funds, destPubkey);
|
||||
|
||||
return(CCaddress(cp,(char *)"Heir",destPubkey));
|
||||
}
|
||||
|
||||
UniValue lottoaddress(const UniValue& params, bool fHelp)
|
||||
@@ -6939,7 +6969,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 + 0.00000000499999;
|
||||
supply = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999; // what for is this '+0.00000000499999'? it will be lost while converting double to int64_t (dimxy)
|
||||
if ( name.size() == 0 || name.size() > 32)
|
||||
{
|
||||
ERR_RESULT("Token name must not be empty and up to 32 characters");
|
||||
@@ -6979,7 +7009,8 @@ UniValue tokentransfer(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
std::vector<unsigned char> pubkey(ParseHex(params[1].get_str().c_str()));
|
||||
amount = atol(params[2].get_str().c_str());
|
||||
//amount = atol(params[2].get_str().c_str());
|
||||
amount = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
if ( tokenid == zeroid )
|
||||
{
|
||||
ERR_RESULT("invalid tokenid");
|
||||
@@ -7015,7 +7046,8 @@ UniValue tokenconvert(const UniValue& params, bool fHelp)
|
||||
evalcode = atoi(params[0].get_str().c_str());
|
||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
std::vector<unsigned char> pubkey(ParseHex(params[2].get_str().c_str()));
|
||||
amount = atol(params[3].get_str().c_str());
|
||||
//amount = atol(params[3].get_str().c_str());
|
||||
amount = atoll(params[3].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
if ( tokenid == zeroid )
|
||||
{
|
||||
ERR_RESULT("invalid tokenid");
|
||||
@@ -7048,7 +7080,8 @@ UniValue tokenbid(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);
|
||||
numtokens = atoi(params[0].get_str().c_str());
|
||||
//numtokens = atoi(params[0].get_str().c_str());
|
||||
numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
price = atof(params[2].get_str().c_str());
|
||||
bidamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||
@@ -7116,7 +7149,8 @@ UniValue tokenfillbid(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
bidtxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
fillamount = atol(params[2].get_str().c_str());
|
||||
// fillamount = atol(params[2].get_str().c_str());
|
||||
fillamount = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
if ( fillamount <= 0 )
|
||||
{
|
||||
ERR_RESULT("fillamount must be positive");
|
||||
@@ -7145,10 +7179,12 @@ UniValue tokenask(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);
|
||||
numtokens = atoi(params[0].get_str().c_str());
|
||||
//numtokens = atoi(params[0].get_str().c_str());
|
||||
numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
price = atof(params[2].get_str().c_str());
|
||||
askamount = (price * numtokens) * COIN + 0.0000000049999;
|
||||
//std::cerr << std::boolalpha << "tokenask(): (tokenid == zeroid) is " << (tokenid == zeroid) << " (numtokens <= 0) is " << (numtokens <= 0) << " (price <= 0) is " << (price <= 0) << " (askamount <= 0) is " << (askamount <= 0) << std::endl;
|
||||
if ( tokenid == zeroid || numtokens <= 0 || price <= 0 || askamount <= 0 )
|
||||
{
|
||||
ERR_RESULT("invalid parameter");
|
||||
@@ -7177,7 +7213,8 @@ UniValue tokenswapask(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);
|
||||
numtokens = atoi(params[0].get_str().c_str());
|
||||
//numtokens = atoi(params[0].get_str().c_str());
|
||||
numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
tokenid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
otherid = Parseuint256((char *)params[2].get_str().c_str());
|
||||
price = atof(params[3].get_str().c_str());
|
||||
@@ -7231,7 +7268,8 @@ UniValue tokenfillask(const UniValue& params, bool fHelp)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
asktxid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
fillunits = atol(params[2].get_str().c_str());
|
||||
//fillunits = atol(params[2].get_str().c_str());
|
||||
fillunits = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
if ( fillunits <= 0 )
|
||||
{
|
||||
ERR_RESULT("fillunits must be positive");
|
||||
@@ -7271,7 +7309,8 @@ UniValue tokenfillswap(const UniValue& params, bool fHelp)
|
||||
tokenid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
otherid = Parseuint256((char *)params[1].get_str().c_str());
|
||||
asktxid = Parseuint256((char *)params[2].get_str().c_str());
|
||||
fillunits = atol(params[3].get_str().c_str());
|
||||
//fillunits = atol(params[3].get_str().c_str());
|
||||
fillunits = atoll(params[3].get_str().c_str()); // dimxy changed to prevent loss of significance
|
||||
hex = FillSell(0,tokenid,otherid,asktxid,fillunits);
|
||||
if (fillunits > 0) {
|
||||
if ( hex.size() > 0 ) {
|
||||
|
||||
@@ -3615,7 +3615,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
||||
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
|
||||
}
|
||||
|
||||
/*
|
||||
// Discourage fee sniping.
|
||||
//
|
||||
// However because of a off-by-one-error in previous versions we need to
|
||||
@@ -3636,7 +3636,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
|
||||
|
||||
assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
|
||||
assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
|
||||
assert(txNew.nLockTime < LOCKTIME_THRESHOLD);*/
|
||||
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
@@ -4960,10 +4960,10 @@ void CWallet::GetFilteredNotes(
|
||||
}
|
||||
|
||||
// skip locked notes
|
||||
// TODO: Add locking for Sapling notes
|
||||
// if (ignoreLocked && IsLockedNote(op)) {
|
||||
// continue;
|
||||
// }
|
||||
// TODO: Add locking for Sapling notes -> done
|
||||
if (ignoreLocked && IsLockedNote(op)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto note = notePt.note(nd.ivk).get();
|
||||
saplingEntries.push_back(SaplingNoteEntry {
|
||||
|
||||
@@ -46,7 +46,7 @@ extern bool fSendFreeTransactions;
|
||||
extern bool fPayAtLeastCustomFee;
|
||||
|
||||
//! -paytxfee default
|
||||
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
||||
static const CAmount DEFAULT_TRANSACTION_FEE = 10000;
|
||||
//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB
|
||||
static const CAmount nHighTransactionFeeWarning = 0.01 * COIN;
|
||||
//! -maxtxfee default
|
||||
|
||||
Reference in New Issue
Block a user