Browse Source

KOMODO_LOCALPRICE_CACHESIZE

z_createrawtransaction
jl777 5 years ago
parent
commit
50f79c5d4a
  1. 4
      src/bitcoind.cpp
  2. 176
      src/komodo_gateway.h
  3. 4
      src/komodo_utils.h
  4. 74
      src/rpc/blockchain.cpp

4
src/bitcoind.cpp

@ -64,7 +64,7 @@ extern uint64_t ASSETCHAINS_CBOPRET;
void komodo_passport_iteration();
uint64_t komodo_interestsum();
int32_t komodo_longestchain();
void komodo_cbopretupdate();
void komodo_cbopretupdate(int32_t forceflag);
void WaitForShutdown(boost::thread_group* threadGroup)
{
@ -89,7 +89,7 @@ void WaitForShutdown(boost::thread_group* threadGroup)
//komodo_interestsum();
//komodo_longestchain();
if ( ASSETCHAINS_CBOPRET != 0 )
komodo_cbopretupdate();
komodo_cbopretupdate(0);
for (i=0; i<=ASSETCHAINS_BLOCKTIME/5; i++)
{
fShutdown = ShutdownRequested();

176
src/komodo_gateway.h

@ -1551,6 +1551,15 @@ void komodo_passport_iteration()
extern std::vector<uint8_t> Mineropret; // opreturn data set by the data gathering code
#define PRICES_MAXCHANGE (COIN / 100) // maximum acceptable change, set at 1%
#define PRICES_SIZEBIT0 (sizeof(uint32_t) * 4) // 4 uint32_t unixtimestamp, BTCUSD, BTCGBP and BTCEUR
#define KOMODO_LOCALPRICE_CACHESIZE 7
uint32_t PriceCache[KOMODO_LOCALPRICE_CACHESIZE][4+sizeof(Cryptos)/sizeof(*Cryptos)+sizeof(Forex)/sizeof(*Forex)];
void komodo_PriceCache_shift()
{
int32_t i;
for (i=KOMODO_LOCALPRICE_CACHESIZE-1; i>=0; i--)
memcpy(PriceCache[i],PriceCache[i-1],sizeof(PriceCache[i]));
}
// komodo_heightpricebits() extracts the price data in the coinbase for nHeight
int32_t komodo_heightpricebits(uint32_t *heightbits,int32_t nHeight)
@ -1574,20 +1583,6 @@ int32_t komodo_heightpricebits(uint32_t *heightbits,int32_t nHeight)
return(-1);
}
int32_t komodo_prices(uint32_t *prices,uint32_t *correlated,uint32_t *smoothed,int32_t height)
{
int32_t i,n;
n = komodo_heightpricebits(prices,height);
for (i=0; i<n; i++)
{
correlated[i] = prices[i];
}
for (i=0; i<n; i++)
{
smoothed[i] = correlated[i];
}
}
/*
komodo_pricenew() is passed in a reference price, the change tolerance and the proposed price. it needs to return a clipped price if it is too big and also set a flag if it is at or above the limit
*/
@ -1712,7 +1707,7 @@ CScript komodo_mineropret(int32_t nHeight)
int32_t komodo_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int32_t nHeight,CScript scriptPubKey)
{
int32_t testchain_exemption = 500;
std::vector<uint8_t> vopret; char maxflags[2048]; double btcusd,btcgbp,btceur; uint32_t localbits[2048],pricebits[2048],prevbits[2048],newprice; int32_t i,prevtime,maxflag,lag,lag2,lag3,n; uint32_t now = (uint32_t)time(NULL);
std::vector<uint8_t> vopret; char maxflags[2048]; double btcusd,btcgbp,btceur; uint32_t localbits[2048],pricebits[2048],prevbits[2048],newprice; int32_t i,j,prevtime,maxflag,lag,lag2,lag3,n,errflag,iter; uint32_t now = (uint32_t)time(NULL);
if ( ASSETCHAINS_CBOPRET != 0 && nHeight > 0 )
{
GetOpReturnData(scriptPubKey,vopret);
@ -1778,16 +1773,48 @@ int32_t komodo_opretvalidate(const CBlock *block,CBlockIndex * const previndex,i
if ( localbits[i] == 0 )
localbits[i] = prevbits[i];
}
for (i=1; i<n; i++)
for (iter=0; iter<2; iter++) // first iter should just refresh prices if out of tolerance
{
if ( (maxflag= maxflags[i]) != 0 )
for (i=1; i<n; i++)
{
// make sure local price is moving in right direction
fprintf(stderr,"maxflag.%d i.%d localbits.%u vs pricebits.%u prevbits.%u\n",maxflag,i,localbits[i],pricebits[i],prevbits[i]);
if ( maxflag > 0 && localbits[i] < prevbits[i] )
return(-1);
else if ( maxflag < 0 && localbits[i] > prevbits[i] )
return(-1);
if ( (maxflag= maxflags[i]) != 0 )
{
// make sure local price is moving in right direction
fprintf(stderr,"maxflag.%d i.%d localbits.%u vs pricebits.%u prevbits.%u\n",maxflag,i,localbits[i],pricebits[i],prevbits[i]);
if ( maxflag > 0 && localbits[i] < prevbits[i] )
{
if ( iter == 0 )
break;
// second iteration checks recent prices to see if within local volatility
for (j=0; j<KOMODO_LOCALPRICE_CACHESIZE; j++)
if ( PriceCache[j][i] >= prevbits[i] )
{
fprintf(stderr,"within recent localprices[%d] %u >= %u\n",j,PriceCache[j][i],prevbits[i]);
continue;
}
break;
}
else if ( maxflag < 0 && localbits[i] > prevbits[i] )
{
if ( iter == 0 )
break;
for (j=0; j<KOMODO_LOCALPRICE_CACHESIZE; j++)
if ( PriceCache[j][i] <= prevbits[i] )
{
fprintf(stderr,"within recent localprices[%d] %u <= prev %u\n",j,PriceCache[j][i],prevbits[i]);
continue;
}
break;
}
}
}
if ( i != n )
{
if ( iter == 0 )
{
fprintf(stderr,"force update prices\n");
komodo_cbopretupdate(1);
} else return(-1);
}
}
}
@ -2057,17 +2084,18 @@ int32_t get_btcusd(uint32_t pricebits[4])
// komodo_cbopretupdate() obtains the external price data and encodes it into Mineropret, which will then be used by the miner and validation
// save history, use new data to approve past rejection, where is the auto-reconsiderblock?
// 51% correlation, smoothing
void komodo_cbopretupdate()
void komodo_cbopretupdate(int32_t forceflag)
{
static uint32_t lasttime,lastcrypto,lastbtc;
static uint32_t pricebits[4],cryptoprices[sizeof(Cryptos)/sizeof(*Cryptos)],forexprices[sizeof(Forex)/sizeof(*Forex)];
int32_t size; uint32_t now = (uint32_t)time(NULL);
int32_t size; uint32_t flags=0,now;
now = (uint32_t)time(NULL);
if ( (ASSETCHAINS_CBOPRET & 1) != 0 )
{
if ( komodo_nextheight() > 333 )
ASSETCHAINS_CBOPRET = 7;
if ( komodo_nextheight() > 333 ) // for debug only!
ASSETCHAINS_CBOPRET = 7;
size = PRICES_SIZEBIT0;
if ( (ASSETCHAINS_CBOPRET & 2) != 0 )
size += sizeof(forexprices);
@ -2076,31 +2104,48 @@ void komodo_cbopretupdate()
if ( Mineropret.size() < size )
Mineropret.resize(size);
size = PRICES_SIZEBIT0;
if ( now > lastbtc+120 && get_btcusd(pricebits) == 0 )
if ( (forceflag != 0 || now > lastbtc+120) && get_btcusd(pricebits) == 0 )
{
memcpy(Mineropret.data(),pricebits,PRICES_SIZEBIT0);
lastbtc = (uint32_t)time(NULL);
if ( flags == 0 )
komodo_PriceCache_shift();
memcpy(PriceCache[0],pricebits,PRICES_SIZEBIT0);
flags |= 1;
}
if ( (ASSETCHAINS_CBOPRET & 2) != 0 )
{
if ( now > lasttime+3600*5 || forexprices[0] == 0 )
if ( now > lasttime+3600*5 || forexprices[0] == 0 ) // cant assume timestamp is valid for forex price as it is a daily weekday changing thing anyway.
{
get_dailyfx(forexprices);
memcpy(&Mineropret.data()[size],forexprices,sizeof(forexprices));
lasttime = (uint32_t)time(NULL);
if ( flags == 0 )
komodo_PriceCache_shift();
flags |= 2;
memcpy(&PriceCache[0][size],forexprices,sizeof(forexprices));
}
size += sizeof(forexprices);
}
if ( (ASSETCHAINS_CBOPRET & 4) != 0 )
{
if ( now > lastcrypto+100 )
if ( forceflag != 0 || flags != 0 )
{
get_cryptoprices(cryptoprices,Cryptos,(int32_t)(sizeof(Cryptos)/sizeof(*Cryptos)));
memcpy(&Mineropret.data()[size],cryptoprices,sizeof(cryptoprices));
lastcrypto = (uint32_t)time(NULL);
if ( flags == 0 )
komodo_PriceCache_shift();
memcpy(&PriceCache[0][size],cryptoprices,sizeof(cryptoprices));
flags |= 4; // very rarely we can see flags == 6 case
}
size += sizeof(cryptoprices);
}
if ( flags != 0 )
{
now = (uint32_t)time(NULL);
if ( (flags & 1) != 0 )
lastbtc = now;
if ( (flags & 2) != 0 )
lasttime = now;
if ( (flags & 4) != 0 )
lastcrypto = now;
memcpy(Mineropret.data(),PriceCache[0],size);
}
//int32_t i; for (i=0; i<Mineropret.size(); i++)
// fprintf(stderr,"%02x",Mineropret[i]);
//fprintf(stderr," <- set Mineropret[%d]\n",(int32_t)Mineropret.size());
@ -2119,3 +2164,60 @@ void komodo_cbopretupdate()
}*/
}
}
char *komodo_pricename(char *name,int32_t ind)
{
strcpy(name,"error");
if ( (ASSETCHAINS_CBOPRET & 1) != 0 )
{
if ( ind < 4 )
{
switch ( ind )
{
case 0: strcpy(name,"timestamp"); break;
case 1: strcpy(name,"BTCUSD"); break;
case 2: strcpy(name,"BTCGBP"); break;
case 3: strcpy(name,"BTCEUR"); break;
default: return(0); break;
}
return(name);
}
else
{
ind -= 4;
if ( (ASSETCHAINS_CBOPRET & 2) != 0 )
{
if ( ind < 0 )
return(0);
if ( ind < sizeof(Forex)/sizeof(*Forex) )
{
strcpy(name,Forex[ind]);
return(name);
} else ind -= sizeof(Forex)/sizeof(*Forex);
}
if ( (ASSETCHAINS_CBOPRET & 4) != 0 )
{
if ( ind < 0 )
return(0);
if ( ind < sizeof(Cryptos)/sizeof(*Cryptos) )
{
strcpy(name,Cryptos[ind]);
return(name);
} else ind -= sizeof(Cryptos)/sizeof(*Cryptos);
}
}
}
return(0);
}
uint32_t komodo_timestampset(uint32_t *correlatedp,uint32_t *rawtimestamps,int32_t numtimestamps)
{
*correlatedp = rawtimestamps[0];
return(rawtimestamps[0]); // really to do this would need to do it on a per pricefeed and which prices were used in the correlation, but that is a lot of extra work for a field which is not critical
}
uint32_t komodo_pricesmoothed(uint32_t *correlatedp,uint32_t *rawprices,int32_t numprices)
{
}

