KOMODO_LOCALPRICE_CACHESIZE

This commit is contained in:
jl777
2019-04-02 00:08:01 -11:00
parent c90448edba
commit 50f79c5d4a
4 changed files with 187 additions and 79 deletions

View File

@@ -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)
{
}