diff --git a/src/cc/CCchannels.h b/src/cc/CCchannels.h index 26057457f..ba31883a2 100644 --- a/src/cc/CCchannels.h +++ b/src/cc/CCchannels.h @@ -22,10 +22,9 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment); -std::string ChannelStop(uint64_t txfee,CPubKey destpub,uint256 origtxid); -std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 origtxid,int32_t n,int64_t amount); -std::string ChannelCollect(uint64_t txfee,uint256 paytxid,uint256 origtxid,int32_t n,int64_t amount); -std::string ChannelRefund(uint64_t txfee,uint256 stoptxid,uint256 origtxid); +std::string ChannelPayment(uint64_t txfee,uint256 opentxid,uint256 prevtxid,int64_t amount); +std::string ChannelClose(uint64_t txfee,uint256 opentxid); +std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid); // CCcustom UniValue ChannelsInfo(); diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index 0ecd6a1be..01a422715 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -244,7 +244,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("vout.1 is CC for channelOpen"); else if ( tx.vout[2].scriptPubKey.IsPayToCryptoCondition() == 0 ) return eval->Invalid("vout.2 is CC for channelOpen"); - else if ( numpayments > 1000) + else if ( numpayments > CHANNELS_MAXPAYMENTS) return eval->Invalid("too many payment increments"); else if ( tx.vout[0].nValue != param1 * param2) return eval->Invalid("tx funds do not match sum of payments"); @@ -287,7 +287,6 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, u GetCCaddress1of2(cp,coinaddr,srcpub,destpub); SetCCunspents(unspentOutputs,coinaddr); - for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { if ( (int32_t)it->first.index==0 && GetTransaction(it->first.txhash,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0) @@ -301,12 +300,10 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, u } } } - if (myIsutxo_spentinmempool(txid,vout) != 0) { txid=zeroid; int32_t mindepth=1000; - BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx) { const CTransaction &txmempool = e.GetTx(); @@ -323,7 +320,6 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, u } } } - if (txid != zeroid) { mtx.vin.push_back(CTxIn(txid,vout,CScript())); @@ -344,6 +340,8 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64 cp = CCinit(&C,EVAL_CHANNELS); if ( txfee == 0 ) txfee = 10000; + if (numpayments>CHANNELS_MAXPAYMENTS) + return (""); mypk = pubkey2pk(Mypubkey()); funds = numpayments * payment; if ( AddNormalinputs(mtx,mypk,funds+3*txfee,64) > 0 ) @@ -364,38 +362,78 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64 return(""); } -std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 opentxid,int32_t numpayments) +std::string ChannelPayment(uint64_t txfee,uint256 opentxid,uint256 prevtxid,int64_t amount) { CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; uint256 txid,secret,hashblock,entropy,hentropy,param3; - struct CCcontract_info *cp,C; int32_t i,funcid,prevdepth,numvouts,param1; + struct CCcontract_info *cp,C; int32_t i,funcid,prevdepth,numvouts,numpayments,param1; int64_t param2,payment,change,funds; uint8_t hash[32],hashdest[32]; CTransaction channelOpenTx,prevTx; - if (GetTransaction(prevtxid,prevTx,hashblock,false) != 0) + if (opentxid==prevtxid) { - if ((numvouts=prevTx.vout.size()) > 0 && ((funcid = DecodeChannelsPaymentOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, txid, srcpub, destpub, param1, param2, param3)) != 0) && (funcid == 'O' || funcid == 'P')) + if (GetTransaction(opentxid,channelOpenTx,hashblock,false) != 0) { - if (mypk != srcpub || mypk != destpub) + if ((numvouts=prevTx.vout.size()) > 0 && ((funcid = DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3)) != 0) && funcid == 'O') + { + if (mypk == srcpub || mypk == destpub) + { + prevdepth=param1; + payment=param2; + } + else + { + fprintf(stderr,"this is not our channel\n"); + return(""); + } + } + else + { + fprintf(stderr,"invalid previous txid\n"); + return(""); + } + if (amount % payment != 0) + return (""); + numpayments=amount/payment; + hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash); + endiancpy(hash, (uint8_t * ) & hentropy, 32); + for (i = 0; i < numpayments; i++) + { + vcalc_sha256(0, hashdest, hash, 32); + memcpy(hash, hashdest, 32); + } + endiancpy((uint8_t * ) & secret, hashdest, 32); + + } + } + else if (GetTransaction(prevtxid,prevTx,hashblock,false) != 0) + { + if ((numvouts=prevTx.vout.size()) > 0 && ((funcid = DecodeChannelsPaymentOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, txid, srcpub, destpub, param1, param2, param3)) != 0) && funcid == 'P') + { + if (mypk == srcpub || mypk == destpub) + { + prevdepth=param1; + payment=param2; + } + else { fprintf(stderr,"this is not our channel\n"); return(""); } - - prevdepth=param1; - payment=param2; } else { fprintf(stderr,"invalid previous txid\n"); return(""); } - + if ((numpayments=amount % payment) != 0) + return (""); + numpayments=amount/payment; if (GetTransaction(opentxid,channelOpenTx,hashblock,false) != 0) { hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash); endiancpy(hash, (uint8_t * ) & hentropy, 32); - for (i = 0; i < prevdepth-numpayments; i++) + for (i = 0; i < numpayments; i++) { vcalc_sha256(0, hashdest, hash, 32); memcpy(hash, hashdest, 32); @@ -416,8 +454,8 @@ std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 opentxid,int3 mypk = pubkey2pk(Mypubkey()); if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 ) { - if ((funds=AddChannelsInputs(cp,mtx,prevtxid)) != 0 && (change=funds-numpayments*payment)>=0) { - mtx.vout.push_back(CTxOut(numpayments * payment, CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG)); + if ((funds=AddChannelsInputs(cp,mtx,prevtxid)) != 0 && (change=funds-amount)>=0) { + mtx.vout.push_back(CTxOut(amount, CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS, txfee, mypk)); mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, change, mypk, destpub)); return (FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeChannelsPaymentOpRet('P', opentxid, prevtxid, mypk, destpub, prevdepth - numpayments, payment, secret))); @@ -426,7 +464,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 prevtxid,uint256 opentxid,int3 return(""); } -std::string ChannelClose(uint64_t txfee,uint256 prevtxid,uint256 opentxid,CPubKey destpub) +std::string ChannelClose(uint64_t txfee,uint256 opentxid) { CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; // verify this is one of our outbound channels @@ -437,12 +475,12 @@ std::string ChannelClose(uint64_t txfee,uint256 prevtxid,uint256 opentxid,CPubKe if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 ) { mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('S',opentxid,mypk,destpub,0,0,zeroid))); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('S',opentxid,mypk,mypk,0,0,zeroid))); } return(""); } -std::string ChannelRefund(uint64_t txfee,uint256 closetxid,uint256 opentxid) +std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid) { CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; int64_t amount; // verify stoptxid and origtxid match and are mine diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 8934ae717..7d2eab1e3 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -383,8 +383,7 @@ static const CRPCCommand vRPCCommands[] = { "channels", "channelsinfo", &channelsinfo, true }, { "channels", "channelsopen", &channelsopen, true }, { "channels", "channelspayment", &channelspayment, true }, - { "channels", "channelscollect", &channelscollect, true }, - { "channels", "channelsstop", &channelsstop, true }, + { "channels", "channelsclose", &channelsclose, true }, { "channels", "channelsrefund", &channelsrefund, true }, /* Oracles */ diff --git a/src/rpcserver.h b/src/rpcserver.h index f4c502d63..a78f1b6fc 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -254,11 +254,9 @@ extern UniValue gatewayspending(const UniValue& params, bool fHelp); extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp); extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp); extern UniValue channelsinfo(const UniValue& params, bool fHelp); -extern UniValue channelsbind(const UniValue& params, bool fHelp); extern UniValue channelsopen(const UniValue& params, bool fHelp); extern UniValue channelspayment(const UniValue& params, bool fHelp); -extern UniValue channelscollect(const UniValue& params, bool fHelp); -extern UniValue channelsstop(const UniValue& params, bool fHelp); +extern UniValue channelsclose(const UniValue& params, bool fHelp); extern UniValue channelsrefund(const UniValue& params, bool fHelp); //extern UniValue tokenswapask(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8f64d093d..c105b4872 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5153,42 +5153,21 @@ UniValue channelsopen(const UniValue& params, bool fHelp) return(result); } -UniValue channelsstop(const UniValue& params, bool fHelp) -{ - UniValue result(UniValue::VOBJ); std::vector destpub; struct CCcontract_info *cp,C; std::string hex; uint256 origtxid; - cp = CCinit(&C,EVAL_CHANNELS); - if ( fHelp || params.size() != 2 ) - throw runtime_error("channelsstop destpubkey origtxid\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); - destpub = ParseHex(params[0].get_str().c_str()); - origtxid = Parseuint256((char *)params[1].get_str().c_str()); - hex = ChannelStop(0,pubkey2pk(destpub),origtxid); - if ( hex.size() > 0 ) - { - result.push_back(Pair("result", "success")); - result.push_back(Pair("hex", hex)); - } else ERR_RESULT("couldnt create channelsstop transaction"); - return(result); -} - UniValue channelspayment(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 origtxid,prevtxid; int32_t n; int64_t amount; + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 opentxid,prevtxid; int32_t n; int64_t amount; cp = CCinit(&C,EVAL_CHANNELS); if ( fHelp || params.size() != 4 ) - throw runtime_error("channelspayment prevtxid origtxid n amount\n"); + throw runtime_error("channelspayment opentxid prevtxid amount\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); - prevtxid = Parseuint256((char *)params[0].get_str().c_str()); - origtxid = Parseuint256((char *)params[1].get_str().c_str()); + opentxid = Parseuint256((char *)params[0].get_str().c_str()); + prevtxid = Parseuint256((char *)params[1].get_str().c_str()); n = atoi((char *)params[2].get_str().c_str()); amount = atoi((char *)params[3].get_str().c_str()); - hex = ChannelPayment(0,prevtxid,origtxid,n,amount); + hex = ChannelPayment(0,opentxid,prevtxid,amount); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); @@ -5197,42 +5176,39 @@ UniValue channelspayment(const UniValue& params, bool fHelp) return(result); } -UniValue channelscollect(const UniValue& params, bool fHelp) +UniValue channelsclose(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 origtxid,paytxid; int32_t n; int64_t amount; + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 opentxid; cp = CCinit(&C,EVAL_CHANNELS); - if ( fHelp || params.size() != 4 ) - throw runtime_error("channelscollect paytxid origtxid n amount\n"); + if ( fHelp || params.size() != 2 ) + throw runtime_error("channelsclose opentxid\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); - paytxid = Parseuint256((char *)params[0].get_str().c_str()); - origtxid = Parseuint256((char *)params[1].get_str().c_str()); - n = atoi((char *)params[2].get_str().c_str()); - amount = atoi((char *)params[3].get_str().c_str()); - hex = ChannelCollect(0,paytxid,origtxid,n,amount); + opentxid = Parseuint256((char *)params[1].get_str().c_str()); + hex = ChannelClose(0,opentxid); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success")); result.push_back(Pair("hex", hex)); - } else ERR_RESULT("couldnt create channelscollect transaction"); + } else ERR_RESULT("couldnt create channelsstop transaction"); return(result); } UniValue channelsrefund(const UniValue& params, bool fHelp) { - UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 origtxid,stoptxid; + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::string hex; uint256 opentxid,closetxid; cp = CCinit(&C,EVAL_CHANNELS); if ( fHelp || params.size() != 2 ) - throw runtime_error("channelsrefund stoptxid origtxid\n"); + throw runtime_error("channelsrefund opentxid closetxid\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); - stoptxid = Parseuint256((char *)params[0].get_str().c_str()); - origtxid = Parseuint256((char *)params[1].get_str().c_str()); - hex = ChannelRefund(0,stoptxid,origtxid); + opentxid = Parseuint256((char *)params[0].get_str().c_str()); + closetxid = Parseuint256((char *)params[1].get_str().c_str()); + hex = ChannelRefund(0,opentxid,closetxid); if ( hex.size() > 0 ) { result.push_back(Pair("result", "success"));