4
src/komodo_utils.h

@ -1664,7 +1664,7 @@ uint64_t komodo_ac_block_subsidy(int nHeight)
}
extern int64_t MAX_MONEY;
void komodo_cbopretupdate();
void komodo_cbopretupdate(int32_t forceflag);
void komodo_args(char *argv0)
{
@ -2067,7 +2067,7 @@ void komodo_args(char *argv0)
if ( ASSETCHAINS_CBOPRET != 0 )
{
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_CBOPRET),(void *)&ASSETCHAINS_CBOPRET);
komodo_cbopretupdate(); // will set Mineropret
komodo_cbopretupdate(1); // will set Mineropret
fprintf(stderr,"This blockchain uses data produced from CoinDesk Bitcoin Price Index\n");
}
}

74
src/rpc/blockchain.cpp

@ -1174,21 +1174,24 @@ UniValue paxprice(const UniValue& params, bool fHelp)
return ret;
}
int32_t komodo_prices(uint32_t *prices,uint32_t *correlated,uint32_t *smoothed,int32_t height);
int32_t komodo_heightpricebits(uint32_t *heightbits,int32_t nHeight);
char *komodo_pricename(char *name,int32_t ind);
uint32_t komodo_pricesmoothed(uint32_t *correlatedp,uint32_t *rawprices,int32_t numprices);
uint32_t komodo_timestampset(uint32_t *correlatedp,uint32_t *rawprices,int32_t numprices);
UniValue prices(const UniValue& params, bool fHelp)
{
if ( fHelp || params.size() != 1 )
throw runtime_error("prices maxsamples\n");
LOCK(cs_main);
UniValue ret(UniValue::VOBJ); uint32_t *prices,*correlated,*smoothed; uint32_t i,firstn=-1,n,nextheight,ht,num=0,daywindow = (3600*24/ASSETCHAINS_BLOCKTIME) + 1;
UniValue ret(UniValue::VOBJ); char name[64],*str; uint32_t rawprices[2048],*prices,*correlated,*smoothed; uint32_t i,j,firstn=-1,n,nextheight,offset,ht,num=0,daywindow = (3600*24/ASSETCHAINS_BLOCKTIME) + 1;
int32_t maxsamples = atoi(params[0].get_str().c_str());
if ( maxsamples < 1 )
maxsamples = 1;
else if ( maxsamples > sizeof(heights)/sizeof(*heights) )
maxsamples = sizeof(heights)/sizeof(*heights);
nextheight = komodo_nextheight();
UniValue a(UniValue::VARR);
if ( daywindow < 7 )
daywindow = 7;
prices = (uint32_t *)calloc(sizeof(*prices),maxsamples+daywindow);
correlated = (uint32_t *)calloc(sizeof(*correlated),maxsamples+daywindow);
smoothed = (uint32_t *)calloc(sizeof(*smoothed),maxsamples+daywindow);
@ -1198,7 +1201,7 @@ UniValue prices(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
else
{
if ( (n= komodo_prices(rawprices,ht)) > 0 )
if ( (n= komodo_heightpricebits(rawprices,ht)) > 0 )
{
if ( firstn == -1 )
firstn = n;
@ -1212,42 +1215,45 @@ UniValue prices(const UniValue& params, bool fHelp)
} else throw JSONRPCError(RPC_INVALID_PARAMETER, "no komodo_rawprices found");
}
}
free(prices);
free(correlated);
free(smoothed);
/*for (i=0; i<maxsamples; i++)
for (i=0; i<maxsamples; i++)
{
UniValue item(UniValue::VOBJ),parr(UniValue::VARR);
item.push_back(Pair("height", (int64_t)ht));
if ( (n= komodo_prices(prices,correlated,smoothed,ht)) <= 0 )
item.push_back(Pair("heighterror",(int64_t)n));
else
UniValue timestamps(UniValue::VARR);
smoothed[i] = komodo_timestampset(&correlated[i],&rawprices[i],daywindow);
timestamps.push_back((int64_t)rawprices[i]);
timestamps.push_back((int64_t)correlated[i]);
timestamps.push_back((int64_t)smoothed[i]);
timestamps.push_back((int64_t)komodo_heightstamp(nextheight-1-i));
ret.push_back(Pair("timestamps",timestamps));
ret.push_back(Pair("heights", (int64_t)nextheight-1-i));
}
for (j=1; j<firstn; j++)
{
UniValue item(UniValue::VOBJ),prices(UniValue::VARR);
if ( (str= komodo_pricename(name,j)) != 0 )
{
UniValue timestamps(UniValue::VARR);
timestamps.push_back((int64_t)prices[0]);
timestamps.push_back((int64_t)correlated[0]);
timestamps.push_back((int64_t)smoothed[0]);
timestamps.push_back((int64_t)komodo_heightstamp(ht));
item.push_back(Pair("timestamps",timestamps));
for (j=0; j<n; i++)
item.push_back(Pair("name",str));
for (i=0; i<maxsamples; i++)
{
UniValue prices(UniValue::VARR);
prices.push_back((double)prices[j]/10000.);
prices.push_back((double)correlated[j]/10000.);
prices.push_back((double)smoothed[j]/10000.);
parr.push_back(prices);
offset = j*(maxsamples+daywindow) + i;
smoothed[offset] = komodo_pricesmoothed(&correlated[offset],&rawprices[offset],daywindow);
UniValue parr(UniValue::VARR);
parr.push_back((double)prices[offset]/10000.);
parr.push_back((double)correlated[offset]/10000.);
parr.push_back((double)smoothed[offset]/10000.);
prices.push_back(parr);
}
item.push_back(Pair("prices",parr));
item.push_back(Pair("numprices",n));
a.push_back(item);
num++;
}
}*/
ret.push_back(Pair("array",a));
item.push_back(Pair("prices",prices));
} else item.push_back(Pair("name","error"));
a.push_back(item);
}
ret.push_back(Pair("pricefeeds",a));
ret.push_back(Pair("result","success"));
ret.push_back(Pair("height",(int64_t)nextheight-1));
ret.push_back(Pair("numsamples",(int64_t)num));
ret.push_back(Pair("numsamples",(int64_t)firstn));
ret.push_back(Pair("maxsamples",(int64_t)maxsamples));
free(prices);
free(correlated);
free(smoothed);
return ret;
}

Loading…
Cancel
Save