Oracle Fix
- Reorder vins so that only one normal vin is before CC vin - Fixed AddOracleInputs to add utxos only from that oracle - Fixed sharing funds from all oracles for that pubkey in OraclesInfo
This commit is contained in:
committed by
GitHub
parent
a1f6cb8019
commit
e288ce42f6
@@ -40,7 +40,10 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
|
|||||||
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
|
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
|
||||||
{
|
{
|
||||||
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||||
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*othercond3=0,*cond; CPubKey unspendablepk;
|
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0;
|
||||||
|
int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0,normalvins=0,ccvins=0;
|
||||||
|
int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64];
|
||||||
|
uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*othercond3=0,*cond; CPubKey unspendablepk;
|
||||||
n = mtx.vout.size();
|
n = mtx.vout.size();
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
@@ -71,11 +74,13 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
|||||||
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 )
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"vin.%d is normal %.8f\n",i,(double)utxovalues[i]/COIN);
|
//fprintf(stderr,"vin.%d is normal %.8f\n",i,(double)utxovalues[i]/COIN);
|
||||||
|
if (ccvins==0) normalvins++;
|
||||||
normalinputs += utxovalues[i];
|
normalinputs += utxovalues[i];
|
||||||
vinimask |= (1LL << i);
|
vinimask |= (1LL << i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ccvins++;
|
||||||
mask |= (1LL << i);
|
mask |= (1LL << i);
|
||||||
}
|
}
|
||||||
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
|
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
|
||||||
@@ -92,6 +97,16 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
|||||||
mtx.vout.push_back(CTxOut(0,opret));
|
mtx.vout.push_back(CTxOut(0,opret));
|
||||||
PrecomputedTransactionData txdata(mtx);
|
PrecomputedTransactionData txdata(mtx);
|
||||||
n = mtx.vin.size();
|
n = mtx.vin.size();
|
||||||
|
//Reorder vins so that for multiple normal vins all other except vin0 goes to the end
|
||||||
|
//This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation.
|
||||||
|
if (normalvins>1)
|
||||||
|
{
|
||||||
|
for(i=1;i<normalvins;i++)
|
||||||
|
{
|
||||||
|
mtx.vin.push_back(mtx.vin[1]);
|
||||||
|
mtx.vin.erase(mtx.vin.begin() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (i=0; i<n; i++)
|
for (i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
|
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
|
||||||
|
|||||||
@@ -133,10 +133,11 @@ uint8_t DecodeOraclesOpRet(const CScript &scriptPubKey,uint256 &oracletxid,CPubK
|
|||||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||||
GetOpReturnData(scriptPubKey,vopret);
|
GetOpReturnData(scriptPubKey,vopret);
|
||||||
script = (uint8_t *)vopret.data();
|
script = (uint8_t *)vopret.data();
|
||||||
if ( vopret.size() > 1 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> oracletxid; ss >> pk; ss >> num) != 0 )
|
if ( vopret.size() > 1 && script[0] == EVAL_ORACLES )
|
||||||
{
|
{
|
||||||
if ( e == EVAL_ORACLES && (f == 'R' || f == 'S') )
|
if (script[0] == EVAL_ORACLES && (script[1]== 'R' || script[1] == 'S') && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> oracletxid; ss >> pk; ss >> num)!=0)
|
||||||
return(f);
|
return(f);
|
||||||
|
else return(script[1]);
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@@ -567,9 +568,6 @@ bool OraclesDataValidate(struct CCcontract_info *cp,Eval* eval,const CTransactio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( i != 0 )
|
|
||||||
return eval->Invalid("vin0 not normal");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
for (i=0; i<numvouts; i++)
|
for (i=0; i<numvouts; i++)
|
||||||
{
|
{
|
||||||
@@ -665,10 +663,10 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
|
|||||||
|
|
||||||
// helper functions for rpc calls in rpcwallet.cpp
|
// helper functions for rpc calls in rpcwallet.cpp
|
||||||
|
|
||||||
int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,uint256 oracletxid,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
|
char coinaddr[64],funcid; int64_t nValue,price,totalinputs = 0; uint256 tmporacletxid,tmpbatontxid,txid,hashBlock; std::vector<uint8_t> origpubkey,data; CTransaction vintx; int32_t numvouts,vout,n = 0;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; CPubKey tmppk; int64_t tmpnum;
|
||||||
GetCCaddress(cp,coinaddr,pk);
|
GetCCaddress(cp,coinaddr,pk);
|
||||||
SetCCunspents(unspentOutputs,coinaddr);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
//fprintf(stderr,"addoracleinputs from (%s)\n",coinaddr);
|
//fprintf(stderr,"addoracleinputs from (%s)\n",coinaddr);
|
||||||
@@ -677,19 +675,27 @@ int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
|||||||
txid = it->first.txhash;
|
txid = it->first.txhash;
|
||||||
vout = (int32_t)it->first.index;
|
vout = (int32_t)it->first.index;
|
||||||
//char str[65]; fprintf(stderr,"oracle check %s/v%d\n",uint256_str(str,txid),vout);
|
//char str[65]; fprintf(stderr,"oracle check %s/v%d\n",uint256_str(str,txid),vout);
|
||||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts=vintx.vout.size()-1)>0)
|
||||||
{
|
{
|
||||||
// get valid CC payments
|
if ((funcid=DecodeOraclesOpRet(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmppk,tmpnum))!=0 && (funcid=='S' || funcid=='D'))
|
||||||
if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
|
||||||
{
|
{
|
||||||
if ( total != 0 && maxinputs != 0 )
|
if (funcid=='D' && DecodeOraclesData(vintx.vout[numvouts].scriptPubKey,tmporacletxid,tmpbatontxid,tmppk,data)==0)
|
||||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
fprintf(stderr,"invalid oraclesdata transaction \n");
|
||||||
nValue = it->second.satoshis;
|
else if (tmporacletxid==oracletxid)
|
||||||
totalinputs += nValue;
|
{
|
||||||
n++;
|
// get valid CC payments
|
||||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
|
||||||
break;
|
{
|
||||||
} //else fprintf(stderr,"nValue %.8f or utxo memspent\n",(double)nValue/COIN);
|
if ( total != 0 && maxinputs != 0 )
|
||||||
|
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||||
|
nValue = it->second.satoshis;
|
||||||
|
totalinputs += nValue;
|
||||||
|
n++;
|
||||||
|
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||||
|
break;
|
||||||
|
} //else fprintf(stderr,"nValue %.8f or utxo memspent\n",(double)nValue/COIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else fprintf(stderr,"couldnt find transaction\n");
|
} else fprintf(stderr,"couldnt find transaction\n");
|
||||||
}
|
}
|
||||||
return(totalinputs);
|
return(totalinputs);
|
||||||
@@ -802,7 +808,7 @@ std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector <uint8_t> da
|
|||||||
if ( batontxid != zeroid ) // not impossible to fail, but hopefully a very rare event
|
if ( batontxid != zeroid ) // not impossible to fail, but hopefully a very rare event
|
||||||
mtx.vin.push_back(CTxIn(batontxid,1,CScript()));
|
mtx.vin.push_back(CTxIn(batontxid,1,CScript()));
|
||||||
else fprintf(stderr,"warning: couldnt find baton utxo %s\n",batonaddr);
|
else fprintf(stderr,"warning: couldnt find baton utxo %s\n",batonaddr);
|
||||||
if ( (inputs= AddOracleInputs(cp,mtx,mypk,datafee,60)) > 0 )
|
if ( (inputs= AddOracleInputs(cp,mtx,oracletxid,mypk,datafee,60)) > 0 )
|
||||||
{
|
{
|
||||||
if ( inputs > datafee )
|
if ( inputs > datafee )
|
||||||
CCchange = (inputs - datafee);
|
CCchange = (inputs - datafee);
|
||||||
@@ -898,7 +904,7 @@ UniValue OracleInfo(uint256 origtxid)
|
|||||||
funding = LifetimeOraclesFunds(cp,oracletxid,pk);
|
funding = LifetimeOraclesFunds(cp,oracletxid,pk);
|
||||||
sprintf(numstr,"%.8f",(double)funding/COIN);
|
sprintf(numstr,"%.8f",(double)funding/COIN);
|
||||||
obj.push_back(Pair("lifetime",numstr));
|
obj.push_back(Pair("lifetime",numstr));
|
||||||
funding = AddOracleInputs(cp,mtx,pk,0,0);
|
funding = AddOracleInputs(cp,mtx,oracletxid,pk,0,0);
|
||||||
sprintf(numstr,"%.8f",(double)funding/COIN);
|
sprintf(numstr,"%.8f",(double)funding/COIN);
|
||||||
obj.push_back(Pair("funds",numstr));
|
obj.push_back(Pair("funds",numstr));
|
||||||
sprintf(numstr,"%.8f",(double)datafee/COIN);
|
sprintf(numstr,"%.8f",(double)datafee/COIN);
|
||||||
|
|||||||
Reference in New Issue
Block a user