Browse Source

Compiler errors

z_createrawtransaction
jl777 5 years ago
parent
commit
3155223e51
  1. 22
      src/cc/CCPrices.h
  2. 72
      src/cc/payments.cpp
  3. 749
      src/cc/prices.cpp
  4. 1
      src/komodo_defs.h
  5. 117
      src/komodo_gateway.h
  6. 69
      src/rpc/blockchain.cpp
  7. 109
      src/txdb.cpp

22
src/cc/CCPrices.h

@ -18,17 +18,27 @@
#define CC_PRICES_H
#include "CCinclude.h"
int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind,int32_t daywindow);
#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1)
#define PRICES_TXFEE 10000
#define PRICES_SMOOTHWIDTH 1
#define KOMODO_MAXPRICES 2048 // must be power of 2 and less than 8192
#define KOMODO_PRICEMASK (~(KOMODO_MAXPRICES - 1))
#define PRICES_WEIGHT (KOMODO_MAXPRICES * 1)
#define PRICES_MUL (KOMODO_MAXPRICES * 2)
#define PRICES_DIV (KOMODO_MAXPRICES * 3)
#define PRICES_INV (KOMODO_MAXPRICES * 4)
#define PRICES_MDD (KOMODO_MAXPRICES * 5)
#define PRICES_MMD (KOMODO_MAXPRICES * 6)
#define PRICES_MMM (KOMODO_MAXPRICES * 7)
#define PRICES_DDD (KOMODO_MAXPRICES * 8)
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
// CCcustom
UniValue PricesList();
UniValue PricesInfo(uint256 fundingtxid);
UniValue PricesStatus(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid);
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);
std::string PricesAddFunding(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,int64_t amount);
std::string PricesBet(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,int64_t amount,int32_t leverage);
std::string PricesFinish(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,uint256 bettxid);
UniValue PricesBet(uint64_t txfee,int64_t amount,int32_t leverage,std::string synthetic);
#endif

72
src/cc/payments.cpp

@ -732,6 +732,78 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr)
return(result);
}
UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr)
{
// need to code: exclude list of tokenid, dust threshold, maxpayees, excluded pubkeys[]
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::vector<uint256> txidoprets; uint256 hashBlock; int32_t i,n,numoprets=0,lockedblocks,minrelease; std::string rawtx; int64_t totalallocations = 0;
cJSON *params = payments_reparse(&n,jsonstr);
if ( params != 0 && n >= 4 )
{
lockedblocks = juint(jitem(params,0),0);
minrelease = juint(jitem(params,1),0);
if ( lockedblocks < 0 || minrelease < 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","negative parameter"));
if ( params != 0 )
free_json(params);
return(result);
}
for (i=0; i<n-2; i++)
txidoprets.push_back(payments_juint256(jitem(params,2+i)));
for (i=0; i<txidoprets.size(); i++)
{
std::vector<uint8_t> scriptPubKey,opret; int64_t allocation;
if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
{
totalallocations += allocation;
if ( opret.size() > 0 )
numoprets++;
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid txidopret"));
result.push_back(Pair("txid",txidoprets[i].GetHex()));
result.push_back(Pair("txi",(int64_t)i));
if ( params != 0 )
free_json(params);
return(result);
}
}
if ( numoprets > 1 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","too many opreturns"));
result.push_back(Pair("numoprets",(int64_t)numoprets));
if ( params != 0 )
free_json(params);
return(result);
}
mypk = pubkey2pk(Mypubkey());
Paymentspk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 )
{
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsOpRet(lockedblocks,minrelease,totalallocations,txidoprets));
if ( params != 0 )
free_json(params);
return(payments_rawtxresult(result,rawtx,1));
}
result.push_back(Pair("result","error"));
result.push_back(Pair("error","not enough normal funds"));
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","parameters error"));
}
if ( params != 0 )
free_json(params);
return(result);
}
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease; std::vector<uint256> txidoprets; int64_t funds,fundsopret,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock;

749
src/cc/prices.cpp

