smart utxo selection without press release to coin telegraph
This commit is contained in:
@@ -33,6 +33,13 @@
|
|||||||
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; };
|
||||||
typedef union _bits256 bits256;
|
typedef union _bits256 bits256;
|
||||||
|
|
||||||
|
struct CC_utxo
|
||||||
|
{
|
||||||
|
uint256 txid;
|
||||||
|
int64_t nValue;
|
||||||
|
int32_t vout;
|
||||||
|
};
|
||||||
|
|
||||||
struct CCcontract_info
|
struct CCcontract_info
|
||||||
{
|
{
|
||||||
uint256 prevtxid;
|
uint256 prevtxid;
|
||||||
|
|||||||
@@ -201,36 +201,124 @@ uint64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct CC_utxo utxos[],int32_t numunspents,uint64_t value)
|
||||||
|
{
|
||||||
|
int32_t i,abovei,belowi; int64_t above,below,gap,atx_value;
|
||||||
|
abovei = belowi = -1;
|
||||||
|
for (above=below=i=0; i<numunspents; i++)
|
||||||
|
{
|
||||||
|
if ( (atx_value= utxos[i].nValue) <= 0 )
|
||||||
|
continue;
|
||||||
|
if ( atx_value == value )
|
||||||
|
{
|
||||||
|
*aboveip = *belowip = i;
|
||||||
|
*abovep = *belowp = 0;
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
else if ( atx_value > value )
|
||||||
|
{
|
||||||
|
gap = (atx_value - value);
|
||||||
|
if ( above == 0 || gap < above )
|
||||||
|
{
|
||||||
|
above = gap;
|
||||||
|
abovei = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gap = (value - atx_value);
|
||||||
|
if ( below == 0 || gap < below )
|
||||||
|
{
|
||||||
|
below = gap;
|
||||||
|
belowi = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below));
|
||||||
|
}
|
||||||
|
*aboveip = abovei;
|
||||||
|
*abovep = above;
|
||||||
|
*belowip = belowi;
|
||||||
|
*belowp = below;
|
||||||
|
//printf("above.%d below.%d\n",abovei,belowi);
|
||||||
|
if ( abovei >= 0 && belowi >= 0 )
|
||||||
|
{
|
||||||
|
if ( above < (below >> 1) )
|
||||||
|
return(abovei);
|
||||||
|
else return(belowi);
|
||||||
|
}
|
||||||
|
else if ( abovei >= 0 )
|
||||||
|
return(abovei);
|
||||||
|
else return(belowi);
|
||||||
|
//return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs)
|
uint64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,uint64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
int32_t vout,j,n = 0; uint64_t nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx;
|
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=1024; int64_t above,below; uint64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
assert(pwalletMain != NULL);
|
assert(pwalletMain != NULL);
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
|
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
|
||||||
|
utxos = calloc(maxutxos,sizeof(*utxos));
|
||||||
BOOST_FOREACH(const COutput& out, vecOutputs)
|
BOOST_FOREACH(const COutput& out, vecOutputs)
|
||||||
{
|
{
|
||||||
if ( out.fSpendable != 0 )
|
if ( out.fSpendable != 0 )
|
||||||
{
|
{
|
||||||
txid = out.tx->GetHash();
|
txid = out.tx->GetHash();
|
||||||
vout = out.i;
|
vout = out.i;
|
||||||
for (j=0; j<mtx.vin.size(); j++)
|
for (i=0; i<mtx.vin.size(); i++)
|
||||||
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
|
if ( txid == mtx.vin[i].prevout.hash && vout == mtx.vin[i].prevout.n )
|
||||||
break;
|
break;
|
||||||
if ( j != mtx.vin.size() )
|
if ( i != mtx.vin.size() )
|
||||||
continue;
|
continue;
|
||||||
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
|
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||||
{
|
{
|
||||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
up = &utxos[n++];
|
||||||
|
up->txid = txid;
|
||||||
|
up->nValue = out.tx->vout[out.i].nValue;
|
||||||
|
up->vout = vout;
|
||||||
|
/*mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||||
nValue = out.tx->vout[out.i].nValue;
|
nValue = out.tx->vout[out.i].nValue;
|
||||||
totalinputs += nValue;
|
totalinputs += nValue;
|
||||||
n++;
|
n++;
|
||||||
if ( totalinputs >= total || n >= maxinputs )
|
if ( totalinputs >= total || n >= maxinputs )
|
||||||
|
break;*/
|
||||||
|
if ( n >= maxutxos )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
remains = total;
|
||||||
|
for (i=0; i<maxinputs; 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,numunspents,dstr(remains),dstr(amount));
|
||||||
|
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,numunspents,dstr(remains),dstr(amount),abovei,belowi,ind);
|
||||||
|
free(utxos);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
up = utxos[ind];
|
||||||
|
utxos[ind] = utxos[--n];
|
||||||
|
memset(&utxos[n],0,sizeof(utxos[n]));
|
||||||
|
mtx.vin.push_back(CTxIn(up->txid,up->vout,CScript()));
|
||||||
|
totalinputs += up->nValue;
|
||||||
|
remains -= up->nValue;
|
||||||
|
if ( totalinputs >= total || (i+1) >= maxinputs )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(utxos);
|
||||||
if ( totalinputs >= total )
|
if ( totalinputs >= total )
|
||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp
|
|||||||
if ( (retval= ptr->valuesize) > 0 )
|
if ( (retval= ptr->valuesize) > 0 )
|
||||||
memcpy(value,ptr->value,retval);
|
memcpy(value,ptr->value,retval);
|
||||||
}
|
}
|
||||||
} else fprintf(stderr,"couldnt find (%s)\n",(char *)key);
|
} //else fprintf(stderr,"couldnt find (%s)\n",(char *)key);
|
||||||
portable_mutex_unlock(&KOMODO_KV_mutex);
|
portable_mutex_unlock(&KOMODO_KV_mutex);
|
||||||
if ( retval < 0 )
|
if ( retval < 0 )
|
||||||
{
|
{
|
||||||
@@ -172,7 +172,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value)
|
|||||||
memcpy(ptr->key,key,keylen);
|
memcpy(ptr->key,key,keylen);
|
||||||
newflag = 1;
|
newflag = 1;
|
||||||
HASH_ADD_KEYPTR(hh,KOMODO_KV,ptr->key,ptr->keylen,ptr);
|
HASH_ADD_KEYPTR(hh,KOMODO_KV,ptr->key,ptr->keylen,ptr);
|
||||||
fprintf(stderr,"KV add.(%s) (%s)\n",ptr->key,valueptr);
|
//fprintf(stderr,"KV add.(%s) (%s)\n",ptr->key,valueptr);
|
||||||
}
|
}
|
||||||
if ( newflag != 0 || (ptr->flags & KOMODO_KVPROTECTED) == 0 )
|
if ( newflag != 0 || (ptr->flags & KOMODO_KVPROTECTED) == 0 )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user