Merge branch 'FSM' of https://github.com/jl777/komodo into jl777-FSM
fix
This commit is contained in:
@@ -24,10 +24,11 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
|||||||
std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys);
|
std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys);
|
||||||
std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vector<uint8_t>proof,CPubKey destpub,int64_t amount);
|
std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vector<uint8_t>proof,CPubKey destpub,int64_t amount);
|
||||||
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
|
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
|
||||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount);
|
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount);
|
||||||
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
|
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
|
||||||
std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid);
|
std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid);
|
||||||
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr);
|
UniValue GatewaysMultisig(char *txidaddr);
|
||||||
|
std::string GatewaysPartialSign(uint64_t txfee,uint256 txidaddr,std::string refcoin, std::string hex);
|
||||||
|
|
||||||
// CCcustom
|
// CCcustom
|
||||||
UniValue GatewaysInfo(uint256 bindtxid);
|
UniValue GatewaysInfo(uint256 bindtxid);
|
||||||
|
|||||||
@@ -276,10 +276,11 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
|
|||||||
abovei = belowi = -1;
|
abovei = belowi = -1;
|
||||||
for (above=below=i=0; i<numunspents; i++)
|
for (above=below=i=0; i<numunspents; i++)
|
||||||
{
|
{
|
||||||
if ( numunspents > 150 ) {
|
// Filter to randomly pick utxo to avoid conflicts, and having multiple CC choose the same ones.
|
||||||
if ( (rand() % 100) < 80 )
|
//if ( numunspents > 500 ) {
|
||||||
continue;
|
// if ( (rand() % 100) < 80 )
|
||||||
}
|
// continue;
|
||||||
|
//}
|
||||||
if ( (atx_value= utxos[i].nValue) <= 0 )
|
if ( (atx_value= utxos[i].nValue) <= 0 )
|
||||||
continue;
|
continue;
|
||||||
if ( atx_value == value )
|
if ( atx_value == value )
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
|
|||||||
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
|
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"ExtractDestination failed\n");
|
//fprintf(stderr,"ExtractDestination failed\n");
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ Possible third iteration:
|
|||||||
|
|
||||||
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub, CPubKey destpub,int32_t v)
|
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub, CPubKey destpub,int32_t v)
|
||||||
{
|
{
|
||||||
char destaddr[64],channeladdr[64];
|
char destaddr[65],channeladdr[65];
|
||||||
|
|
||||||
GetCCaddress1of2(cp,channeladdr,srcpub,destpub);
|
GetCCaddress1of2(cp,channeladdr,srcpub,destpub);
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -77,7 +77,7 @@ int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey
|
|||||||
|
|
||||||
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
|
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
|
||||||
{
|
{
|
||||||
char destaddr[64],ccaddr[64];
|
char destaddr[65],ccaddr[65];
|
||||||
|
|
||||||
GetCCaddress(cp,ccaddr,srcpub);
|
GetCCaddress(cp,ccaddr,srcpub);
|
||||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||||
@@ -364,7 +364,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
|||||||
|
|
||||||
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, CTransaction openTx, uint256 &prevtxid)
|
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, CTransaction openTx, uint256 &prevtxid)
|
||||||
{
|
{
|
||||||
char coinaddr[64]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
|
char coinaddr[65]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
CPubKey srcpub,destpub;
|
CPubKey srcpub,destpub;
|
||||||
uint8_t myprivkey[32];
|
uint8_t myprivkey[32];
|
||||||
@@ -692,7 +692,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
|
|||||||
UniValue ChannelsInfo(uint256 channeltxid)
|
UniValue ChannelsInfo(uint256 channeltxid)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid;
|
UniValue result(UniValue::VOBJ); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid;
|
||||||
struct CCcontract_info *cp,C; char myCCaddr[64],addr[64],str1[256],str2[64]; int32_t vout,numvouts,param1,numpayments;
|
struct CCcontract_info *cp,C; char myCCaddr[65],addr[65],str1[256],str2[256]; int32_t vout,numvouts,param1,numpayments;
|
||||||
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
|
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
|
||||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include "cJSON.c"
|
#include "cJSON.c"
|
||||||
|
|
||||||
|
bits256 zeroid;
|
||||||
|
|
||||||
char hexbyte(int32_t c)
|
char hexbyte(int32_t c)
|
||||||
{
|
{
|
||||||
c &= 0xf;
|
c &= 0xf;
|
||||||
@@ -139,7 +141,7 @@ long _stripwhite(char *buf,int accept)
|
|||||||
char *clonestr(char *str)
|
char *clonestr(char *str)
|
||||||
{
|
{
|
||||||
char *clone;
|
char *clone;
|
||||||
if ( str == 0 || str[0] == 0 )
|
if ( str == 0 || str[0]==0)
|
||||||
{
|
{
|
||||||
printf("warning cloning nullstr.%p\n",str);
|
printf("warning cloning nullstr.%p\n",str);
|
||||||
//#ifdef __APPLE__
|
//#ifdef __APPLE__
|
||||||
@@ -331,6 +333,7 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char
|
|||||||
*retstrp = 0;
|
*retstrp = 0;
|
||||||
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
|
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
|
||||||
{
|
{
|
||||||
|
jsonstr[strlen(jsonstr)-1]='\0';
|
||||||
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
|
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
|
||||||
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
|
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
|
||||||
*retstrp = jsonstr;
|
*retstrp = jsonstr;
|
||||||
@@ -357,7 +360,7 @@ bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson)
|
|||||||
retstr[64] = 0;
|
retstr[64] = 0;
|
||||||
decode_hex(txid.bytes,32,retstr);
|
decode_hex(txid.bytes,32,retstr);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"broadcast %s txid.(%s)\n",acname,bits256_str(str,txid));
|
fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid));
|
||||||
free(retstr);
|
free(retstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,6 +533,23 @@ cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare)
|
||||||
|
{
|
||||||
|
cJSON *retjson; char *retstr; int32_t res=0;
|
||||||
|
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 )
|
||||||
|
{
|
||||||
|
if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1;
|
||||||
|
free_json(retjson);
|
||||||
|
}
|
||||||
|
else if ( retstr != 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||||
|
free(retstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
void importaddress(char *refcoin,char *acname,char *depositaddr)
|
void importaddress(char *refcoin,char *acname,char *depositaddr)
|
||||||
{
|
{
|
||||||
cJSON *retjson; char *retstr;
|
cJSON *retjson; char *retstr;
|
||||||
@@ -545,6 +565,24 @@ void importaddress(char *refcoin,char *acname,char *depositaddr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys,char *bindtxidstr)
|
||||||
|
{
|
||||||
|
cJSON *retjson; char *retstr,Mstr[10],tmp[128];
|
||||||
|
|
||||||
|
sprintf(Mstr,"%d",M);
|
||||||
|
sprintf(tmp,"\"%s\"",bindtxidstr);
|
||||||
|
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"addmultisigaddress",Mstr,pubkeys,tmp,"")) != 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"unexpected addmultisigaddress json.(%s)\n",jprint(retjson,0));
|
||||||
|
free(retstr);
|
||||||
|
}
|
||||||
|
else if ( retstr != 0 )
|
||||||
|
{
|
||||||
|
printf("addmultisigaddress.(%s)\n",retstr);
|
||||||
|
free_json(retjson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required)
|
cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required)
|
||||||
{
|
{
|
||||||
cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid;
|
cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid;
|
||||||
@@ -584,7 +622,7 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
satoshis -= txfee;
|
satoshis -= txfee;
|
||||||
sprintf(array,"[\"%s\"]",depositaddr);
|
sprintf(array,"\'[\"%s\"]\'",depositaddr);
|
||||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 )
|
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 )
|
||||||
{
|
{
|
||||||
//createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
|
//createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
|
||||||
@@ -599,9 +637,12 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
|||||||
change = (total - satoshis);
|
change = (total - satoshis);
|
||||||
jaddnum(vouts,depositaddr,(double)change/SATOSHIDEN);
|
jaddnum(vouts,depositaddr,(double)change/SATOSHIDEN);
|
||||||
}
|
}
|
||||||
char *argA,*argB;
|
char *tmpA=jprint(vins,1);
|
||||||
argA = jprint(vins,1);
|
char *tmpB=jprint(vouts,1);
|
||||||
argB = jprint(vouts,1);
|
char *argA=malloc(sizeof(char) * (strlen(tmpA)+3));
|
||||||
|
char *argB=malloc(sizeof(char) * (strlen(tmpB)+3));
|
||||||
|
sprintf(argA,"\'%s\'",tmpA);
|
||||||
|
sprintf(argB,"\'%s\'",tmpB);
|
||||||
if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
|
if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
|
||||||
{
|
{
|
||||||
printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0));
|
printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0));
|
||||||
@@ -609,10 +650,13 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
|||||||
}
|
}
|
||||||
else if ( txstr == 0 )
|
else if ( txstr == 0 )
|
||||||
printf("createmultisig: null txstr and JSON2\n");
|
printf("createmultisig: null txstr and JSON2\n");
|
||||||
|
free(tmpA);
|
||||||
|
free(tmpB);
|
||||||
free(argA);
|
free(argA);
|
||||||
free(argB);
|
free(argB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free_json(retjson);
|
||||||
}
|
}
|
||||||
else if ( retstr != 0 )
|
else if ( retstr != 0 )
|
||||||
{
|
{
|
||||||
@@ -628,7 +672,7 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
|
|||||||
char *retstr,*hexstr; cJSON *retjson;
|
char *retstr,*hexstr; cJSON *retjson;
|
||||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 )
|
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 )
|
||||||
{
|
{
|
||||||
if ( jint(retjson,"complete") != 0 )
|
if ( is_cJSON_True(jobj(retjson,"complete")) != 0 )
|
||||||
return(retjson);
|
return(retjson);
|
||||||
else if ( (hexstr= jstr(retjson,"hex")) != 0 && strlen(hexstr) > strlen(rawtx) )
|
else if ( (hexstr= jstr(retjson,"hex")) != 0 && strlen(hexstr) > strlen(rawtx) )
|
||||||
{
|
{
|
||||||
@@ -640,18 +684,36 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_gatewaysmultisig(char *refcoin,char *acname,char *bindtxidstr,char *withtxidstr,char *txidaddr)
|
char *get_gatewaysmultisig(char *refcoin,char *acname,char *txidaddr,int32_t *K)
|
||||||
{
|
{
|
||||||
char *retstr,*hexstr,*hex=0; cJSON *retjson;
|
char *retstr,*hexstr,*hex=0; cJSON *retjson;
|
||||||
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",bindtxidstr,refcoin,withtxidstr,txidaddr)) != 0 )
|
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",txidaddr,"","","")) != 0 )
|
||||||
{
|
{
|
||||||
if ( (hexstr= jstr(retjson,"hex")) != 0 )
|
if ((hexstr=jstr(retjson,"hex")) != 0 )
|
||||||
hex = clonestr(hexstr);
|
{
|
||||||
|
if (strlen(hexstr)>0) hex = clonestr(hexstr);
|
||||||
|
}
|
||||||
|
*K=jint(retjson,"number_of_signs");
|
||||||
free_json(retjson);
|
free_json(retjson);
|
||||||
}
|
}
|
||||||
return(hex);
|
return(hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *hex)
|
||||||
|
{
|
||||||
|
char str[65],*retstr; cJSON *retjson;
|
||||||
|
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspartialsign",bits256_str(str,txid),refcoin,hex,"")) != 0 )
|
||||||
|
{
|
||||||
|
return(komodobroadcast(refcoin,acname,retjson));
|
||||||
|
}
|
||||||
|
else if ( retstr != 0 )
|
||||||
|
{
|
||||||
|
printf("error parsing gatewayspartialsing.(%s)\n",retstr);
|
||||||
|
free(retstr);
|
||||||
|
}
|
||||||
|
return (zeroid);
|
||||||
|
}
|
||||||
|
|
||||||
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid)
|
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid)
|
||||||
{
|
{
|
||||||
char str[65],str2[65],*retstr; cJSON *retjson;
|
char str[65],str2[65],*retstr; cJSON *retjson;
|
||||||
@@ -668,9 +730,9 @@ void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr)
|
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr, char **pubkeys)
|
||||||
{
|
{
|
||||||
char *oracle,*retstr,*name,*deposit; cJSON *retjson;
|
char *oracle,*retstr,*name,*deposit,temp[128]; cJSON *retjson,*pubarray; int32_t n;
|
||||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 )
|
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 )
|
||||||
{
|
{
|
||||||
if ( (oracle= jstr(retjson,"oracletxid")) != 0 && strcmp(oracle,oraclestr) == 0 && (deposit= jstr(retjson,"deposit")) != 0 )
|
if ( (oracle= jstr(retjson,"oracletxid")) != 0 && strcmp(oracle,oraclestr) == 0 && (deposit= jstr(retjson,"deposit")) != 0 )
|
||||||
@@ -680,9 +742,23 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
|
|||||||
{
|
{
|
||||||
*Mp = jint(retjson,"M");
|
*Mp = jint(retjson,"M");
|
||||||
*Np = jint(retjson,"N");
|
*Np = jint(retjson,"N");
|
||||||
//printf("(%s)\n",jprint(retjson,0));
|
}
|
||||||
} else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
|
else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
|
||||||
} else printf("%s != %s\n",oracle,oraclestr);
|
if ((pubarray=jarray(&n,retjson,"pubkeys"))!=0)
|
||||||
|
{
|
||||||
|
*pubkeys=malloc((sizeof(char)*70*n)+64);
|
||||||
|
sprintf(*pubkeys,"\"[");
|
||||||
|
for (int i=0;i<n;i++)
|
||||||
|
{
|
||||||
|
sprintf(temp,"\\\"%s\\\"",jstri(pubarray,i));
|
||||||
|
if (i<n-1) strcat(temp,",");
|
||||||
|
strcat(*pubkeys,temp);
|
||||||
|
}
|
||||||
|
sprintf(temp,"]\"");
|
||||||
|
strcat(*pubkeys,temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else printf("%s != %s\n",oracle,oraclestr);
|
||||||
free_json(retjson);
|
free_json(retjson);
|
||||||
}
|
}
|
||||||
else if ( retstr != 0 )
|
else if ( retstr != 0 )
|
||||||
@@ -697,15 +773,14 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
|
|||||||
|
|
||||||
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
|
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
|
||||||
{
|
{
|
||||||
cJSON *txobj,*vouts,*vout,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numvouts,retval = 0;
|
cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0;
|
||||||
if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 )
|
if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 )
|
||||||
{
|
{
|
||||||
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 )
|
if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 )
|
||||||
{
|
{
|
||||||
for (i=0; i<numvouts; i++)
|
for (i=0; i<numarray; i++)
|
||||||
{
|
{
|
||||||
vout = jitem(vouts,i);
|
if ((vout = jitem(vouts,i)) !=0 && (sobj= jobj(vout,"scriptPubKey")) != 0 )
|
||||||
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 )
|
|
||||||
{
|
{
|
||||||
if ( (addresses= jarray(&n,sobj,"addresses")) != 0 )
|
if ( (addresses= jarray(&n,sobj,"addresses")) != 0 )
|
||||||
{
|
{
|
||||||
@@ -715,26 +790,55 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd
|
|||||||
if ( strcmp(addr,coinaddr) == 0 )
|
if ( strcmp(addr,coinaddr) == 0 )
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
|
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
|
||||||
retval = 1;
|
hasvout = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasvout==1) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if (hasvout==1 && (vins=jarray(&numarray,txobj,"vin"))!=0)
|
||||||
|
// {
|
||||||
|
// for (int i=0;i<numarray;i++)
|
||||||
|
// {
|
||||||
|
// if ((vin=jitem(vins,i))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
|
||||||
|
// {
|
||||||
|
// retval=1;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
free_json(txobj);
|
free_json(txobj);
|
||||||
}
|
}
|
||||||
return(retval);
|
return(hasvout);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t coinaddrexists(char *refcoin,char *acname,char *coinaddr)
|
int32_t markerfromthisnodeorunconfirmed(char *refcoin,char *acname,char *coinaddr)
|
||||||
{
|
{
|
||||||
cJSON *array; bits256 txid; int32_t i,n,num=0;
|
cJSON *array,*item,*rawtx,*vins,*vin; bits256 txid,tmptxid; int32_t i,n,m,num=0; char *retstr;
|
||||||
if ( (array= get_addressutxos(refcoin,acname,coinaddr)) != 0 )
|
if ( (array= get_addressutxos(refcoin,acname,coinaddr)) != 0 )
|
||||||
{
|
{
|
||||||
num = cJSON_GetArraySize(array);
|
n=cJSON_GetArraySize(array);
|
||||||
|
for (i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
if ((item=jitem(array,i))!=0 && (bits256_nonz(tmptxid=jbits256(item,"txid")))!=0 && (rawtx=get_rawtransaction(refcoin,acname,tmptxid))!=0 && (vins=jarray(&m,rawtx,"vin"))!=0)
|
||||||
|
{
|
||||||
|
for (int j=0;j<m;j++)
|
||||||
|
{
|
||||||
|
if ((vin=jitem(vins,j))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
|
||||||
|
{
|
||||||
|
num=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num==1) break;
|
||||||
|
}
|
||||||
free_json(array);
|
free_json(array);
|
||||||
} else return(-1);
|
}
|
||||||
|
else return(-1);
|
||||||
if ( num == 0 )
|
if ( num == 0 )
|
||||||
{
|
{
|
||||||
if ( (array= get_rawmempool(refcoin,acname)) != 0 )
|
if ( (array= get_rawmempool(refcoin,acname)) != 0 )
|
||||||
@@ -766,7 +870,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
|||||||
/// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
|
/// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
|
||||||
/// if not enough sigs, post partially signed to acname with marker2
|
/// if not enough sigs, post partially signed to acname with marker2
|
||||||
// monitor marker2, for the partially signed withdraws
|
// monitor marker2, for the partially signed withdraws
|
||||||
cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,retval,processed = 0; bits256 txid,cointxid,origtxid,zeroid; int64_t satoshis;
|
cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,K,retval,processed = 0; bits256 txid,cointxid,origtxid; int64_t satoshis;
|
||||||
memset(&zeroid,0,sizeof(zeroid));
|
memset(&zeroid,0,sizeof(zeroid));
|
||||||
if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 )
|
if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 )
|
||||||
{
|
{
|
||||||
@@ -783,17 +887,16 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
|||||||
//process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
|
//process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
|
||||||
if ( (txidaddr= jstr(item,"txidaddr")) != 0 && (withdrawaddr= jstr(item,"withdrawaddr")) != 0 && (depositaddr= jstr(item,"depositaddr")) != 0 && (signeraddr= jstr(item,"signeraddr")) != 0 )
|
if ( (txidaddr= jstr(item,"txidaddr")) != 0 && (withdrawaddr= jstr(item,"withdrawaddr")) != 0 && (depositaddr= jstr(item,"depositaddr")) != 0 && (signeraddr= jstr(item,"signeraddr")) != 0 )
|
||||||
{
|
{
|
||||||
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && (retval= coinaddrexists("KMD",acname,txidaddr)) == 0 )
|
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && markerfromthisnodeorunconfirmed("KMD",acname,txidaddr) == 0)
|
||||||
{
|
{
|
||||||
// this is less errors but more expensive: ./komodo-cli z_sendmany "signeraddr" '[{"address":"<txidaddr>","amount":0.0001},{"address":"<withdrawaddr>","amount":<withamount>}]'
|
// the actual withdraw
|
||||||
txid = sendtoaddress("KMD",acname,txidaddr,10000);
|
if ( strcmp(depositaddr,signeraddr) == 0 )
|
||||||
if ( bits256_nonz(txid) != 0 && coinaddrexists("KMD",acname,txidaddr) > 0 )
|
|
||||||
{
|
{
|
||||||
// the actual withdraw
|
txid= sendtoaddress("KMD",acname,txidaddr,10000);
|
||||||
if ( strcmp(depositaddr,signeraddr) == 0 )
|
if (bits256_nonz(txid) != 0)
|
||||||
{
|
{
|
||||||
cointxid = sendtoaddress(refcoin,"",withdrawaddr,satoshis);
|
cointxid = sendtoaddress(refcoin,"",withdrawaddr,satoshis);
|
||||||
if ( bits256_nonz(cointxid) != 0 )
|
if ( bits256_nonz(cointxid) != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
fprintf(stderr,"withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
||||||
@@ -806,41 +909,39 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,bindtxidstr,bits256_str(str,origtxid),txidaddr)) == 0 )
|
fprintf(stderr,"ERROR sending withdraw marker %s %s to %s %.8f processed\n",refcoin,bits256_str(str,cointxid),txidaddr,(double)10000/SATOSHIDEN);
|
||||||
{
|
|
||||||
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
|
|
||||||
}
|
|
||||||
if ( rawtx != 0 )
|
|
||||||
{
|
|
||||||
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
|
|
||||||
{
|
|
||||||
if ( jint(clijson,"complete") != 0 )
|
|
||||||
{
|
|
||||||
cointxid = komodobroadcast(refcoin,"",clijson);
|
|
||||||
if ( bits256_nonz(cointxid) != 0 )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
|
||||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( jint(clijson,"partialtx") != 0 )
|
|
||||||
{
|
|
||||||
// 10000 + ith -> txidaddr
|
|
||||||
txid = komodobroadcast("KMD",acname,clijson);
|
|
||||||
fprintf(stderr,"%s M.%d of N.%d partialtx %s sent\n",refcoin,M,N,bits256_str(str,txid));
|
|
||||||
}
|
|
||||||
free_json(clijson);
|
|
||||||
}
|
|
||||||
processed++;
|
|
||||||
free(rawtx);
|
|
||||||
} else fprintf(stderr,"couldnt create msig rawtx\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if ( retval > 0 )
|
{
|
||||||
{
|
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,txidaddr,&K)) == 0)
|
||||||
fprintf(stderr,"already did withdraw %s %s %.8f processed\n",refcoin,withdrawaddr,(double)satoshis/SATOSHIDEN);
|
{
|
||||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,zeroid);
|
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
|
||||||
|
}
|
||||||
|
if ( rawtx != 0 )
|
||||||
|
{
|
||||||
|
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
|
||||||
|
{
|
||||||
|
if ( is_cJSON_True(jobj(clijson,"complete")) != 0 )
|
||||||
|
{
|
||||||
|
cointxid = komodobroadcast(refcoin,"",clijson);
|
||||||
|
if ( bits256_nonz(cointxid) != 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||||
|
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( jint(clijson,"partialtx") != 0 )
|
||||||
|
{
|
||||||
|
txid=gatewayspartialsign(refcoin,acname,origtxid,jstr(clijson,"hex"));
|
||||||
|
fprintf(stderr,"%d of %d partialtx %s sent\n",K+1,N,bits256_str(str,txid));
|
||||||
|
}
|
||||||
|
free_json(clijson);
|
||||||
|
}
|
||||||
|
processed++;
|
||||||
|
free(rawtx);
|
||||||
|
} else fprintf(stderr,"couldnt create msig rawtx\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -907,7 +1008,7 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
|
|||||||
|
|
||||||
int32_t main(int32_t argc,char **argv)
|
int32_t main(int32_t argc,char **argv)
|
||||||
{
|
{
|
||||||
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
|
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *pubkeys,*format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
|
||||||
if ( argc < 6 )
|
if ( argc < 6 )
|
||||||
{
|
{
|
||||||
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
|
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
|
||||||
@@ -943,12 +1044,18 @@ int32_t main(int32_t argc,char **argv)
|
|||||||
printf("need to specify path to refcoin's cli as last argv\n");
|
printf("need to specify path to refcoin's cli as last argv\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr) < 0 )
|
pubkeys=0;
|
||||||
|
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) < 0 )
|
||||||
{
|
{
|
||||||
printf("cant find bindtxid.(%s)\n",bindtxidstr);
|
printf("cant find bindtxid.(%s)\n",bindtxidstr);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
importaddress(refcoin,"",depositaddr);
|
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0)
|
||||||
|
{
|
||||||
|
if (M==N==1) importaddress(refcoin,"",depositaddr);
|
||||||
|
else addmultisigaddress(refcoin,"",M,pubkeys,bindtxidstr);
|
||||||
|
}
|
||||||
|
if (pubkeys!=0) free(pubkeys);
|
||||||
printf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
|
printf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
|
||||||
}
|
}
|
||||||
if ( (regjson= jarray(&n,clijson,"registered")) != 0 )
|
if ( (regjson= jarray(&n,clijson,"registered")) != 0 )
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ WARNING: there is an attack vector that precludes betting any large amounts, it
|
|||||||
3. reorg the chain and make a big bet using the winning entropy calculated in 2.
|
3. reorg the chain and make a big bet using the winning entropy calculated in 2.
|
||||||
|
|
||||||
In order to mitigate this, the disclosure of the house entropy needs to be delayed beyond a reasonable reorg depth (notarization). It is recommended for production dice game with significant amounts of money to use such a delayed disclosure method.
|
In order to mitigate this, the disclosure of the house entropy needs to be delayed beyond a reasonable reorg depth (notarization). It is recommended for production dice game with significant amounts of money to use such a delayed disclosure method.
|
||||||
|
|
||||||
|
Actually a much better solution to this is possible, which allows to retain the realtime response aspect of dice CC, which is critical to its usage.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../compat/endian.h"
|
#include "../compat/endian.h"
|
||||||
@@ -279,7 +284,7 @@ uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1)));
|
//fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1)));
|
||||||
if ( modval < 10000/(odds+1) )
|
if ( modval < 10000/(odds+1) )
|
||||||
winnings = bet * (odds+1);
|
winnings = bet * (odds+1);
|
||||||
}
|
}
|
||||||
@@ -413,10 +418,8 @@ int32_t DiceIsWinner(uint256 &entropy,uint256 txid,CTransaction tx,CTransaction
|
|||||||
hentropy2 = DiceHashEntropy(entropy,vinTx.vin[0].prevout.hash);
|
hentropy2 = DiceHashEntropy(entropy,vinTx.vin[0].prevout.hash);
|
||||||
if ( hentropy == hentropy2 )
|
if ( hentropy == hentropy2 )
|
||||||
{
|
{
|
||||||
char str[65];
|
|
||||||
fprintf(stderr, "%s something \n",uint256_str(str,entropy));
|
|
||||||
winnings = DiceCalc(tx.vout[1].nValue,tx.vout[2].nValue,minbet,maxbet,maxodds,timeoutblocks,entropy,bettorentropy);
|
winnings = DiceCalc(tx.vout[1].nValue,tx.vout[2].nValue,minbet,maxbet,maxodds,timeoutblocks,entropy,bettorentropy);
|
||||||
fprintf(stderr,"%s winnings %.8f bet %.8f at odds %d:1\n",uint256_str(str,tx.GetHash()),(double)winnings/COIN,(double)tx.vout[1].nValue/COIN,(int32_t)(tx.vout[2].nValue-10000));
|
char str[65]; fprintf(stderr,"%s winnings %.8f bet %.8f at odds %d:1\n",uint256_str(str,tx.GetHash()),(double)winnings/COIN,(double)tx.vout[1].nValue/COIN,(int32_t)(tx.vout[2].nValue-10000));
|
||||||
//fprintf(stderr,"I am house entropy %.8f entropy.(%s) vs %s -> winnings %.8f\n",(double)vinTx.vout[0].nValue/COIN,uint256_str(str,entropy),uint256_str(str2,hash),(double)winnings/COIN);
|
//fprintf(stderr,"I am house entropy %.8f entropy.(%s) vs %s -> winnings %.8f\n",(double)vinTx.vout[0].nValue/COIN,uint256_str(str,entropy),uint256_str(str2,hash),(double)winnings/COIN);
|
||||||
if ( winnings == 0 )
|
if ( winnings == 0 )
|
||||||
{
|
{
|
||||||
@@ -445,7 +448,6 @@ bool DiceVerifyTimeout(CTransaction &betTx,int32_t timeoutblocks)
|
|||||||
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||||
{
|
{
|
||||||
uint256 txid,fundingtxid,vinfundingtxid,vinhentropy,vinproof,hashBlock,hash,proof,entropy; int64_t minbet,maxbet,maxodds,timeoutblocks,odds,winnings; uint64_t vinsbits,sbits,amount,inputs,outputs,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,iswin; uint8_t funcid; CScript fundingPubKey; CTransaction fundingTx,vinTx,vinofvinTx; char CCaddr[64];
|
uint256 txid,fundingtxid,vinfundingtxid,vinhentropy,vinproof,hashBlock,hash,proof,entropy; int64_t minbet,maxbet,maxodds,timeoutblocks,odds,winnings; uint64_t vinsbits,sbits,amount,inputs,outputs,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,iswin; uint8_t funcid; CScript fundingPubKey; CTransaction fundingTx,vinTx,vinofvinTx; char CCaddr[64];
|
||||||
CBlockIndex block;
|
|
||||||
numvins = tx.vin.size();
|
numvins = tx.vin.size();
|
||||||
numvouts = tx.vout.size();
|
numvouts = tx.vout.size();
|
||||||
preventCCvins = preventCCvouts = -1;
|
preventCCvins = preventCCvouts = -1;
|
||||||
@@ -544,18 +546,22 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
|||||||
//vin.3+: funding CC vout.0 from 'F', 'E', 'W', 'L' or 'T'
|
//vin.3+: funding CC vout.0 from 'F', 'E', 'W', 'L' or 'T'
|
||||||
//vout.1: tag to owner address for entropy funds
|
//vout.1: tag to owner address for entropy funds
|
||||||
preventCCvouts = 1;
|
preventCCvouts = 1;
|
||||||
CBlockIndex block;
|
|
||||||
DiceAmounts(inputs,outputs,cp,eval,tx,sbits,fundingtxid);
|
DiceAmounts(inputs,outputs,cp,eval,tx,sbits,fundingtxid);
|
||||||
if ( IsCCInput(tx.vin[1].scriptSig) == 0 || IsCCInput(tx.vin[2].scriptSig) == 0 )
|
if ( IsCCInput(tx.vin[1].scriptSig) == 0 || IsCCInput(tx.vin[2].scriptSig) == 0 )
|
||||||
return eval->Invalid("vin0 or vin1 normal vin for bet");
|
return eval->Invalid("vin0 or vin1 normal vin for bet");
|
||||||
else if ( tx.vin[1].prevout.hash != tx.vin[2].prevout.hash )
|
else if ( tx.vin[1].prevout.hash != tx.vin[2].prevout.hash )
|
||||||
return eval->Invalid("vin0 != vin1 prevout.hash for bet");
|
return eval->Invalid("vin0 != vin1 prevout.hash for bet");
|
||||||
|
<<<<<<< HEAD
|
||||||
else if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 ) {
|
else if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 ) {
|
||||||
char str[65],str2[65],str3[65];
|
char str[65],str2[65],str3[65];
|
||||||
fprintf(stderr, "txid.%s tx.%s hashBlock.%s\n",uint256_str(str,txid),uint256_str(str2,tx.vin[1].prevout.hash),uint256_str(str3,hashBlock));
|
fprintf(stderr, "txid.%s tx.%s hashBlock.%s\n",uint256_str(str,txid),uint256_str(str2,tx.vin[1].prevout.hash),uint256_str(str3,hashBlock));
|
||||||
return eval->Invalid("always should find looking vin.0, but didnt for wlt");
|
return eval->Invalid("always should find looking vin.0, but didnt for wlt");
|
||||||
} else if (hashBlock.IsNull() || !eval->GetBlock(hashBlock, block))
|
} else if (hashBlock.IsNull() || !eval->GetBlock(hashBlock, block))
|
||||||
return eval->Invalid(" TX not confirmed! always should find vin.0, but didnt for wlt");
|
return eval->Invalid(" TX not confirmed! always should find vin.0, but didnt for wlt");
|
||||||
|
=======
|
||||||
|
else if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 )
|
||||||
|
return eval->Invalid("always should find looking vin.0, but didnt for wlt");
|
||||||
|
>>>>>>> 19d614c8344b70a0d4a7da8620a2dd1168016abc
|
||||||
else if ( vinTx.vout.size() < 3 || DecodeDiceOpRet(tx.vin[1].prevout.hash,vinTx.vout[vinTx.vout.size()-1].scriptPubKey,vinsbits,vinfundingtxid,vinhentropy,vinproof) != 'B' )
|
else if ( vinTx.vout.size() < 3 || DecodeDiceOpRet(tx.vin[1].prevout.hash,vinTx.vout[vinTx.vout.size()-1].scriptPubKey,vinsbits,vinfundingtxid,vinhentropy,vinproof) != 'B' )
|
||||||
return eval->Invalid("not betTx for vin0/1 for wlt");
|
return eval->Invalid("not betTx for vin0/1 for wlt");
|
||||||
else if ( sbits != vinsbits || fundingtxid != vinfundingtxid )
|
else if ( sbits != vinsbits || fundingtxid != vinfundingtxid )
|
||||||
@@ -591,12 +597,21 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
|||||||
{
|
{
|
||||||
fprintf(stderr,"inputs %.8f != outputs %.8f + %.8f\n",(double)inputs/COIN,(double)outputs/COIN,(double)tx.vout[2].nValue/COIN);
|
fprintf(stderr,"inputs %.8f != outputs %.8f + %.8f\n",(double)inputs/COIN,(double)outputs/COIN,(double)tx.vout[2].nValue/COIN);
|
||||||
return eval->Invalid("CC funds mismatch for win/timeout");
|
return eval->Invalid("CC funds mismatch for win/timeout");
|
||||||
|
<<<<<<< HEAD
|
||||||
}
|
}
|
||||||
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
||||||
{
|
{
|
||||||
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
||||||
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
}
|
||||||
|
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
||||||
|
{
|
||||||
|
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
||||||
|
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
||||||
|
}
|
||||||
|
>>>>>>> 19d614c8344b70a0d4a7da8620a2dd1168016abc
|
||||||
iswin = (funcid == 'W');
|
iswin = (funcid == 'W');
|
||||||
}
|
}
|
||||||
if ( iswin != 0 )
|
if ( iswin != 0 )
|
||||||
@@ -732,7 +747,9 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
|||||||
entropytxid = txid;
|
entropytxid = txid;
|
||||||
entropyval = tx.vout[0].nValue;
|
entropyval = tx.vout[0].nValue;
|
||||||
first = 1;
|
first = 1;
|
||||||
fprintf(stderr, "chosen entropy on loop: %d\n",loops);
|
if (random) {
|
||||||
|
fprintf(stderr, "chosen entropy on loop: %d\n",loops);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1198,7 +1215,7 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
|||||||
} else return(0.);
|
} else return(0.);
|
||||||
}
|
}
|
||||||
error = "didnt find dicefinish tx";
|
error = "didnt find dicefinish tx";
|
||||||
}
|
} else error = res;
|
||||||
return(-1.);
|
return(-1.);
|
||||||
}
|
}
|
||||||
return(0.);
|
return(0.);
|
||||||
|
|||||||
@@ -178,6 +178,41 @@ uint8_t DecodeGatewaysOpRet(const CScript &scriptPubKey,std::string &coin,uint25
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t DecodeGatewaysPartialOpRet(const CScript &scriptPubKey,int32_t &K, CPubKey &signerpk, std::string &coin,std::string &hex)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||||
|
GetOpReturnData(scriptPubKey, vopret);
|
||||||
|
script = (uint8_t *)vopret.data();
|
||||||
|
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> K; ss >> signerpk; ss >> coin; ss >> hex) != 0 )
|
||||||
|
{
|
||||||
|
return(f);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t DecodeGatewaysWithdrawOpRet(const CScript &scriptPubKey, uint256 &assetid, std::string &refcoin, CPubKey &withdrawpub, int64_t &amount)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||||
|
GetOpReturnData(scriptPubKey, vopret);
|
||||||
|
script = (uint8_t *)vopret.data();
|
||||||
|
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> refcoin; ss >> withdrawpub; ss >> amount) != 0 )
|
||||||
|
{
|
||||||
|
return(f);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
uint8_t DecodeGatewaysMarkdoneOpRet(const CScript &scriptPubKey, std::string &refcoin, uint256 &cointxid)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||||
|
GetOpReturnData(scriptPubKey, vopret);
|
||||||
|
script = (uint8_t *)vopret.data();
|
||||||
|
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> refcoin; ss >> cointxid) != 0 )
|
||||||
|
{
|
||||||
|
return(f);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,std::string &coin,uint256 &tokenid,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &pubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2)
|
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,std::string &coin,uint256 &tokenid,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &pubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2)
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||||
@@ -763,9 +798,11 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
|
|||||||
return("");
|
return("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount)
|
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount)
|
||||||
{
|
{
|
||||||
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64];
|
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C;
|
||||||
|
uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin;
|
||||||
|
std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; CScript opret;
|
||||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 10000;
|
txfee = 10000;
|
||||||
@@ -788,11 +825,12 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
|||||||
if ( inputs > amount )
|
if ( inputs > amount )
|
||||||
CCchange = (inputs - amount);
|
CCchange = (inputs - amount);
|
||||||
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
|
||||||
mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG));
|
||||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG));
|
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,txfee,gatewayspk));
|
||||||
if ( CCchange != 0 )
|
if ( CCchange != 0 )
|
||||||
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,mypk));
|
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,mypk));
|
||||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
|
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'W' << assetid << refcoin << withdrawpub << amount);
|
||||||
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr,"cant find enough inputs or mismatched total\n");
|
fprintf(stderr,"cant find enough inputs or mismatched total\n");
|
||||||
@@ -806,6 +844,7 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
|
|||||||
if ( txfee == 0 )
|
if ( txfee == 0 )
|
||||||
txfee = 5000;
|
txfee = 5000;
|
||||||
mypk = pubkey2pk(Mypubkey());
|
mypk = pubkey2pk(Mypubkey());
|
||||||
|
|
||||||
mtx.vin.push_back(CTxIn(withdrawtxid,2,CScript()));
|
mtx.vin.push_back(CTxIn(withdrawtxid,2,CScript()));
|
||||||
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||||
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'M' << cointxid << refcoin);
|
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'M' << cointxid << refcoin);
|
||||||
@@ -814,8 +853,12 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
|
|||||||
|
|
||||||
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ),pending(UniValue::VARR),obj(UniValue::VOBJ); CTransaction tx; std::string coin; CPubKey mypk,gatewayspk; std::vector<CPubKey> msigpubkeys; uint256 hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2; char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64]; int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply; struct CCcontract_info *cp,C;
|
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,tmprefcoin; CPubKey mypk,gatewayspk,withdrawpub; std::vector<CPubKey> msigpubkeys;
|
||||||
|
uint256 cointxid,hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2;
|
||||||
|
char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64];
|
||||||
|
int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply,amount,nValue; struct CCcontract_info *cp,C;
|
||||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||||
|
|
||||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||||
mypk = pubkey2pk(Mypubkey());
|
mypk = pubkey2pk(Mypubkey());
|
||||||
gatewayspk = GetUnspendable(cp,0);
|
gatewayspk = GetUnspendable(cp,0);
|
||||||
@@ -838,19 +881,22 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
|||||||
queueflag = 1;
|
queueflag = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Getscriptaddress(withmarker,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG);
|
SetCCunspents(unspentOutputs,coinaddr);
|
||||||
SetCCunspents(unspentOutputs,withmarker);
|
|
||||||
numqueued = 0;
|
numqueued = 0;
|
||||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||||
{
|
{
|
||||||
txid = it->first.txhash;
|
txid = it->first.txhash;
|
||||||
vout = (int32_t)it->first.index;
|
vout = (int32_t)it->first.index;
|
||||||
if ( GetTransaction(txid,tx,hashBlock,false) != 0 )
|
nValue = (int64_t)it->second.satoshis;
|
||||||
|
fprintf(stderr,"%s %d %ld\n",txid.ToString().c_str(),vout,(long)nValue);
|
||||||
|
if ( vout == 2 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) &&
|
||||||
|
DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,tmprefcoin,withdrawpub,amount) == 'W' && myIsutxo_spentinmempool(txid,vout) == 0)
|
||||||
{
|
{
|
||||||
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
|
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
|
||||||
Getscriptaddress(withaddr,tx.vout[1].scriptPubKey);
|
Getscriptaddress(withaddr,tx.vout[1].scriptPubKey);
|
||||||
if ( strcmp(destaddr,coinaddr) == 0 )
|
if ( strcmp(destaddr,coinaddr) == 0 )
|
||||||
{
|
{
|
||||||
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.push_back(Pair("txid",uint256_str(str,txid)));
|
obj.push_back(Pair("txid",uint256_str(str,txid)));
|
||||||
CCtxidaddr(txidaddr,txid);
|
CCtxidaddr(txidaddr,txid);
|
||||||
obj.push_back(Pair("txidaddr",txidaddr));
|
obj.push_back(Pair("txidaddr",txidaddr));
|
||||||
@@ -873,31 +919,72 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
|||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr)
|
UniValue GatewaysMultisig(char *txidaddr)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); std::string coin,hex; char str[67],numstr[65],depositaddr[64],gatewaysassets[64]; uint8_t M,N; std::vector<CPubKey> pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CPubKey Gatewayspk,mypk; struct CCcontract_info *cp,C; int32_t i,n,complete,partialtx; int64_t totalsupply;
|
std::string parthex,hex,refcoin; uint256 txid,hashBlock; CTransaction tx; int32_t i,maxK,K,numvouts; CPubKey signerpk;
|
||||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; UniValue result(UniValue::VOBJ);
|
||||||
if ( txfee == 0 )
|
|
||||||
txfee = 10000;
|
SetCCunspents(unspentOutputs,txidaddr);
|
||||||
complete = partialtx = 0;
|
maxK=0;
|
||||||
mypk = pubkey2pk(Mypubkey());
|
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||||
Gatewayspk = GetUnspendable(cp,0);
|
|
||||||
_GetCCaddress(gatewaysassets,EVAL_GATEWAYS,Gatewayspk);
|
|
||||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
|
|
||||||
{
|
{
|
||||||
depositaddr[0] = 0;
|
txid = it->first.txhash;
|
||||||
if ( tx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,tx.vout[tx.vout.size()-1].scriptPubKey,coin,tokenid,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 0 && M <= N && N > 1 && coin == refcoin )
|
if (GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
|
||||||
{
|
{
|
||||||
// need a decentralized way to add signatures to msig tx
|
maxK=K;
|
||||||
n = pubkeys.size();
|
parthex=hex;
|
||||||
for (i=0; i<n; i++)
|
|
||||||
if ( mypk == pubkeys[i] )
|
|
||||||
break;
|
|
||||||
if ( i != n )
|
|
||||||
{
|
|
||||||
hex = "";
|
|
||||||
} else fprintf(stderr,"not one of the multisig signers\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(hex);
|
|
||||||
|
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
|
||||||
|
{
|
||||||
|
const CTransaction &txmempool = e.GetTx();
|
||||||
|
const uint256 &hash = txmempool.GetHash();
|
||||||
|
|
||||||
|
if ((numvouts=txmempool.vout.size()) > 0 && DecodeGatewaysPartialOpRet(txmempool.vout[numvouts-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK)
|
||||||
|
{
|
||||||
|
maxK=K;
|
||||||
|
parthex=hex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(Pair("hex",parthex));
|
||||||
|
result.push_back(Pair("number_of_signs",maxK));
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string hex)
|
||||||
|
{
|
||||||
|
CMutableTransaction mtx; CScript opret; CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx;
|
||||||
|
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; char txidaddr[65];
|
||||||
|
int32_t maxK,K=0; uint256 tmptxid,parttxid,hashBlock;
|
||||||
|
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||||
|
if ( txfee == 0 )
|
||||||
|
txfee = 5000;
|
||||||
|
mypk = pubkey2pk(Mypubkey());
|
||||||
|
txidaddrpk=CCtxidaddr(txidaddr,txid);
|
||||||
|
SetCCunspents(unspentOutputs,txidaddr);
|
||||||
|
maxK=0;
|
||||||
|
if (unspentOutputs.size()==0)
|
||||||
|
{
|
||||||
|
if (AddNormalinputs(mtx,mypk,2*txfee,2)==0) fprintf(stderr,"error adding funds for partialsign\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||||
|
{
|
||||||
|
tmptxid = it->first.txhash;
|
||||||
|
if (GetTransaction(tmptxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
|
||||||
|
{
|
||||||
|
maxK=K;
|
||||||
|
parttxid=tmptxid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxK>0) mtx.vin.push_back(CTxIn(parttxid,0,CScript()));
|
||||||
|
else fprintf(stderr,"Error finding previous partial tx\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(txidaddrpk)) << OP_CHECKSIG));
|
||||||
|
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'P' << maxK+1 << mypk << refcoin << hex);
|
||||||
|
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||||
}
|
}
|
||||||
|
|||||||
52
src/main.cpp
52
src/main.cpp
@@ -92,6 +92,7 @@ unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
|
|||||||
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
||||||
|
|
||||||
CTxMemPool mempool(::minRelayTxFee);
|
CTxMemPool mempool(::minRelayTxFee);
|
||||||
|
CTxMemPool tmpmempool(::minRelayTxFee);
|
||||||
|
|
||||||
struct COrphanTx {
|
struct COrphanTx {
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
@@ -1309,7 +1310,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
|
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, bool fNullifiers)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
if (pfMissingInputs)
|
if (pfMissingInputs)
|
||||||
@@ -1390,14 +1391,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
|
if (fNullifiers == false)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
|
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
|
||||||
{
|
{
|
||||||
if (pool.mapNullifiers.count(nf))
|
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"pool.mapNullifiers.count\n");
|
if (pool.mapNullifiers.count(nf))
|
||||||
return false;
|
{
|
||||||
|
fprintf(stderr,"pool.mapNullifiers.count\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1450,12 +1454,14 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// are the joinsplit's requirements met?
|
// are the joinsplit's requirements met?
|
||||||
if (!view.HaveJoinSplitRequirements(tx))
|
if ( fNullifiers == true )
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"accept failure.2\n");
|
if (!view.HaveJoinSplitRequirements(tx))
|
||||||
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
|
{
|
||||||
|
//fprintf(stderr,"accept failure.2\n");
|
||||||
|
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bring the best block into scope
|
// Bring the best block into scope
|
||||||
view.GetBestBlock();
|
view.GetBestBlock();
|
||||||
|
|
||||||
@@ -4247,6 +4253,17 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
|||||||
{
|
{
|
||||||
CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
|
CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
|
||||||
//fprintf(stderr,"put block's tx into mempool\n");
|
//fprintf(stderr,"put block's tx into mempool\n");
|
||||||
|
// Copy the mempool to temporary mempool because there can be tx in local mempool that make the block invalid.
|
||||||
|
LOCK(mempool.cs);
|
||||||
|
BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) {
|
||||||
|
const CTransaction &tx = e.GetTx();
|
||||||
|
const uint256 &hash = tx.GetHash();
|
||||||
|
tmpmempool.addUnchecked(hash,e,!IsInitialBlockDownload());
|
||||||
|
//fprintf(stderr, "added mempool tx to temp mempool\n");
|
||||||
|
}
|
||||||
|
// clear the mempool before importing all block txs to mempool.
|
||||||
|
mempool.clear();
|
||||||
|
// add all the txs in the block to the empty mempool.
|
||||||
while ( 1 )
|
while ( 1 )
|
||||||
{
|
{
|
||||||
for (i=0; i<block.vtx.size(); i++)
|
for (i=0; i<block.vtx.size(); i++)
|
||||||
@@ -4295,6 +4312,21 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
|||||||
LogPrintf("CheckBlockHeader komodo_check_deposit error");
|
LogPrintf("CheckBlockHeader komodo_check_deposit error");
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order
|
||||||
|
{
|
||||||
|
int invalidtxs = 0;
|
||||||
|
BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) {
|
||||||
|
CTransaction tx = e.GetTx();
|
||||||
|
CValidationState state; bool fMissingInputs,fOverrideFees = false;
|
||||||
|
if (AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees,true) == false )
|
||||||
|
invalidtxs++;
|
||||||
|
//else fprintf(stderr, "added mempool tx back to mempool\n");
|
||||||
|
}
|
||||||
|
if ( 0 && invalidtxs > 0 )
|
||||||
|
fprintf(stderr, "number of invalid txs: %d\n",invalidtxs );
|
||||||
|
// empty the temp mempool for next time.
|
||||||
|
tmpmempool.clear();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ void PruneAndFlush();
|
|||||||
|
|
||||||
/** (try to) add transaction to memory pool **/
|
/** (try to) add transaction to memory pool **/
|
||||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
||||||
bool* pfMissingInputs, bool fRejectAbsurdFee=false);
|
bool* pfMissingInputs, bool fRejectAbsurdFee=false, bool fNullifiers=false);
|
||||||
|
|
||||||
|
|
||||||
struct CNodeStateStats {
|
struct CNodeStateStats {
|
||||||
|
|||||||
@@ -426,6 +426,7 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "gateways", "gatewayspending", &gatewayspending, true },
|
{ "gateways", "gatewayspending", &gatewayspending, true },
|
||||||
{ "gateways", "gatewaysmultisig", &gatewaysmultisig, true },
|
{ "gateways", "gatewaysmultisig", &gatewaysmultisig, true },
|
||||||
{ "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
|
{ "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
|
||||||
|
{ "gateways", "gatewayspartialsign", &gatewayspartialsign, true },
|
||||||
|
|
||||||
/* dice */
|
/* dice */
|
||||||
{ "dice", "dicelist", &dicelist, true },
|
{ "dice", "dicelist", &dicelist, true },
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ extern UniValue gatewayswithdraw(const UniValue& params, bool fHelp);
|
|||||||
extern UniValue gatewayspending(const UniValue& params, bool fHelp);
|
extern UniValue gatewayspending(const UniValue& params, bool fHelp);
|
||||||
extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp);
|
extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp);
|
||||||
extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp);
|
extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp);
|
||||||
|
extern UniValue gatewayspartialsign(const UniValue& params, bool fHelp);
|
||||||
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
|
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
|
||||||
extern UniValue channelsopen(const UniValue& params, bool fHelp);
|
extern UniValue channelsopen(const UniValue& params, bool fHelp);
|
||||||
extern UniValue channelspayment(const UniValue& params, bool fHelp);
|
extern UniValue channelspayment(const UniValue& params, bool fHelp);
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
|||||||
CPubKey pubKey(vSolutions[0]);
|
CPubKey pubKey(vSolutions[0]);
|
||||||
if (!pubKey.IsValid())
|
if (!pubKey.IsValid())
|
||||||
{
|
{
|
||||||
fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
|
//fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5621,7 +5621,7 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp)
|
|||||||
coin = params[1].get_str();
|
coin = params[1].get_str();
|
||||||
withdrawpub = ParseHex(params[2].get_str());
|
withdrawpub = ParseHex(params[2].get_str());
|
||||||
amount = atof((char *)params[3].get_str().c_str()) * COIN;
|
amount = atof((char *)params[3].get_str().c_str()) * COIN;
|
||||||
hex = GatewaysWithdraw(0,bindtxid,coin,withdrawpub,amount);
|
hex = GatewaysWithdraw(0,bindtxid,coin,pubkey2pk(withdrawpub),amount);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("result", "success"));
|
||||||
@@ -5665,18 +5665,30 @@ UniValue gatewayspending(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
UniValue gatewaysmultisig(const UniValue& params, bool fHelp)
|
UniValue gatewaysmultisig(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
UniValue result(UniValue::VOBJ); uint256 bindtxid,withtxid; std::string coin,hex; char *txidaddr;
|
UniValue result(UniValue::VOBJ); std::string hex; char *txidaddr;
|
||||||
if ( fHelp || params.size() != 2 )
|
if ( fHelp || params.size() != 1 )
|
||||||
throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\n");
|
throw runtime_error("gatewaysmultisig txidaddr\n");
|
||||||
if ( ensure_CCrequirements() < 0 )
|
if ( ensure_CCrequirements() < 0 )
|
||||||
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
|
txidaddr = (char *)params[0].get_str().c_str();
|
||||||
|
return(GatewaysMultisig(txidaddr));
|
||||||
|
}
|
||||||
|
|
||||||
|
UniValue gatewayspartialsign(const UniValue& params, bool fHelp)
|
||||||
|
{
|
||||||
|
UniValue result(UniValue::VOBJ); std::string coin,parthex,hex; uint256 txid;
|
||||||
|
if ( fHelp || params.size() != 3 )
|
||||||
|
throw runtime_error("gatewayspartialsign txidaddr refcoin hex\n");
|
||||||
|
if ( ensure_CCrequirements() < 0 )
|
||||||
|
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
|
||||||
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
txid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
coin = params[1].get_str();
|
coin = params[1].get_str();
|
||||||
withtxid = Parseuint256((char *)params[2].get_str().c_str());
|
parthex = params[2].get_str();
|
||||||
txidaddr = (char *)params[3].get_str().c_str();
|
hex = GatewaysPartialSign(0,txid,coin,parthex);
|
||||||
hex = GatewaysMultisig(0,coin,bindtxid,withtxid,txidaddr);
|
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
result.push_back(Pair("result", "success"));
|
result.push_back(Pair("result", "success"));
|
||||||
@@ -5715,7 +5727,8 @@ UniValue oraclesregister(const UniValue& params, bool fHelp)
|
|||||||
const CKeyStore& keystore = *pwalletMain;
|
const CKeyStore& keystore = *pwalletMain;
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
txid = Parseuint256((char *)params[0].get_str().c_str());
|
txid = Parseuint256((char *)params[0].get_str().c_str());
|
||||||
datafee = atol((char *)params[1].get_str().c_str());
|
if ( (datafee= atol((char *)params[1].get_str().c_str())) == 0 )
|
||||||
|
datafee = atof((char *)params[1].get_str().c_str()) * COIN;
|
||||||
hex = OracleRegister(0,txid,datafee);
|
hex = OracleRegister(0,txid,datafee);
|
||||||
if ( hex.size() > 0 )
|
if ( hex.size() > 0 )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user