@ -17,123 +17,115 @@
#include "CCPrices.h"
/*
Prices CC would best build on top of the oracles CC, ie. to combine payments for multiple oracles and to calculate a 51% protected price feed.
CBOPRET creates trustless oracles, which can be used for making a synthetic cash settlement system based on real world prices;
We need to assume there is an oracle for a specific price. In the event there are more than one provider, the majority need to be within correlation distance to update a pricepoint.
int64_t OraclePrice(int32_t height,uint256 reforacletxid,char *markeraddr,char *format);
Using the above function, a consensus price can be obtained for a datasource.
given an oracletxid, the marketaddr and format can be extracted to be used for future calls to OraclePrice. This allows to set a starting price and that in turn allows cash settled leveraged trading!
Funds work like with dice, ie. there is a Prices plan that traders bet against.
PricesFunding oracletxid, margin, priceaveraging, maxleverage, funding, longtoken, shorttoken, N [pubkeys]
0.5% fee based on betamount, NOT leveraged betamount!!
0.1% collected by price basis determinant
0.2% collected by rekt tx
PricesBet -> oracletxid start with 'L', leverage, funding, direction
funds are locked into global CC address
it can be closed at anytime by the trader for cash settlement
the house account can close it if rekt
PricesBet -> +/-leverage, amount, synthetic -> opreturn includes current price
funds are locked into 1of2 global CC address
for first day, long basis is MAX(correlated,smoothed), short is MIN()
reference price is the smoothed of the previous block
if synthetic value + amount goes negative, then anybody can rekt it to collect a rektfee, proof of rekt must be included to show cost basis, rekt price
original creator can liquidate at anytime and collect (synthetic value + amount) from globalfund
0.5% of bet -> globalfund
PricesStatus -> bettxid maxsamples returns initial params, cost basis, amount left, rekt:true/false, rektheight, initial synthetic price, current synthetic price, net gain
Implementation Notes:
In order to eliminate the need for worrying about sybil attacks, each prices plan would be able to specific pubkey(s?) for whitelisted publishers. It would be possible to have a non-whitelisted plan that would use 50% correlation between publishers.
PricesRekt -> bettxid height -> 0.1% to miner, rest to global CC
delta neutral balancing of riskexposure: fabs(long exposure - short exposure)
bet +B at leverage L
absval(sum(+BLi) - sum(-Bli))
PricesClose -> bettxid returns (synthetic value + amount)
validate: update riskexposure and it needs to be <= funds
PricesList -> all bettxid -> list [bettxid, netgain]
PricesProfits: limit withdraw to funds in excess of riskexposure
PricesFinish: payout (if winning) and update riskexposure
need long/short exposure assets
funding -> 1of2 CC global CC address and dealer address, exposure tokens to global 1of2 assets CC address
pricebet -> user funds and exposure token to 1of2 address.
pricewin -> winnings from dealer funds, exposure token back to global address
priceloss -> exposuretoken back to global address
exposure address, funds address
*/
// start of consensus code
int64_t PricesOraclePrice(int64_t &rektprice,uint64_t mode,uint256 oracletxid,std::vector<CPubKey>pubkeys,int32_t dir,int64_t amount,int32_t leverage)
CScript prices_betopret(CPubKey mypk,int32_t height,int64_t amount,int16_t leverage,int64_t firstprice,std::vector<uint16_t> vec,uint256 tokenid)
{
CScript opret;
opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'B' << mypk << height << amount << leverage << firstprice << vec << tokenid);
return(opret);
}
uint8_t prices_betopretdecode(CScript scriptPubKey,CPubKey &pk,int32_t &height,int64_t &amount,int16_t &leverage,int64_t &firstprice,std::vector<uint16_t> &vec,uint256 &tokenid)
{
int64_t price;
// howto ensure price when block it confirms it not known
// get price from oracle + current chaintip
// normalize leveraged amount
if ( dir > 0 )
rektprice = price * leverage / (leverage-1);
else rektprice = price * (leverage-1) / leverage;
return(price);
std::vector<uint8_t> vopret; uint8_t e,f;
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk; ss >> height; ss >> amount; ss >> leverage; ss >> firstprice; ss >> vec; ss >> tokenid) != 0 && e == EVAL_PRICES && f == 'B' )
{
return(f);
}
return(0);
}
CScript EncodePricesFundingOpRet(uint8_t funcid,CPubKey planpk,uint256 oracletxid,uint256 longtoken,uint256 shorttoken,int32_t millimargin,uint64_t mode,int32_t maxleverage,std::vector<CPubKey> pubkeys,uint256 bettoken)
CScript prices_addopret(uint256 bettxid,CPubKey mypk,int64_t amount)
{
CScript opret;
fprintf(stderr,"implement EncodePricesFundingOpRet\n");
opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'A' << bettxid << mypk << amount);
return(opret);
}
uint8_t DecodePricesFundingOpRet(CScript scriptPubKey,CPubKey &planpk,uint256 &oracletxid,uint256 &longtoken,uint256 &shorttoken,int32_t &millimargin,uint64_t &mode,int32_t &maxleverage,std::vector<CPubKey> &pubkeys,uint256 &bettoken)
uint8_t prices_addopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int64_t &amount)
{
fprintf(stderr,"implement DecodePricesFundingOpRet\n");
std::vector<uint8_t> vopret; uint8_t e,f;
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bettxid; ss >> pk; ss >> amount) != 0 && e == EVAL_PRICES && f == 'A' )
{
return(f);
}
return(0);
}
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
CScript prices_costbasisopret(uint256 bettxid,CPubKey mypk,int32_t height,int64_t costbasis)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
CScript opret;
opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'C' << bettxid << mypk << height << costbasis);
return(opret);
}
return true; // TODO remove, for test dual-evals
uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int32_t &height,int64_t &costbasis)
{
std::vector<uint8_t> vopret; uint8_t e,f;
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bettxid; ss >> pk; ss >> height; ss >> costbasis) != 0 && e == EVAL_PRICES && f == 'C' )
{
return(f);
}
return(0);
}
return eval->Invalid("no validation yet");
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
CScript prices_finalopret(uint256 bettxid,int64_t profits,int32_t height,CPubKey mypk,int64_t firstprice,int64_t costbasis,int64_t addedbets,int64_t positionsize,int16_t leverage)
{
CScript opret;
opret << OP_RETURN << E_MARSHAL(ss << EVAL_PRICES << 'F' << bettxid << profits << height << mypk << firstprice << costbasis << addedbets << positionsize << leverage);
return(opret);
}
uint8_t prices_finalopretdecode(CScript scriptPubKey,uint256 &bettxid,int64_t &profits,int32_t &height,CPubKey &pk,int64_t &firstprice,int64_t &costbasis,int64_t &addedbets,int64_t &positionsize,int16_t &leverage)
{
std::vector<uint8_t> vopret; uint8_t e,f;
GetOpReturnData(scriptPubKey,vopret);
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> bettxid; ss >> profits; ss >> height; ss >> pk; ss >> firstprice; ss >> costbasis; ss >> addedbets; ss >> positionsize; ss >> leverage) != 0 && e == EVAL_PRICES && f == 'F' )
{
for (i=0; i<numvins; i++)
{
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
{
return eval->Invalid("illegal normal vini");
}
}
//fprintf(stderr,"check amounts\n");
//if ( PricesExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"Pricesget invalid amount\n");
return false;
}
//else
{
txid = tx.GetHash();
memcpy(hash,&txid,sizeof(hash));
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"Pricesget validated\n");
else fprintf(stderr,"Pricesget invalid\n");
return(retval);
}
return(f);
}
return(0);
}
bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
{
return true;
}
// end of consensus code
// helper functions for rpc calls in rpcwallet.cpp
int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,uint256 tolenid,int64_t total,int32_t maxinputs)
int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,int64_t total,int32_t maxinputs,uint256 vintxid,int32_t vinvout)
{
// add threshold check
int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,destaddr);
@ -141,11 +133,11 @@ int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
// need to prevent dup
if ( vout == vinvout && txid == vintxid )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && vout < vintx.vout.size() )
{
// need to verify assetid
if ( (nValue= vintx.vout[vout].nValue) >= 10000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
if ( (nValue= vintx.vout[vout].nValue) >= total/maxinputs && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
@ -162,7 +154,7 @@ int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char
UniValue PricesList()
{
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; uint64_t mode; int32_t margin,maxleverage; std::vector<CPubKey>pubkeys; uint256 txid,hashBlock,oracletxid,longtoken,shorttoken,bettoken; CPubKey planpk,pricespk; char str[65]; CTransaction vintx;
UniValue result(UniValue::VARR); std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; struct CCcontract_info *cp,C; int64_t amount,firstprice; int32_t height; int16_t leverage; uint256 txid,hashBlock; CPubKey pk,pricespk; std::vector<uint16_t> vec; CTransaction vintx;
cp = CCinit(&C,EVAL_PRICES);
pricespk = GetUnspendable(cp,0);
SetCCtxids(addressIndex,cp->normaladdr);
@ -171,7 +163,7 @@ UniValue PricesList()
txid = it->first.txhash;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' )
if ( vintx.vout.size() > 0 && prices_betopretdecode(vintx.vout[vintx.vout.size()-1].scriptPubKey,pk,height,amount,leverage,firstprice,vec) == 'B' )
{
result.push_back(uint256_str(str,txid));
}
@ -180,274 +172,455 @@ UniValue PricesList()
return(result);
}
// longtoken satoshis limits long exposure
// shorttoken satoshis limits short exposure
// both must be in the 1of2 CC address with its total supply
// 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)
UniValue prices_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag)
{
CTransaction tx;
if ( rawtx.size() > 0 )
{
result.push_back(Pair("hex",rawtx));
if ( DecodeHexTx(tx,rawtx) != 0 )
{
if ( broadcastflag != 0 && myAddtomempool(tx) != 0 )
RelayTransaction(tx);
result.push_back(Pair("txid",tx.GetHash().ToString()));
result.push_back(Pair("result","success"));
} else result.push_back(Pair("error","decode hex"));
} else result.push_back(Pair("error","couldnt finalize CCtx"));
return(result);
}
int32_t prices_syntheticvec(std::vector<uint16_t> &vec,std::vector<std::string> synthetic)
{
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 )
int32_t i,need,depth = 0; std::string opstr; uint16_t opcode,weight;
if ( synthetic.size() == 0 )
return(-1);
for (i=0; i<synthetic.size(); i++)
{
CCerror = "invalid parameter error";
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
need = 0;
opstr = synthetic[i];
if ( opstr == "*" )
opcode = PRICES_MULT, need = 2;
else if ( opstr == "/" )
opcode = PRICES_DIV, need = 2;
else if ( opstr == "!" )
opcode = PRICES_INV, need = 1;
else if ( opstr == "**/" )
opcode = PRICES_MMD, need = 3;
else if ( opstr == "*//" )
opcode = PRICES_MDD, need = 3;
else if ( opstr == "***" )
opcode = PRICES_MMM, need = 3;
else if ( opstr == "///" )
opcode = PRICES_DDD, need = 3;
else if ( (ind= prices_ind(opstr.c_str())) >= 0 )
opcode = ind, need = 0;
else if ( (weight= atoi(opstr.c_str())) > 0 && weight < KOMODO_MAXPRICES )
{
opcode = PRICES_WEIGHT | weight;
need = 1;
} else return(-2);
if ( depth < need )
return(-3);
depth -= need;
if ( (opcode & KOMODO_PRICEMASK) != PRICES_WEIGHT ) // weight
depth++;
if ( depth > 3 )
return(-4);
vec.push_back(opcode);
}
cp = CCinit(&C,EVAL_PRICES);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
if ( (N= (int32_t)pubkeys.size()) || N > 15 )
if ( depth != 0 )
{
fprintf(stderr,"too many pubkeys N.%d\n",N);
return("");
fprintf(stderr,"depth.%d not empty\n",depth);
return(-5);
}
for (i=0; i<N; i++)
return(0);
}
int64_t prices_syntheticprice(std::vector<uint16_t> vec,int32_t height,int32_t minmax,int16_t leverage)
{
int32_t i,errcode,depth,retval = -1; uint16_t opcode; int64_t *pricedata,stack[4],price,den,a,b,c;
pricedata = (int64_t *)calloc(sizeof(*pricedata)*3,numblocks + PRICES_DAYWINDOW*2 + PRICES_SMOOTHWIDTH);
price = den = depth = errcode = 0;
for (i=0; i<vec.size(); i++)
{
Getscriptaddress(coinaddr,CScript() << ParseHex(HexStr(pubkeys[i])) << OP_CHECKSIG);
if ( CCaddress_balance(coinaddr) == 0 )
opcode = vec[i];
ind = (opcode & (KOMODO_MAXPRICES-1));
switch ( opcode & KOMODO_PRICEMASK )
{
fprintf(stderr,"N.%d but pubkeys[%d] has no balance\n",N,i);
return("");
case 0:
pricestack[depth] = 0;
if ( prices_extract(pricedata,height,1,ind) == 0 )
{
if ( minmax == 0 )
pricestack[depth] = pricedata[2];
else
{
if ( leverage > 0 )
pricestack[depth] = MAX(pricedata[1],pricedata[2]);
else pricestack[depth] = MIN(pricedata[1],pricedata[2]);
}
}
if ( pricestack[depth] == 0 )
errcode = -1;
depth++;
break;
case PRICES_WEIGHT: // multiply by weight and consume top of stack by updating price
if ( depth == 1 )
{
depth--;
price += pricestack[0] * ind;
den += ind;
} else errcode = -2;
break;
case PRICES_MUL:
if ( depth >= 2 )
{
b = pricestack[--depth];
a = pricestack[--depth];
pricestack[depth++] = (a * b) / SATOSHIDEN;
} else errcode = -3;
break;
case PRICES_DIV:
if ( depth >= 2 )
{
b = pricestack[--depth];
a = pricestack[--depth];
pricestack[depth++] = (a * SATOSHIDEN) / b;
} else errcode = -4;
break;
case PRICES_INV:
if ( depth >= 1 )
{
a = pricestack[--depth];
pricestack[depth++] = (SATOSHIDEN * SATOSHIDEN) / a;
} else errcode = -5;
break;
case PRICES_MDD:
if ( depth >= 3 )
{
c = pricestack[--depth];
b = pricestack[--depth];
a = pricestack[--depth];
pricestack[depth++] = (((a * SATOSHIDEN) / b) * SATOSHIDEN) / c;
} else errcode = -6;
break;
case PRICES_MMD:
if ( depth >= 3 )
{
c = pricestack[--depth];
b = pricestack[--depth];
a = pricestack[--depth];
pricestack[depth++] = (a * b) / c;
} else errcode = -7;
break;
case PRICES_MMM:
if ( depth >= 3 )
{
c = pricestack[--depth];
b = pricestack[--depth];
a = pricestack[--depth];
pricestack[depth++] = ((a * b) / SATOSHIDEN) * c;
} else errcode = -8;
break;
case PRICES_DDD:
if ( depth >= 3 )
{
c = pricestack[--depth];
b = pricestack[--depth];
a = pricestack[--depth];
pricestack[depth++] = (((((SATOSHIDEN * SATOSHIDEN) / a) * SATOSHIDEN) / b) * SATOSHIDEN) / c;
} else errcode = -9;
break;
default:
errcode = -10;
break;
}
if ( errcode != 0 )
break;
}
if ( GetCCaddress1of2(cp,houseaddr,pricespk,mypk) == 0 )
{
fprintf(stderr,"PricesCreateFunding cant create globaladdr\n");
return("");
}
if ( CCtoken_balance(houseaddr,longtoken) != CCfullsupply(longtoken) )
free(pricedata);
if ( den == 0 )
return(-11);
else if ( depth != 0 )
return(-12);
else if ( errcode != 0 )
return(errcode);
return(price / den);
}
int64_t prices_syntheticprofits(int64_t &costbasis,int32_t firstheight,int32_t height,int16_t leverage,std::vector<uint16_t> vec,int64_t positionsize,int64_t addedbets)
{
int64_t price,profits = 0; int32_t minmax;
minmax = (height > firstheight+PRICES_DAYWINDOW);
if ( (price= prices_syntheticprice(vec,height,minmax)) < 0 )
{
fprintf(stderr,"PricesCreateFunding (%s) globaladdr.%s token balance %.8f != %.8f\n",uint256_str(str,longtoken),houseaddr,(double)CCtoken_balance(houseaddr,longtoken)/COIN,(double)CCfullsupply(longtoken)/COIN);
return("");
fprintf(stderr,"unexpected zero synthetic price at height.%d\n",height);
return(0);
}
if ( CCtoken_balance(houseaddr,shorttoken) != CCfullsupply(shorttoken) )
if ( minmax != 0 )
{
fprintf(stderr,"PricesCreateFunding (%s) globaladdr.%s token balance %.8f != %.8f\n",uint256_str(str,longtoken),houseaddr,(double)CCtoken_balance(houseaddr,longtoken)/COIN,(double)CCfullsupply(shorttoken)/COIN);
return("");
if ( leverage > 0 && price > costbasis )
costbasis = price;
else if ( leverage < 0 && (costbasis == 0 || price < costbasis) )
costbasis = price;
}
if ( GetTransaction(oracletxid,oracletx,hashBlock,false) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
profits = ((price * SATOSHIDEN) / costbasis) - SATOSHIDEN;
profits *= leverage * positionsize;
return(positionsize + addedbets + profits)
}
void prices_betjson(UniValue &result,int64_t profits,int64_t costbasis,int64_t positionsize,int64_t addedbets,int16_t leverage,int32_t firstheight,int64_t firstprice)
{
result.push_back(Pair("profits",ValueFromAmount(profits)));
result.push_back(Pair("costbasis",ValueFromAmount(costbasis)));
result.push_back(Pair("positionsize",ValueFromAmount(positionsize)));
result.push_back(Pair("addedbets",ValueFromAmount(addedbets)));
result.push_back(Pair("leverage",(int64_t)leverage));
result.push_back(Pair("firstheight",(int64_t)firstheight));
result.push_back(Pair("firstprice",ValueFromAmount(firstprice)));
}
int64_t prices_costbasis(CTransaction bettx)
{
int64_t costbasis = 0;
// if vout1 is spent, follow and extract costbasis from opreturn
//uint8_t prices_costbasisopretdecode(CScript scriptPubKey,uint256 &bettxid,CPubKey &pk,int32_t &height,int64_t &costbasis)
return(costbasis);
}
int64_t prices_batontxid(uint256 &batontxid,CTransaction bettx,uint256 bettxid);
{
int64_t addedbets = 0;
// iterate through batons, adding up vout1 -> addedbets
return(addedbets);
}
UniValue PricesBet(uint64_t txfee,int64_t amount,int16_t leverage,std::vector<std::string> synthetic)
{
int32_t nextheight = komodo_nextheight();
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ);
struct CCcontract_info *cp,C; CPubKey pricespk,mypk; int64_t betamount,firstprice; std::vector<uint16_t> vec;
if ( leverage > PRICES_MAXLEVERAGE || leverage < -PRICES_MAXLEVERAGE )
{
fprintf(stderr,"cant find oracletxid %s\n",uint256_str(str,oracletxid));
return("");
result.push_back(Pair("result","error"));
result.push_back(Pair("error","leverage too big"));
return(result);
}
fprintf(stderr,"error check bettoken\n");
if ( AddNormalinputs(mtx,mypk,3*txfee,4) > 0 )
cp = CCinit(&C,EVAL_PRICES);
if ( txfee == 0 )
txfee = PRICES_TXFEE;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
GetCCaddress(cp,myaddr,mypk);
if ( prices_syntheticvec(vec,synthetic) < 0 || (firstprice= prices_syntheticprice(vec,nextheight-1,1)) < 0 || vec.size() == 0 || vec.size() > 4096 )
{
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesFundingOpRet('F',mypk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken)));
result.push_back(Pair("result","error"));
result.push_back(Pair("error","invalid synthetic"));
return(result);
}
else
if ( AddNormalinputs(mtx,mypk,amount+4*txfee,64) >= amount+4*txfee )
{
CCerror = "cant find enough inputs";
fprintf(stderr,"%s\n", CCerror.c_str() );
betamount = (amount * 199) / 200;
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding
mtx.vout.push_back(MakeCC1vout(cp->evalcode,(amount-betamount)+2*txfee,pricespk));
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,betamount,pricespk,mypk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_betopret(mypk,nextheight-1,amount,leverage,firstprice,vec,zeroid));
return(prices_rawtxresult(result,rawtx,0));
}
return("");
result.push_back(Pair("result","error"));
result.push_back(Pair("error","not enough funds"));
return(result);
}
UniValue PricesInfo(uint256 fundingtxid)
UniValue PricesAddFunding(uint64_t txfee,uint256 bettxid,int64_t amount)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); CPubKey pricespk,planpk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction vintx; int64_t balance,supply,exposure; uint64_t funding,mode; int32_t i,margin,maxleverage; char numstr[65],houseaddr[64],exposureaddr[64],str[65]; std::vector<CPubKey>pubkeys; struct CCcontract_info *cp,C;
int32_t nextheight = komodo_nextheight();
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ);
struct CCcontract_info *cp,C; CPubKey pricespk,mypk; int64_t addedbets=0,betamount,firstprice; std::vector<uint16_t> vec; uint256 batonttxid;
cp = CCinit(&C,EVAL_PRICES);
if ( txfee == 0 )
txfee = PRICES_TXFEE;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
if ( GetTransaction(fundingtxid,vintx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
ERR_RESULT("cant find fundingtxid");
return(result);
}
if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' )
GetCCaddress(cp,myaddr,mypk);
if ( AddNormalinputs(mtx,mypk,amount+txfee,64) >= amount+txfee )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("fundingtxid",uint256_str(str,fundingtxid)));
result.push_back(Pair("bettoken",uint256_str(str,bettoken)));
result.push_back(Pair("oracletxid",uint256_str(str,oracletxid)));
sprintf(numstr,"%.3f",(double)margin/1000);
result.push_back(Pair("profitmargin",numstr));
result.push_back(Pair("maxleverage",maxleverage));
result.push_back(Pair("mode",(int64_t)mode));
for (i=0; i<pubkeys.size(); i++)
a.push_back(pubkey33_str(str,(uint8_t *)&pubkeys[i]));
result.push_back(Pair("pubkeys",a));
GetCCaddress1of2(cp,houseaddr,pricespk,planpk);
GetCCaddress1of2(cp,exposureaddr,pricespk,pricespk); // assets addr
result.push_back(Pair("houseaddr",houseaddr));
result.push_back(Pair("betaddr",exposureaddr));
result.push_back(Pair("longtoken",uint256_str(str,longtoken)));
supply = CCfullsupply(longtoken);
result.push_back(Pair("longsupply",supply));
balance = CCtoken_balance(houseaddr,longtoken);
result.push_back(Pair("longavail",balance));
exposure = CCtoken_balance(exposureaddr,longtoken);
result.push_back(Pair("longexposure",exposure));
result.push_back(Pair("shorttoken",uint256_str(str,shorttoken)));
supply = CCfullsupply(shorttoken);
result.push_back(Pair("shortsupply",supply));
balance = CCtoken_balance(houseaddr,shorttoken);
result.push_back(Pair("shortavail",balance));
exposure = CCtoken_balance(exposureaddr,shorttoken);
result.push_back(Pair("shortexposure",exposure));
sprintf(numstr,"%.8f",(double)CCtoken_balance(houseaddr,bettoken)/COIN);
result.push_back(Pair("funds",numstr));
if ( prices_batontxid(addedbets,batontxid,bettxid) >= 0 )
{
mtx.vin.push_back(CTxVin(batontxid,0,CScript()));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk)); // baton for total funding
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pricespk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_addopret(bettxid,mypk,amount));
return(prices_rawtxresult(result,rawtx,0));
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt find batonttxid"));
return(result);
}
}
result.push_back(Pair("result","error"));
result.push_back(Pair("error","not enough funds"));
return(result);
}
std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount)
UniValue PricesSetcostbasis(uint64_t txfee,uint256 bettxid)
{
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";
fprintf(stderr,"%s\n", CCerror.c_str() );
return("");
}
int32_t nextheight = komodo_nextheight();
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ);
struct CCcontract_info *cp,C; CTransaction bettx; uint256 hashBlock; int64_t myfee,positionsize=0,addedbets,firstprice=0,profits=0,costbasis=0; int32_t i,firstheight=0,height,numvouts; int16_t leverage=0; std::vector<uint16_t> vec; CPubKey pk,mypk,pricespk; std::string rawtx;
cp = CCinit(&C,EVAL_PRICES);
if ( txfee == 0 )
txfee = 10000;
txfee = PRICES_TXFEE;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
GetCCaddress(cp,myaddr,mypk);
if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 )
if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 )
{
fprintf(stderr,"cant find fundingtxid\n");
return("");
if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec) == 'B' )
{
addedbets = prices_addedbets(bettx);
mtx.vin.push_back(CTxVin(bettx,1,CScript()));
for (i=0; i<PRICES_DAYWINDOW; i++)
{
if ( (profits= prices_syntheticprofits(&costbasis,firstheight,firstheight+i,leverage,vec,positionsize,addedbets)) < 0 )
{
result.push_back(Pair("rekt",(int64_t)1));
result.push_back(Pair("rektheight",(int64_t)firstheight+i));
break;
}
}
if ( i == PRICES_DAYWINDOW )
result.push_back(Pair("rekt",0));
prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice);
myfee = bettx.vout[1].nValue / 10;
result.push_back(Pair("myfee",myfee));
mtx.vout.push_back(CTxOut(myfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,bettx.vout[1].nValue-myfee-txfee,pricespk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_costbasisopret(bettxid,mypk,firstheight+PRICES_DAYWINDOW-1,costbasis));
return(prices_rawtxresult(result,rawtx,0));
}
}
if ( tx.vout.size() > 0 && DecodePricesFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' && bettoken == refbettoken )
result.push_back(Pair("result","error"));
result.push_back(Pair("error","cant find bettxid"));
return(result);
}
UniValue PricesRekt(uint64_t txfee,uint256 bettxid,int32_t rektheight)
{
int32_t nextheight = komodo_nextheight();
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ);
struct CCcontract_info *cp,C; CTransaction bettx; uint256 hashBlock,tokenid; int64_t myfee=0,positionsize,addedbets,firstprice,profits,costbasis=0; int32_t firstheight,numvouts; int16_t leverage; std::vector<uint16_t> vec; CPubKey pk,mypk,pricespk; std::string rawtx;
cp = CCinit(&C,EVAL_PRICES);
if ( txfee == 0 )
txfee = PRICES_TXFEE;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 )
{
GetCCaddress1of2(cp,houseaddr,pricespk,planpk);
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' )
{
if ( (inputs= AddTokensInputs(cp,mtx,myaddr,bettoken,amount,60)) >= amount )
costbasis = prices_costbasis(bettx);
addedbets = prices_batontxid(batontxid,bettx,bettxid);
if ( (profits= prices_syntheticprofits(&ignore,firstheight,rektheight,leverage,vec,positionsize,addedbets)) < 0 )
{
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,amount,pricespk,planpk));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(planpk)) << OP_CHECKSIG));
if ( inputs > amount+txfee )
CCchange = (inputs - amount);
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,mypk));
// add addr2
std::vector<CPubKey> voutTokenPubkeysEmpty; //TODO: add token vout pubkeys
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,
EncodeTokenOpRet(bettoken, voutTokenPubkeysEmpty,
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('t',/*bettoken,*/zeroid, 0, Mypubkey())))));
myfee = (positionsize + addedbets) / 500;
}
prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice);
if ( myfee != 0 )
{
mtx.vin.push_back(CTxVin(bettxid,2,CScript()));
mtx.vout.push_back(CTxOut(myfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,bettx.vout[2].nValue-myfee-txfee,pricespk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_finalopret(bettxid,profits,rektheight,mypk,firstprice,costbasis,addedbets,positionsize,leverage));
return(prices_rawtxresult(result,rawtx,0));
}
else
{
CCerror = "cant find enough bet inputs";
fprintf(stderr,"%s\n", CCerror.c_str() );
result.push_back(Pair("result","error"));
result.push_back(Pair("error","position not rekt"));
return(result);
}
}
else
{
CCerror = "cant find enough inputs";
fprintf(stderr,"%s\n", CCerror.c_str() );
result.push_back(Pair("result","error"));
result.push_back(Pair("error","cant decode opret"));
return(result);
}
}
return("");
result.push_back(Pair("result","error"));
result.push_back(Pair("error","cant find bettxid"));
return(result);
}
std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount,int32_t leverage)
UniValue PricesCashout(uint64_t txfee,uint256 bettxid)
{
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;
dir = -1;
} else dir = 1;
int32_t nextheight = komodo_nextheight();
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ);
struct CCcontract_info *cp,C; char destaddr[64]; CTransaction bettx; uint256 hashBlock,tokenid; int64_t CCchange=0,positionsize,addedbets,firstprice,profits,costbasis=0; int32_t i,firstheight,height,numvouts; int16_t leverage; std::vector<uint16_t> vec; CPubKey pk,mypk,pricespk; std::string rawtx;
cp = CCinit(&C,EVAL_PRICES);
if ( txfee == 0 )
txfee = 10000;
txfee = PRICES_TXFEE;
mypk = pubkey2pk(Mypubkey());
pricespk = GetUnspendable(cp,0);
GetCCaddress(cp,myaddr,mypk);
if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 )
{
fprintf(stderr,"cant find fundingtxid\n");
return("");
}
if ( tx.vout.size() > 0 && DecodePricesFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' && bettoken == refbettoken )
GetCCaddress(cp,destaddr,pricespk);
if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 )
{
if ( leverage > maxleverage || leverage < 1 )
{
fprintf(stderr,"illegal leverage\n");
return("");
}
GetCCaddress1of2(cp,houseaddr,pricespk,planpk);
GetCCaddress1of2(cp,exposureaddr,pricespk,pricespk);
if ( dir < 0 )
tokenid = shorttoken;
else tokenid = longtoken;
exposure = leverage * amount;
longexposure = CCtoken_balance(exposureaddr,longtoken);
shortexposure = CCtoken_balance(exposureaddr,shorttoken);
netexposure = (longexposure - shortexposure + exposure*dir);
if ( netexposure < 0 )
netexposure = -netexposure;
balance = CCtoken_balance(myaddr,bettoken) / COIN;
if ( balance < netexposure*9/10 ) // 10% extra room for dynamically closed bets in wrong direction
{
fprintf(stderr,"balance %lld < 90%% netexposure %lld, refuse bet\n",(long long)balance,(long long)netexposure);
return("");
}
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' )
{
if ( (inputs= AddTokensInputs(cp,mtx,houseaddr,tokenid,exposure,30)) >= exposure )
{
if ( (inputs2= AddTokensInputs(cp,mtx,myaddr,bettoken,amount,30)) >= amount )
{
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,amount,pricespk,planpk));
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,exposure,pricespk,pricespk));
if ( inputs > exposure+txfee )
CCchange = (inputs - exposure);
if ( inputs2 > amount+txfee )
CCchange2 = (inputs2 - amount);
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,CCchange,pricespk,planpk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange2,mypk));
// add addr2 and addr3
//return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesExtra('T',tokenid,bettoken,zeroid,dir*leverage)));
CScript opret;
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
else
{
fprintf(stderr,"cant find enough bettoken inputs\n");
return("");
}
}
else
costbasis = prices_costbasis(bettx);
addedbets = prices_batontxid(batontxid,bettx,bettxid);
if ( (profits= prices_syntheticprofits(&ignore,firstheight,nextheight-1,leverage,vec,positionsize,addedbets)) < 0 )
{
fprintf(stderr,"cant find enough exposure inputs\n");
return("");
prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice);
result.push_back(Pair("result","error"));
result.push_back(Pair("error","position rekt"));
return(result);
}
prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice);
mtx.vin.push_back(CTxVin(bettxid,2,CScript()));
if ( (inputsum= AddPricesInputs(cp,mtx,destaddr,profits+txfee,64,bettxid,2)) > profits+txfee )
CCchange = (inputsum - profits);
mtx.vout.push_back(CTxOut(bettx.vout[2].nValue + profits,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
if ( CCchange >= txfee )
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,pricespk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,prices_finalopret(bettxid,profits,nextheight-1,mypk,firstprice,costbasis,addedbets,positionsize,leverage));
return(prices_rawtxresult(result,rawtx,0));
}
else
{
CCerror = "cant find enough inputsB";
fprintf(stderr,"%s\n", CCerror.c_str() );
result.push_back(Pair("result","error"));
result.push_back(Pair("error","cant decode opret"));
return(result);
}
}
return("");
}
UniValue PricesStatus(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid)
{
UniValue result(UniValue::VOBJ);
// get height of bettxid
// get price and rekt
// get current height and price
// what about if rekt in the past?
return(result);
}
std::string PricesFinish(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid)
UniValue PricesInfo(uint256 bettxid,int32_t height)
{
return("");
UniValue result(UniValue::VOBJ); uint256 hashBlock,tokenid; int64_t myfee,ignore,positionsize=0,addedbets=0,firstprice=0,profits=0,costbasis=0; int32_t i,firstheight=0,height,numvouts; int16_t leverage=0; std::vector<uint16_t> vec; CPubKey pk,mypk,pricespk; std::string rawtx;
if ( myGetTransaction(bettxid,bettx,hashBlock) != 0 && (numvouts= bettx.vout.size()) > 3 )
{
if ( prices_betopretdecode(bettx.vout[numvouts-1].scriptPubKey,pk,firstheight,positionsize,leverage,firstprice,vec,tokenid) == 'B' )
{
costbasis = prices_costbasis(bettx);
addedbets = prices_batontxid(batontxid,bettx,bettxid);
if ( (profits= prices_syntheticprofits(&ignore,firstheight,firstheight+i,leverage,vec,positionsize,addedbets)) < 0 )
{
result.push_back(Pair("rekt",1));
result.push_back(Pair("rektfee",(positionsize + addedbets) / 500));
} else result.push_back(Pair("rekt",0));
result.push_back(Pair("batontxid",batontxid.GetHex()));
prices_betjson(result,profits,costbasis,positionsize,addedbets,leverage,firstheight,firstprice);
return(result);
}
}
result.push_back(Pair("result","error"));
result.push_back(Pair("error","cant find bettxid"));
return(result);
}

