diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index 254f7e3a528..64bb9557290 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -250,10 +250,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("channelopen is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for channelpayment!"); - else if ( IsCCInput(tx.vin[1].scriptSig) == 0 ) - return eval->Invalid("vin.1 is CC for channelpayment!"); - else if ( IsCCInput(tx.vin[2].scriptSig) == 0 ) - return eval->Invalid("vin.2 is CC for channelpayment!"); + else if ( IsCCInput(tx.vin[tx.vin.size()-2].scriptSig) == 0 ) + return eval->Invalid("vin."+std::to_string(tx.vin.size()-2)+" is CC for channelpayment!"); else if ( ConstrainVout(tx.vout[1],1,srcmarker,CC_MARKER_VALUE)==0 ) return eval->Invalid("vout.1 is CC marker to srcpub or invalid amount for channelpayment!"); else if ( ConstrainVout(tx.vout[2],1,destmarker,CC_MARKER_VALUE)==0 ) @@ -283,8 +281,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("invalid previous tx OP_RETURN data!"); else if ( ConstrainVout(tx.vout[0],1,channeladdress,(p1-param2)*payment)==0 ) return eval->Invalid("vout.0 is CC or invalid CC change amount for channelpayment!"); - else if ((*cp->ismyvin)(tx.vin[2].scriptSig) == 0 || prevTx.vout[tx.vin[2].prevout.n].nValue!=CC_MARKER_VALUE) - return eval->Invalid("vin.2 is CC marker or invalid marker amount for channelpayment!"); + else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0 || prevTx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE) + return eval->Invalid("vin."+std::to_string(tx.vin.size()-1)+" is CC marker or invalid marker amount for channelpayment!"); else if (param1+param2!=p1) return eval->Invalid("invalid payment depth!"); else if (tx.vout[3].nValue > prevTx.vout[0].nValue) @@ -313,10 +311,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("channelopen is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for channelclose!"); - else if ( IsCCInput(tx.vin[1].scriptSig) == 0 ) - return eval->Invalid("vin.1 is CC for channelclose!"); - else if ( IsCCInput(tx.vin[2].scriptSig) == 0 ) - return eval->Invalid("vin.2 is CC for channelclose!"); + else if ( IsCCInput(tx.vin[tx.vin.size()-2].scriptSig) == 0 ) + return eval->Invalid("vin."+std::to_string(tx.vin.size()-2)+" is CC for channelclose!"); else if ( ConstrainVout(tx.vout[0],1,channeladdress,0)==0 ) return eval->Invalid("vout.0 is CC for channelclose!"); else if ( ConstrainVout(tx.vout[1],1,srcmarker,CC_MARKER_VALUE)==0 ) @@ -329,8 +325,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & { if ((numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tokenid, tmp_txid, srcpub, destpub, p1, p2, p3) == 0) return eval->Invalid("invalid previous tx OP_RETURN data!"); - else if ((*cp->ismyvin)(tx.vin[2].scriptSig) == 0 || prevTx.vout[tx.vin[2].prevout.n].nValue!=CC_MARKER_VALUE) - return eval->Invalid("vin.2 is CC marker or invalid marker amount for channelclose!"); + else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0 || prevTx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE) + return eval->Invalid("vin."+std::to_string(tx.vin.size()-1)+" is CC marker or invalid marker amount for channelclose!"); else if (tx.vout[0].nValue != prevTx.vout[0].nValue) return eval->Invalid("invalid CC amount, amount must match funds in channel"); } @@ -358,10 +354,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("channelClose is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for channelrefund!"); - else if ( IsCCInput(tx.vin[1].scriptSig) == 0 ) - return eval->Invalid("vin.1 is CC for channelrefund!"); - else if ( IsCCInput(tx.vin[2].scriptSig) == 0 ) - return eval->Invalid("vin.2 is CC for channelrefund!"); + else if ( IsCCInput(tx.vin[tx.vin.size()-2].scriptSig) == 0 ) + return eval->Invalid("vin."+std::to_string(tx.vin.size()-2)+" CC for channelrefund!"); else if ( ConstrainVout(tx.vout[0],1,srcmarker,CC_MARKER_VALUE)==0 ) return eval->Invalid("vout.0 is CC marker to srcpub or invalid amount for channelrefund!"); else if ( ConstrainVout(tx.vout[1],1,destmarker,CC_MARKER_VALUE)==0 ) @@ -376,8 +370,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & { if ((numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, tokenid, tmp_txid, srcpub, destpub, p1, p2, p3) == 0) return eval->Invalid("invalid previous tx OP_RETURN data!"); - else if ((*cp->ismyvin)(tx.vin[2].scriptSig) == 0 || prevTx.vout[tx.vin[2].prevout.n].nValue!=CC_MARKER_VALUE) - return eval->Invalid("vin.2 is CC marker or invalid marker amount for channelrefund!"); + else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0 || prevTx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE) + return eval->Invalid("vin."+std::to_string(tx.vin.size()-1)+" is CC marker or invalid marker amount for channelrefund!"); else if (tx.vout[2].nValue != prevTx.vout[0].nValue) return eval->Invalid("invalid amount, refund amount and funds in channel must match!"); } diff --git a/src/cc/dapps/oraclefeed.c b/src/cc/dapps/oraclefeed.c index 6ac014ad1f4..4687837ac8f 100644 --- a/src/cc/dapps/oraclefeed.c +++ b/src/cc/dapps/oraclefeed.c @@ -592,7 +592,7 @@ void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys) 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,j=0,n,v; int64_t satoshis; bits256 txid; *totalp = 0; if ( (n= cJSON_GetArraySize(unspents)) > 0 ) { @@ -610,7 +610,10 @@ cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required) jaddi(vins,vin); *totalp += satoshis; if ( (*totalp) >= required ) - break; + { + if (j<3) j++; + else break; + } } } } @@ -910,10 +913,11 @@ void update_gatewayspending(int8_t type,char *refcoin,char *acname,char *bindtxi processed++; } free(rawtx); - } else fprintf(stderr,"couldnt create rawtx\n"); + } else fprintf(stderr,"couldnt create rawtx\n"); } else { + rawtx=0; lasttxid = jbits256(item,"last_txid"); if ( lasttxid.txid==withdrawtxid.txid) { @@ -921,24 +925,27 @@ void update_gatewayspending(int8_t type,char *refcoin,char *acname,char *bindtxi } else rawtx=jstr(item,"hex"); K=jint(item,"number_of_signs"); - if ( rawtx!=0 && (clijson=addsignature(refcoin,"",rawtx,M)) != 0 ) + if (rawtx!=0) { - if ( is_cJSON_True(jobj(clijson,"complete")) != 0 ) - { - txid=gatewayscompletesigning(type,refcoin,acname,lasttxid,jstr(clijson,"hex")); - if (txid.txid!=zeroid.txid) fprintf(stderr,"### SIGNING withdraw %s %dof%d\n",bits256_str(str,withdrawtxid),K+1,N); - else fprintf(stderr,"### SIGNING error broadcasting tx on %s\n",acname); - } - else if ( jint(clijson,"partialtx") != 0 ) + if ((clijson=addsignature(refcoin,"",rawtx,M)) != 0 ) { - txid=gatewayspartialsign(type,refcoin,acname,lasttxid,jstr(clijson,"hex")); - if (txid.txid!=zeroid.txid) fprintf(stderr,"### SIGNING withdraw %s %d/%dof%d\n",bits256_str(str,withdrawtxid),K+1,M,N); - else fprintf(stderr,"### SIGNING error broadcasting tx on %s\n",acname); - } - free_json(clijson); - processed++; - if ( lasttxid.txid==withdrawtxid.txid) free(rawtx); - } + if ( is_cJSON_True(jobj(clijson,"complete")) != 0 ) + { + txid=gatewayscompletesigning(type,refcoin,acname,lasttxid,jstr(clijson,"hex")); + if (txid.txid!=zeroid.txid) fprintf(stderr,"### SIGNING withdraw %s %dof%d\n",bits256_str(str,withdrawtxid),K+1,N); + else fprintf(stderr,"### SIGNING error broadcasting tx on %s\n",acname); + } + else if ( jint(clijson,"partialtx") != 0 ) + { + txid=gatewayspartialsign(type,refcoin,acname,lasttxid,jstr(clijson,"hex")); + if (txid.txid!=zeroid.txid) fprintf(stderr,"### SIGNING withdraw %s %d/%dof%d\n",bits256_str(str,withdrawtxid),K+1,M,N); + else fprintf(stderr,"### SIGNING error broadcasting tx on %s\n",acname); + } + free_json(clijson); + processed++; + if ( lasttxid.txid==withdrawtxid.txid) free(rawtx); + } + } else fprintf(stderr,"couldnt create rawtx or find previous partial signed tx\n"); } } } diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index d88b3d25f54..00c80082b98 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -628,20 +628,25 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("deposit amount greater then bind total supply"); else if (komodo_txnotarizedconfirmed(deposittxid) == false) return eval->Invalid("gatewaysdeposit tx is not yet confirmed(notarised)!"); - else if (myGetTransaction(tx.vin[2].prevout.hash,tmptx,hashblock) == 0) - return eval->Invalid("invalid gatewaysdeposittxid!"); else if (IsCCInput(tx.vin[0].scriptSig) != 0) return eval->Invalid("vin.0 is normal for gatewaysclaim!"); - else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0 || myGetTransaction(tx.vin[tx.vin.size()-1].prevout.hash,tmptx,hashblock)==0 || tmptx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE) + else if (tx.vin.size()>2) + { + i=1; + while (i<=tx.vin.size()-2) + { + if (IsCCInput(tx.vin[i].scriptSig)==0) return eval->Invalid("vin."+std::to_string(i)+" is CC for gatewaysclaim!"); + i++; + } + } + else if ((*cp->ismyvin)(tx.vin[tx.vin.size()-1].scriptSig) == 0 || tmptx.vout[tx.vin[tx.vin.size()-1].prevout.n].nValue!=CC_MARKER_VALUE) return eval->Invalid("vin."+std::to_string(tx.vin.size()-1)+" is CC marker for gatewaysclaim or invalid marker amount!"); else if (_GetCCaddress(destaddr,EVAL_TOKENS,pubkey)==0 || ConstrainVout(tx.vout[0],1,destaddr,amount)==0) return eval->Invalid("invalid vout tokens to destpub for gatewaysclaim!"); - else if (numvouts>2 && (myGetTransaction(tx.vin[1].prevout.hash,tmptx,hashblock)==0 || ConstrainVout(tx.vout[1],1,gatewaystokensaddr,tmptx.vout[tx.vin[1].prevout.n].nValue-amount)==0)) + else if (numvouts>2 && tx.vout[1].scriptPubKey.IsPayToCryptoCondition() && (myGetTransaction(tx.vin[1].prevout.hash,tmptx,hashblock)==0 || ConstrainVout(tx.vout[1],1,gatewaystokensaddr,tmptx.vout[tx.vin[1].prevout.n].nValue-amount)==0)) return eval->Invalid("invalid CC change vout for gatewaysclaim!"); else if (amount!=tmpamount) - return eval->Invalid("claimed amount different then deposit amount"); - else if (tx.vout[0].nValue!=amount) - return eval->Invalid("claim amount not matching amount in opret"); + return eval->Invalid("claimed amount different then deposit amount"); else if (pubkey!=tmppubkey) return eval->Invalid("claim destination pubkey different than in deposit tx"); else @@ -697,8 +702,6 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("invalid marker vout for gatewaysWithdraw!"); else if ( ConstrainVout(tmptx.vout[1],1,gatewaystokensaddr,amount)==0) return eval->Invalid("invalid tokens to gateways vout for gatewaysWithdraw!"); - else if (tmptx.vout[1].nValue!=amount) - return eval->Invalid("amount in opret not matching tx tokens amount!"); else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) @@ -953,7 +956,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3) > 0 ) + if ( AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,2) > 0 ) { if (AddTokenCCInputs(cpTokens, mtx, mypk, tokenid, totalsupply, 64)>0) { @@ -1032,7 +1035,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std:: LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if ( AddNormalinputs(mtx,mypk,txfee+2*CC_MARKER_VALUE,4) > 0 ) + if ( AddNormalinputs(mtx,mypk,txfee+2*CC_MARKER_VALUE,3) > 0 ) { mtx.vout.push_back(MakeCC1vout(cp->evalcode,CC_MARKER_VALUE,destpub)); mtx.vout.push_back(CTxOut(CC_MARKER_VALUE,CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr,cointxid))) << OP_CHECKSIG)); @@ -1104,7 +1107,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 ) + if ( AddNormalinputs(mtx,mypk,txfee,1) > 0 ) { if ((inputs=AddGatewaysInputs(cp, mtx, gatewayspk, bindtxid, amount, 60)) > 0) { @@ -1182,7 +1185,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin } } } - if( AddNormalinputs(mtx, mypk, txfee+CC_MARKER_VALUE, 4) > 0 ) + if( AddNormalinputs(mtx, mypk, txfee+CC_MARKER_VALUE, 2) > 0 ) { if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, tokenid, amount, 60)) > 0) { @@ -1294,7 +1297,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc return(""); } } - if (AddNormalinputs(mtx,mypk,txfee,3)!=0) + if (AddNormalinputs(mtx,mypk,txfee,1)!=0) { mtx.vin.push_back(CTxIn(tx.GetHash(),0,CScript())); mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CC_MARKER_VALUE,gatewayspk)); @@ -1393,7 +1396,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string return(""); } } - if (AddNormalinputs(mtx,mypk,txfee,3)!=0) + if (AddNormalinputs(mtx,mypk,txfee,1)!=0) { mtx.vin.push_back(CTxIn(lasttxid,0,CScript())); mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CC_MARKER_VALUE,gatewayspk)); @@ -1458,7 +1461,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if (AddNormalinputs(mtx,mypk,txfee,3)!=0) + if (AddNormalinputs(mtx,mypk,txfee,1)!=0) { mtx.vin.push_back(CTxIn(completetxid,0,CScript())); mtx.vout.push_back(CTxOut(CC_MARKER_VALUE,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));