Merge pull request #906 from Mixa84/channelCCFSM

Channel CC
This commit is contained in:
jl777
2018-10-09 03:50:34 -11:00
committed by GitHub
2 changed files with 45 additions and 16 deletions

View File

@@ -163,7 +163,6 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
numvins = tx.vin.size();
numvouts = tx.vout.size();
preventCCvins = preventCCvouts = -1;
fprintf(stderr,"validateCC\n");
if ( numvouts < 1 )
return eval->Invalid("no vouts");
else
@@ -207,15 +206,15 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
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.1 is CC for channelPayment!");
return eval->Invalid("vin.2 is CC for channelPayment!");
else if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("vout.0 is CC for channelPayment!");
else if ( tx.vout[1].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("vout.1 is CC for channelPayment (marker to srcPub)!");
else if ( tx.vout[2].scriptPubKey.IsPayToCryptoCondition() == 0 )
return eval->Invalid("vout.1 is CC for channelPayment (marker to dstPub)!");
return eval->Invalid("vout.2 is CC for channelPayment (marker to dstPub)!");
else if ( tx.vout[3].scriptPubKey.IsPayToCryptoCondition() != 0 )
return eval->Invalid("vout.1 is normal for channelPayment!");
return eval->Invalid("vout.3 is normal for channelPayment!");
else if ( tx.vout[3].scriptPubKey!=CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG)
return eval->Invalid("payment funds do not go to receiver!");
else if ( param1 > CHANNELS_MAXPAYMENTS)
@@ -353,8 +352,8 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
}
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"Channelsget validated\n");
else fprintf(stderr,"Channelsget invalid\n");
fprintf(stderr,"Channel tx validated\n");
else fprintf(stderr,"Channel tx invalid\n");
return(retval);
}
}
@@ -377,7 +376,7 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
}
else
{
fprintf(stderr,"invalid open txid\n");
fprintf(stderr,"invalid channel open txid\n");
return 0;
}
@@ -396,7 +395,6 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
}
if (txid!=zeroid && myIsutxo_spentinmempool(txid,0) != 0)
{
fprintf(stderr,"spent in mempool\n");
txid=zeroid;
int32_t mindepth=CHANNELS_MAXPAYMENTS;
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
@@ -428,7 +426,9 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment)
{
CMutableTransaction mtx; uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy; CPubKey mypk; struct CCcontract_info *cp,C;
CMutableTransaction mtx; uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy;
CPubKey mypk; struct CCcontract_info *cp,C;
if ( numpayments <= 0 || payment <= 0 || numpayments > CHANNELS_MAXPAYMENTS )
{
CCerror = strprintf("invalid ChannelOpen param numpayments.%d max.%d payment.%lld\n",numpayments,CHANNELS_MAXPAYMENTS,(long long)payment);
@@ -481,13 +481,12 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
{
if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O')
{
if (mypk != srcpub && mypk != destpub)
{
fprintf(stderr,"this is not our channel\n");
return("");
}
else if (amount % payment != 0)
else if (amount % payment != 0 || amount<payment)
{
fprintf(stderr,"invalid amount, not a magnitude of payment size\n");
return ("");
@@ -497,6 +496,15 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
((funcid = DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, prevdepth, param2, param3)) != 0) &&
(funcid == 'P' || funcid=='O'))
{
if (numpayments > prevdepth)
{
fprintf(stderr,"not enough funds in channel for that amount\n");
return ("");
} else if (numpayments == 0)
{
fprintf(stderr,"invalid amount\n");
return ("");
}
if (secret!=zeroid)
{
endiancpy(hash, (uint8_t * ) & secret, 32);
@@ -580,7 +588,7 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
}
if (mypk != srcpub)
{
fprintf(stderr,"this channel is not in our ownership\n");
fprintf(stderr,"cannot close, you are not channel owner\n");
return("");
}
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
@@ -628,7 +636,6 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
}
if (txid!=opentxid)
{
fprintf(stderr,"%s - %s\n",txid.ToString().c_str(),opentxid.ToString().c_str());
fprintf(stderr, "open and close txid are not from same channel\n");
return ("");
}
@@ -644,14 +651,15 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
}
if (mypk != srcpub)
{
fprintf(stderr,"this channel is not in our ownership\n");
fprintf(stderr,"cannot refund, you are not the channel owenr\n");
return("");
}
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
{
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && funds-txfee>0)
{
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 && DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3) != 0)
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 &&
DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3) != 0)
{
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
endiancpy(hash, (uint8_t * ) & hentropy, 32);
@@ -736,7 +744,8 @@ UniValue ChannelsInfo(uint256 channeltxid)
}
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'P' && opentxid==channeltxid)
{
if (GetTransaction(opentxid,opentx,hashBlock,false) != 0 && (numvouts=opentx.vout.size()) > 0 && DecodeChannelsOpRet(opentx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,numpayments,payment,hashchain) == 'O')
if (GetTransaction(opentxid,opentx,hashBlock,false) != 0 && (numvouts=opentx.vout.size()) > 0 &&
DecodeChannelsOpRet(opentx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,numpayments,payment,hashchain) == 'O')
{
Getscriptaddress(str2,tx.vout[3].scriptPubKey);
sprintf(str1,"%lld satoshi to %s, %lld payments left",(long long)(param2*payment),str2,(long long)param1);

View File

@@ -5146,8 +5146,23 @@ UniValue channelsopen(const UniValue& params, bool fHelp)
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
destpub = ParseHex(params[0].get_str().c_str());
if (destpub.size()!= 33)
{
ERR_RESULT("invalid destination pubkey");
return result;
}
numpayments = atoi(params[1].get_str().c_str());
if (numpayments <1)
{
ERR_RESULT("invalid number of payments, must be greater than 0");
return result;
}
payment = atol(params[2].get_str().c_str());
if (payment <1)
{
ERR_RESULT("invalid payment amount, must be greater than 0");
return result;
}
hex = ChannelOpen(0,pubkey2pk(destpub),numpayments,payment);
if ( hex.size() > 0 )
{
@@ -5169,6 +5184,11 @@ UniValue channelspayment(const UniValue& params, bool fHelp)
LOCK2(cs_main, pwalletMain->cs_wallet);
opentxid = Parseuint256((char *)params[0].get_str().c_str());
amount = atoi((char *)params[1].get_str().c_str());
if (amount <1)
{
ERR_RESULT("invalid payment amount, must be greater than 0");
return result;
}
if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty())
{
secret = Parseuint256((char *)params[2].get_str().c_str());