1
src/komodo_defs.h

@ -37,6 +37,7 @@
#define KOMODO_MAXNVALUE (((uint64_t)1 << 63) - 1)
#define KOMODO_BIT63SET(x) ((x) & ((uint64_t)1 << 63))
#define KOMODO_VALUETOOBIG(x) ((x) > (uint64_t)10000000001*COIN)
#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1)
extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC;
int32_t MAX_BLOCK_SIZE(int32_t height);

117
src/komodo_gateway.h

@ -2182,6 +2182,9 @@ void komodo_cbopretupdate(int32_t forceflag)
if ( (flags & 4) != 0 )
lastcrypto = now;
memcpy(Mineropret.data(),PriceCache[0],size);
// high volatility still strands nodes so we need to check new prices to approve a stuck block
// scan list of stuck blocks (one?) and auto reconsiderblock if it changed state
//int32_t i; for (i=0; i<Mineropret.size(); i++)
// fprintf(stderr,"%02x",Mineropret[i]);
//fprintf(stderr," <- set Mineropret[%d] size.%d %ld\n",(int32_t)Mineropret.size(),size,sizeof(PriceCache[0]));
@ -2281,31 +2284,32 @@ char *komodo_pricename(char *name,int32_t ind)
return(0);
}
int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t daywindow,uint32_t *nonzprices,int32_t smoothwidth)
int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth)
{
int32_t i,j,k,n,iter,correlation,maxcorrelation=0; int64_t firstprice,price,sum,den,mult,refprice,lowprice,highprice;
if ( daywindow < 2 || ind >= KOMODO_MAXPRICES )
if ( PRICES_DAYWINDOW < 2 || ind >= KOMODO_MAXPRICES )
return(-1);
mult = PriceMult[ind];
memset(nonzprices,0,sizeof(*nonzprices)*daywindow);
for (iter=0; iter<daywindow; iter++)
if ( nonzprices != 0 )
memset(nonzprices,0,sizeof(*nonzprices)*PRICES_DAYWINDOW);
for (iter=0; iter<PRICES_DAYWINDOW; iter++)
{
correlation = 0;
i = (iter + seed) % daywindow;
refprice = rawprices[i];
highprice = (refprice * (COIN + PRICES_MAXCHANGE*3)) / COIN;
lowprice = (refprice * (COIN - PRICES_MAXCHANGE*3)) / COIN;
i = (iter + seed) % PRICES_DAYWINDOW;
refprice = rawprices[i*rawskip];
highprice = (refprice * (COIN + PRICES_MAXCHANGE*5)) / COIN;
lowprice = (refprice * (COIN - PRICES_MAXCHANGE*5)) / COIN;
if ( highprice == refprice )
highprice++;
if ( lowprice == refprice )
lowprice--;
sum = 0;
//fprintf(stderr,"firsti.%d: ",i);
for (j=0; j<daywindow; j++,i++)
for (j=0; j<PRICES_DAYWINDOW; j++,i++)
{
if ( i >= daywindow )
if ( i >= PRICES_DAYWINDOW )
i = 0;
if ( (price= rawprices[i]) == 0 )
if ( (price= rawprices[i*rawskip]) == 0 )
{
fprintf(stderr,"null rawprice.[%d]\n",i);
return(-1);
@ -2315,28 +2319,29 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int
//fprintf(stderr,"%.1f ",(double)price/10000);
sum += price;
correlation++;
if ( correlation > (daywindow>>1) )
if ( correlation > (PRICES_DAYWINDOW>>1) )
{
return(refprice * mult);
if ( nonzprices == 0 )
return(refprice * mult);
//fprintf(stderr,"-> %.4f\n",(double)sum*mult/correlation);
//return(sum*mult/correlation);
n = 0;
i = (iter + seed) % daywindow;
for (k=0; k<daywindow; k++,i++)
i = (iter + seed) % PRICES_DAYWINDOW;
for (k=0; k<PRICES_DAYWINDOW; k++,i++)
{
if ( i >= daywindow )
if ( i >= PRICES_DAYWINDOW )
i = 0;
if ( n > (daywindow>>1) )
if ( n > (PRICES_DAYWINDOW>>1) )
nonzprices[i] = 0;
else
{
price = rawprices[i];
price = rawprices[i*rawskip];
if ( price < lowprice || price > highprice )
nonzprices[i] = 0;
else
{
nonzprices[i] = price;
//fprintf(stderr,"(%d %u) ",i,rawprices[i]);
//fprintf(stderr,"(%d %u) ",i,rawprices[i*rawskip]);
n++;
}
}
@ -2345,17 +2350,17 @@ int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int
if ( n != correlation )
return(-1);
sum = den = n = 0;
for (i=0; i<daywindow; i++)
for (i=0; i<PRICES_DAYWINDOW; i++)
if ( nonzprices[i] != 0 )
break;
firstprice = nonzprices[i];
//fprintf(stderr,"firsti.%d: ",i);
for (i=0; i<daywindow; i++)
for (i=0; i<PRICES_DAYWINDOW; i++)
{
if ( (price= nonzprices[i]) != 0 )
{
den += (daywindow - i);
sum += ((daywindow - i) * (price + firstprice*4)) / 5;
den += (PRICES_DAYWINDOW - i);
sum += ((PRICES_DAYWINDOW - i) * (price + firstprice*4)) / 5;
n++;
}
}
@ -2447,61 +2452,29 @@ void smooth64(int64_t dest[],int64_t src[],int32_t width,int32_t smoothiters)
} else memcpy(dest,src,width*sizeof(*dest));
}
int64_t komodo_pricesmoothed(int64_t *correlated,int32_t daywindow,int64_t *nonzprices,int32_t smoothwidth)
int64_t komodo_pricesmoothed(int64_t *correlated,int32_t cskip,int64_t *rawprices,int32_t numprices)
{
const int64_t coeffs[7] = { -2, 0, 18, 32, 18, 0, -2 };
int32_t i,iter; int64_t smoothedden,smoothedsum,sum,den,smoothed[7],firstprice = correlated[0];
if ( daywindow < 2 )
//const int64_t coeffs[7] = { -2, 0, 18, 32, 18, 0, -2 };
int32_t i; int64_t sum=0,nonzprice,price;
if ( PRICES_DAYWINDOW < 2 )
return(0);
if ( smoothwidth != sizeof(smoothed)/sizeof(*smoothed) )
for (i=0; i<PRICES_DAYWINDOW; i++)
{
fprintf(stderr,"smoothwidth %d != %d\n",smoothwidth,(int32_t)(sizeof(smoothed)/sizeof(*smoothed)));
return(0);
}
memset(nonzprices,0,sizeof(*nonzprices)*daywindow);
for (i=1; i<daywindow; i++)
{
if ( correlated[i] == 0 )
correlated[i] = correlated[i-1];
if ( firstprice == 0 && correlated[i] != 0 )
{
firstprice = correlated[i];
if ( (nonzprice= correlated[i*cskip]) != 0 )
break;
}
}
if ( firstprice != 0 )
if ( nonzprice == 0 )
return(-1);
for (i=0; i<PRICES_DAYWINDOW; i++)
{
for (i=0; i<daywindow; i++)
{
if ( correlated[i] == 0 )
correlated[i] = firstprice;
else break;
}
//memcpy(orig,correlated,(daywindow+smoothwidth)*sizeof(*correlated));
for (iter=0; iter<smoothwidth; iter++)
{
sum = den = 0;
//smooth64(dest,correlated+iter,daywindow,1);
//smooth64(correlated+iter,dest,daywindow,1);
for (i=0; i<daywindow; i++)
{
sum += correlated[i+iter];//((daywindow - i) * (correlated[i+iter] + firstprice*4)) / 5;
den += 1;//(daywindow - i);
}
smoothed[iter] = (sum / den);
//memcpy(correlated,orig,(daywindow+smoothwidth)*sizeof(*correlated));
}
smoothedsum = 0;
smoothedden = 64;
for (i=0; i<7; i++)
{
//fprintf(stderr,"%.4f ",(double)smoothed[i]/10000);
smoothedsum += coeffs[i] * smoothed[i];
//smoothedden += (7-i);
}
//fprintf(stderr,"-> %.4f\n",(double)(smoothedsum/smoothedden)/10000);
return(smoothedsum/smoothedden);
if ( (price= correlated[i*cskip]) != 0 )
nonzprice = price;
//correlated2[i] = nonzprice / PRICES_DAYWINDOW; // reduce precision
sum += nonzprice;
}
return(0);
price = sum / PRICES_DAYWINDOW;
// improve smoothing with correlated2 processing
// price = smooth(correlated2,PRICES_DAYWINDOW,price/daywindow) * PRICES_DAYWINDOW;
return(price);
}

69
src/rpc/blockchain.cpp

@ -1176,19 +1176,58 @@ UniValue paxprice(const UniValue& params, bool fHelp)
int32_t komodo_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight);
char *komodo_pricename(char *name,int32_t ind);
int64_t komodo_pricesmoothed(int64_t *correlated,int32_t numprices,int64_t *correlated2,int32_t smoothwidth);
int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t numprices,uint32_t *rawprices2,int32_t smoothwidth);
int64_t komodo_pricesmoothed(int64_t *correlated,int32_t cskip,int32_t int64_t *correlated2,int32_t numprices);
int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t skip,int32_t numprices,uint32_t *rawprices2,int32_t smoothwidth);
int32_t komodo_nextheight();
uint32_t komodo_heightstamp(int32_t height);
int64_t komodo_pricemult(int32_t ind);
#define PRICES_SMOOTHWIDTH 1
int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind)
{
int32_t height,i,width,numpricefeeds = -1; uint64_t seed,rngval,*correlated2; uint32_t rawprices[1440*6],*ptr;
//daywindow = (3600*24/ASSETCHAINS_BLOCKTIME) + 1;
//pricedata = (uint32_t *)calloc(sizeof(*prices)*3,numblocks + daywindow*2 + PRICES_SMOOTHWIDTH);
width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH;
komodo_heightpricebits(&seed,rawprices,firstheight + numblocks - 1);
if ( firstheight < width )
return(-1);
for (i=0; i<width; i++)
{
if ( (n= komodo_heightpricebits(&ignore,rawprices,firstheight + numblocks - 1 - i)) < 0 )
return(-1);
if ( numpricefeeds < 0 )
numpricefeeds = n;
if ( n != numpricefeeds )
return(-2);
ptr = (uint32_t *)&pricedata[i*3];
ptr[0] = rawprices[ind];
ptr[1] = rawprices[0]; // timestamp
}
rngval = seed;
correlated2 = (int64_t *)calloc(sizeof(*correlated2),width);
for (i=0; i<numblocks+PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH; i++)
{
rngval = (rngval*11109 + 13849);
ptr = (uint32_t *)&pricedata[i*3];
correlated2[i] = ptr[0];
if ( (pricedata[i*3+1]= komodo_pricecorrelated(rngval,ind,(uint32_t)&pricedata[i*3],6,0,PRICES_SMOOTHWIDTH)) < 0 )
{
free(correlated2);
return(-3);
}
}
for (i=0; i<numblocks; i++)
pricedata[i*3+2] = komodo_pricesmoothed(&pricedata[i*3+1],3,correlated2,numblocks+PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH);
return(0);
}
UniValue prices(const UniValue& params, bool fHelp)
{
int32_t smoothwidth = 7;
if ( fHelp || params.size() != 1 )
throw runtime_error("prices maxsamples\n");
LOCK(cs_main);
UniValue ret(UniValue::VOBJ); uint64_t seed,rngval; int64_t smoothed,*correlated,*correlated2; char name[64],*str; uint32_t rawprices[1440*6],*prices,*prices2; uint32_t i,width,j,numpricefeeds=-1,n,numsamples,nextheight,offset,ht,daywindow = (3600*24/ASSETCHAINS_BLOCKTIME) + 1;
UniValue ret(UniValue::VOBJ); uint64_t seed,rngval; int64_t smoothed,*correlated,*correlated2; char name[64],*str; uint32_t rawprices[1440*6],*prices; uint32_t i,width,j,numpricefeeds=-1,n,numsamples,nextheight,offset,ht;
if ( ASSETCHAINS_CBOPRET == 0 )
throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices");
@ -1197,16 +1236,16 @@ UniValue prices(const UniValue& params, bool fHelp)
maxsamples = 1;
nextheight = komodo_nextheight();
UniValue a(UniValue::VARR);
if ( daywindow < 7 )
daywindow = 7;
width = maxsamples+2*daywindow+smoothwidth;
if ( PRICES_DAYWINDOW < 7 )
throw JSONRPCError(RPC_INVALID_PARAMETER, "daywindow is too small");
width = maxsamples+2*PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH;
numpricefeeds = komodo_heightpricebits(&seed,rawprices,nextheight-1);
if ( numpricefeeds <= 0 )
throw JSONRPCError(RPC_INVALID_PARAMETER, "illegal numpricefeeds");
prices = (uint32_t *)calloc(sizeof(*prices),width*numpricefeeds);
correlated = (int64_t *)calloc(sizeof(*correlated),width);
correlated2 = (int64_t *)calloc(sizeof(*correlated2),width);
prices2 = (uint32_t *)calloc(sizeof(*prices2),width);
//prices2 = (uint32_t *)calloc(sizeof(*prices2),width);
i = 0;
for (ht=nextheight-1,i=0; i<width&&ht>2; i++,ht--)
{
@ -1233,7 +1272,7 @@ UniValue prices(const UniValue& params, bool fHelp)
timestamps.push_back((int64_t)prices[i]);
ret.push_back(Pair("timestamps",timestamps));
rngval = seed;
//for (i=0; i<daywindow; i++)
//for (i=0; i<PRICES_DAYWINDOW; i++)
// fprintf(stderr,"%.4f ",(double)prices[width+i]/10000);
//fprintf(stderr," maxsamples.%d\n",maxsamples);
for (j=1; j<numpricefeeds; j++)
@ -1244,21 +1283,23 @@ UniValue prices(const UniValue& params, bool fHelp)
item.push_back(Pair("name",str));
if ( numsamples >= width )
{
for (i=0; i<maxsamples+daywindow+smoothwidth&&i<numsamples; i++)
for (i=0; i<maxsamples+PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH&&i<numsamples; i++)
{
offset = j*width + i;
rngval = (rngval*11109 + 13849);
if ( (correlated[i]= komodo_pricecorrelated(rngval,j,&prices[offset],daywindow,prices2,smoothwidth)) < 0 )
correlated2[i] = prices[offset];
if ( (correlated[i]= komodo_pricecorrelated(rngval,j,&prices[offset],1,0,PRICES_SMOOTHWIDTH)) < 0 )
throw JSONRPCError(RPC_INVALID_PARAMETER, "null correlated price");
}
for (i=0; i<maxsamples&&i<numsamples; i++)
{
offset = j*width + i;
smoothed = komodo_pricesmoothed(&correlated[i],daywindow,correlated2,smoothwidth);
smoothed = komodo_pricesmoothed(&correlated[i],1,correlated2,maxsamples+PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH);
UniValue parr(UniValue::VARR);
parr.push_back(ValueFromAmount((int64_t)prices[offset] * komodo_pricemult(j)));
parr.push_back(ValueFromAmount(correlated[i]));
parr.push_back(ValueFromAmount(smoothed));
// compare to alternate method
p.push_back(parr);
}
}
@ -1282,10 +1323,10 @@ UniValue prices(const UniValue& params, bool fHelp)
ret.push_back(Pair("height",(int64_t)nextheight-1));
ret.push_back(Pair("maxsamples",(int64_t)maxsamples));
ret.push_back(Pair("width",(int64_t)width));
ret.push_back(Pair("daywindow",(int64_t)daywindow));
ret.push_back(Pair("daywindow",(int64_t)PRICES_DAYWINDOW));
ret.push_back(Pair("numpricefeeds",(int64_t)numpricefeeds));
free(prices);
free(prices2);
//free(prices2);
free(correlated);
free(correlated2);
return ret;

109
src/txdb.cpp

@ -438,6 +438,111 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type,
bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address);
uint32_t komodo_segid32(char *coinaddr);
const std::map <std::string,int> ignoredMap = {
{"RReUxSs5hGE39ELU23DfydX8riUuzdrHAE", 1},
{"RMUF3UDmzWFLSKV82iFbMaqzJpUnrWjcT4", 1},
{"RA5imhVyJa7yHhggmBytWuDr923j2P1bxx", 1},
{"RBM5LofZFodMeewUzoMWcxedm3L3hYRaWg", 1},
{"RAdcko2d94TQUcJhtFHZZjMyWBKEVfgn4J", 1},
{"RLzUaZ934k2EFCsAiVjrJqM8uU1vmMRFzk", 1},
{"RMSZMWZXv4FhUgWhEo4R3AQXmRDJ6rsGyt", 1},
{"RUDrX1v5toCsJMUgtvBmScKjwCB5NaR8py", 1},
{"RMSZMWZXv4FhUgWhEo4R3AQXmRDJ6rsGyt", 1},
{"RRvwmbkxR5YRzPGL5kMFHMe1AH33MeD8rN", 1},
{"RQLQvSgpPAJNPgnpc8MrYsbBhep95nCS8L", 1},
{"RK8JtBV78HdvEPvtV5ckeMPSTojZPzHUTe", 1},
{"RHVs2KaCTGUMNv3cyWiG1jkEvZjigbCnD2", 1},
{"RE3SVaDgdjkRPYA6TRobbthsfCmxQedVgF", 1},
{"RW6S5Lw5ZCCvDyq4QV9vVy7jDHfnynr5mn", 1},
{"RTkJwAYtdXXhVsS3JXBAJPnKaBfMDEswF8", 1},
{"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} //Burnaddress for null privkey
};
UniValue CBlockTreeDB::Snapshot2(int64_t dustthreshold,int32_t top,std::vector <std::pair<CAmount, std::string>> &vaddr)
{
int64_t total = 0; int64_t totalAddresses = 0; std::string address;
int64_t utxos = 0; int64_t ignoredAddresses = 0;
boost::scoped_ptr<CDBIterator> iter(NewIterator());
std::map <std::string, CAmount> addressAmounts;
for (iter->SeekToLast(); iter->Valid(); iter->Prev())
{
boost::this_thread::interruption_point();
try
{
std::vector<unsigned char> slKey = std::vector<unsigned char>();
pair<char, CAddressIndexIteratorKey> keyObj;
iter->GetKey(keyObj);
char chType = keyObj.first;
CAddressIndexIteratorKey indexKey = keyObj.second;
//fprintf(stderr, "chType=%d\n", chType);
if (chType == DB_ADDRESSUNSPENTINDEX)
{
try {
CAmount nValue;
iter->GetValue(nValue);
getAddressFromIndex(indexKey.type, indexKey.hashBytes, address);
if ( nValue > dustthreshold )
{
std::map <std::string, int>::iterator ignored = ignoredMap.find(address);
if (ignored != ignoredMap.end())
{
fprintf(stderr,"ignoring %s\n", address.c_str());
ignoredAddresses++;
continue;
}
std::map <std::string, CAmount>::iterator pos = addressAmounts.find(address);
if ( pos == addressAmounts.end() )
{
// insert new address + utxo amount
//fprintf(stderr, "inserting new address %s with amount %li\n", address.c_str(), nValue);
addressAmounts[address] = nValue;
totalAddresses++;
}
else
{
// update unspent tally for this address
//fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue);
addressAmounts[address] += nValue;
}
//fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN);
// total += nValue;
utxos++;
} else fprintf(stderr,"ignoring amount=0 UTXO for %s\n", address.c_str());
}
catch (const std::exception& e)
{
fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what());
break;
}
}
}
catch (const std::exception& e)
{
fprintf(stderr, "DONE reading index entries\n");
break;
}
}
fprintf(stderr, "total=%f, totalAddresses=%li, utxos=%li, ignored=%li\n", (double) total / COIN, totalAddresses, utxos, ignoredAddresses);
for (std::pair<std::string, CAmount> element : addressAmounts)
vaddr.push_back( make_pair(element.second, element.first) );
std::sort(vaddr.rbegin(), vaddr.rend());
int topN = 0;
for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it)
{
//obj.push_back( make_pair("addr", it->second.c_str() ) );
//char amount[32];
//sprintf(amount, "%.8f", (double) it->first / COIN);
//obj.push_back( make_pair("amount", amount) );
//obj.push_back( make_pair("segid",(int32_t)komodo_segid32((char *)it->second.c_str()) & 0x3f) );
//addressesSorted.push_back(obj);
total += it->first;
topN++;
// If requested, only show top N addresses in output JSON
if ( top == topN )
break;
}
}
UniValue CBlockTreeDB::Snapshot(int top)
{
int64_t total = 0; int64_t totalAddresses = 0; std::string address;
@ -448,7 +553,7 @@ UniValue CBlockTreeDB::Snapshot(int top)
UniValue result(UniValue::VOBJ);
result.push_back(Pair("start_time", (int) time(NULL)));
std::map <std::string,int> ignoredMap = {
/* std::map <std::string,int> ignoredMap = {
{"RReUxSs5hGE39ELU23DfydX8riUuzdrHAE", 1},
{"RMUF3UDmzWFLSKV82iFbMaqzJpUnrWjcT4", 1},
{"RA5imhVyJa7yHhggmBytWuDr923j2P1bxx", 1},
@ -466,7 +571,7 @@ UniValue CBlockTreeDB::Snapshot(int top)
{"RW6S5Lw5ZCCvDyq4QV9vVy7jDHfnynr5mn", 1},
{"RTkJwAYtdXXhVsS3JXBAJPnKaBfMDEswF8", 1},
{"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} //Burnaddress for null privkey
};
};*/
int64_t startingHeight = chainActive.Height();
//fprintf(stderr, "Starting snapshot at height %lli\n", startingHeight);

Loading…
Cancel
Save