Browse Source

Vectorize OraclesPrices

metaverse
jl777 6 years ago
parent
commit
6b078fa6fe
  1. 2
      src/cc/CCOracles.h
  2. 106
      src/cc/oracles.cpp

2
src/cc/CCOracles.h

@ -19,8 +19,6 @@
#include "CCinclude.h"
#define ORACLES_MAXPROVIDERS 64
bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format);
std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee);

106
src/cc/oracles.cpp

@ -369,6 +369,13 @@ int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t
return(offset);
}
struct oracleprice_info
{
CPubKey pk;
std::vector <uint8_t> data;
int32_t height;
};
int64_t _correlate_price(int64_t *prices,int32_t n,int64_t price)
{
int32_t i,count = 0; int64_t diff,threshold = (price >> 8);
@ -384,25 +391,11 @@ int64_t _correlate_price(int64_t *prices,int32_t n,int64_t price)
else return(price);
}
int _increasing_uint64(const void *a,const void *b)
{
#define uint64_a (*(uint64_t *)a)
#define uint64_b (*(uint64_t *)b)
if ( uint64_b > uint64_a )
return(-1);
else if ( uint64_b < uint64_a )
return(1);
return(0);
#undef uint64_a
#undef uint64_b
}
int64_t correlate_price(int32_t height,int64_t *prices,int32_t n)
{
int32_t i,j; int64_t price = 0;
if ( n == 1 )
return(prices[0]);
//heapsort(prices,n,sizeof(*prices),_increasing_uint64);
for (i=0; i<n; i++)
{
j = (height + i) % n;
@ -414,55 +407,84 @@ int64_t correlate_price(int32_t height,int64_t *prices,int32_t n)
fprintf(stderr,"-> %llu ht.%d\n",(long long)price,height);
}
int64_t OracleCorrelatedPrice(int32_t height,char *format,std::vector <uint8_t> datas[ORACLES_MAXPROVIDERS],int32_t n)
int64_t OracleCorrelatedPrice(std::vector <int64_t> origprices)
{
std::vector <int64_t> sorted; int32_t i,n; int64_t *prices,price;
if ( (n= origprices.size()) == 1 )
return(origprices[0]);
sorted = origprices.sorted();
prices = calloc(n,sizeof(*prices));
i = 0;
for (std::vector<int64_t>::const_iterator it=sorted.begin(); it!=sorted.end(); it++)
prices[i++] = it->first;
price = correlate_price(prices,i);
free(prices);
return(price);
}
int32_t oracleprice_add(std::vector<struct oracleprice_info> &publishers,CPubKey pk,int32_t height,std::vector <uint8_t> data,int32_t maxheight)
{
int64_t prices[ORACLES_MAXPROVIDERS]; int32_t i,m=0; uint256 hash; int64_t val,price=0;
if ( format[0] == 'L' )
struct oracleprice_info item; int32_t flag = 0;
for (std::vector<struct oracleprice_info>::const_iterator it=publishers.begin(); it!=publishers.end(); it++)
{
for (i=0; i<n; i++)
if ( pk == it->first.pk )
{
oracle_format(&hash,&val,0,'L',(uint8_t *)datas[i].data(),0,(int32_t)datas[i].size());
if ( val != 0 )
prices[m++] = val;
flag = 1;
if (height > it->first.height )
{
it->first.height = height;
it->first.data = data;
return(height);
}
}
}
if ( m != 0 )
price = correlate_price(height,prices,m);
return(0);
if ( flag == 0 )
{
item.pk = pk;
item.data = data;
item.height = height;
publishers.push_back(item);
return(height);
} else return(0);
}
int64_t OraclePrice(int32_t height,uint256 reforacletxid,char *markeraddr,char *format)
{
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
CTransaction regtx,tx; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk,providers[ORACLES_MAXPROVIDERS]; int32_t i,j,n=0; int64_t datafee; char batonaddr[64]; std::vector <uint8_t> data,datas[ORACLES_MAXPROVIDERS]; struct CCcontract_info *cp,C;
CTransaction regtx,tx; uint256 hash,txid,oracletxid,batontxid; CPubKey pk; int32_t i,ht,height,maxheight=0; int64_t datafee,price; char batonaddr[64]; std::vector <uint8_t> data; struct CCcontract_info *cp,C; std::vector <struct oracleprice_info> providers; std::vector <int64_t> prices;
if ( format[0] != 'L' )
return(0);
cp = CCinit(&C,EVAL_ORACLES);
SetCCunspents(unspentOutputs,markeraddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
if ( myGetTransaction(txid,regtx,hashBlock) != 0 )
height = (int32_t)it->second.blockHeight;
if ( myGetTransaction(txid,regtx,hash) != 0 )
{
if ( regtx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == reforacletxid )
{
for (j=0; j<n; j++)
if ( pk == providers[j] )
break;
if ( j == n )
{
Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey);
batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data);
if ( batontxid != zeroid )
{
datas[n] = data;
providers[n++] = pk;
if ( n == ORACLES_MAXPROVIDERS )
break;
}
}
Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey);
batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data);
if ( batontxid != zeroid && (ht= oracleprice_add(publishers,pk,height,data,maxheight)) > maxht )
maxheight = ht;
}
}
}
return(OracleCorrelatedPrice(height,format,datas,n));
if ( maxheight > 10 )
{
for (std::vector<struct oracleprice_info>::const_iterator it=publishers.begin(); it!=publishers.end(); it++)
{
if ( it->first.height >= maxheight-10 )
{
oracle_format(&hash,&price,0,'L',(uint8_t *)it->first.data.data(),0,(int32_t)it->first.data.size());
if ( price != 0 )
prices.push_back(price);
}
}
return(OracleCorrelatedPrice(prices));
}
return(0);
}
int64_t IsOraclesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)

Loading…
Cancel
Save