-modified ChannelsExactAmount

-fixes
This commit is contained in:
Mihailo Milenkovic
2018-10-01 18:24:14 +02:00
parent bd632043f2
commit 7f0ed443f1
4 changed files with 109 additions and 74 deletions

View File

@@ -27,6 +27,6 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid);
std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid); std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid);
// CCcustom // CCcustom
UniValue ChannelsInfo(); UniValue ChannelsInfo(char *);
#endif #endif

View File

@@ -111,7 +111,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
{ {
privkey = myprivkey; privkey = myprivkey;
cond = mycond; cond = mycond;
fprintf(stderr,"my CC addr.(%s)\n",myaddr);
} }
else if ( strcmp(destaddr,unspendable) == 0 ) else if ( strcmp(destaddr,unspendable) == 0 )
{ {

View File

@@ -75,6 +75,19 @@ int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey
return(0); return(0);
} }
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
{
char destaddr[64],ccaddr[64];
GetCCaddress(cp,ccaddr,srcpub);
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
{
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,ccaddr) == 0 )
return(tx.vout[v].nValue);
}
return(0);
}
CScript EncodeChannelsOpRet(uint8_t funcid,uint256 opentxid,CPubKey srcpub,CPubKey destpub,int32_t numpayments,int64_t payment,uint256 hashchain) CScript EncodeChannelsOpRet(uint8_t funcid,uint256 opentxid,CPubKey srcpub,CPubKey destpub,int32_t numpayments,int64_t payment,uint256 hashchain)
{ {
CScript opret; uint8_t evalcode = EVAL_CHANNELS; CScript opret; uint8_t evalcode = EVAL_CHANNELS;
@@ -110,24 +123,15 @@ bool ChannelsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
numvins = tx.vin.size(); numvins = tx.vin.size();
numvouts = tx.vout.size(); numvouts = tx.vout.size();
if ((numvouts=tx.vout.size()) > 0 && (funcid=DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3)) !=0) if ((numvouts=tx.vout.size()) > 0 && DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3)!=0)
{ {
for (i=0; i<numvins; i++) for (i=0; i<numvins; i++)
{ {
//fprintf(stderr,"vini.%d\n",i); if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 ) return eval->Invalid("cant find vinTx");
else
{ {
//fprintf(stderr,"vini.%d check mempool\n",i); inputs += vinTx.vout[tx.vin[i].prevout.n].nValue;
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
return eval->Invalid("cant find vinTx");
else
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant Channels from mempool");
if ( (assetoshis= IsChannelsvout(cp,vinTx,srcpub,destpub,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
} }
} }
} }
@@ -137,9 +141,7 @@ bool ChannelsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
} }
for (i=0; i<numvouts; i++) for (i=0; i<numvouts; i++)
{ {
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts); outputs += tx.vout[i].nValue;
if ( (assetoshis= IsChannelsvout(cp,tx,srcpub,destpub,i)) != 0 )
outputs += assetoshis;
} }
if ( inputs != outputs+txfee ) if ( inputs != outputs+txfee )
{ {
@@ -166,8 +168,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
return eval->Invalid("no vouts"); return eval->Invalid("no vouts");
else else
{ {
//fprintf(stderr,"check amounts\n"); if (ChannelsExactAmounts(cp,eval,tx,1,10000) == false )
if ( 0) //ChannelsExactAmounts(cp,eval,tx,1,10000) == false )
{ {
fprintf(stderr,"Channelsget invalid amount\n"); fprintf(stderr,"Channelsget invalid amount\n");
return false; return false;
@@ -364,7 +365,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 funcid,param1; char coinaddr[64]; 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];
@@ -386,14 +387,14 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
{ {
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3)!=0 && if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,param1,param2,param3)!=0 &&
(tmp_txid==openTx.GetHash() || tx.GetHash()==openTx.GetHash()) && (tmp_txid==openTx.GetHash() || tx.GetHash()==openTx.GetHash()) &&
(totalinputs=IsChannelsvout(cp,tx,srcpub,destpub,0)+IsChannelsvout(cp,tx,srcpub,destpub,1))>0) (totalinputs=IsChannelsvout(cp,tx,srcpub,destpub,0)+IsChannelsMarkervout(cp,tx,srcpub,1))>0)
{ {
txid = it->first.txhash; txid = it->first.txhash;
break; break;
} }
} }
} }
if (myIsutxo_spentinmempool(txid,0) != 0) if (txid!=zeroid && myIsutxo_spentinmempool(txid,0) != 0)
{ {
fprintf(stderr,"spent in mempool\n"); fprintf(stderr,"spent in mempool\n");
txid=zeroid; txid=zeroid;
@@ -476,7 +477,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
} }
if (AddNormalinputs(mtx,mypk,2*txfee,1) > 0) if (AddNormalinputs(mtx,mypk,2*txfee,1) > 0)
{ {
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && (change=funds-amount)>=0) if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && (change=funds-amount-txfee)>=0)
{ {
if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O') if ((numvouts=channelOpenTx.vout.size()) > 0 && DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, totalnumpayments, payment, hashchain)=='O')
{ {
@@ -505,7 +506,6 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
memcpy(hash, hashdest, 32); memcpy(hash, hashdest, 32);
} }
endiancpy((uint8_t * ) & gensecret, hashdest, 32); endiancpy((uint8_t * ) & gensecret, hashdest, 32);
fprintf(stderr, "%d %d %d %s %s\n",(int)(totalnumpayments-(prevdepth-numpayments)),(int)prevdepth,(int)numpayments,gensecret.ToString().c_str(),hashchain.ToString().c_str());
if (gensecret!=hashchain) if (gensecret!=hashchain)
{ {
fprintf(stderr,"invalid secret supplied\n"); fprintf(stderr,"invalid secret supplied\n");
@@ -515,13 +515,17 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
else else
{ {
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash); hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
endiancpy(hash, (uint8_t * ) & hentropy, 32); if (prevdepth-numpayments)
for (i = 0; i < prevdepth-numpayments; i++)
{ {
vcalc_sha256(0, hashdest, hash, 32); endiancpy(hash, (uint8_t * ) & hentropy, 32);
memcpy(hash, hashdest, 32); for (i = 0; i < prevdepth-numpayments; i++)
{
vcalc_sha256(0, hashdest, hash, 32);
memcpy(hash, hashdest, 32);
}
endiancpy((uint8_t * ) & secret, hashdest, 32);
} }
endiancpy((uint8_t * ) & secret, hashdest, 32); else endiancpy((uint8_t * ) & secret, (uint8_t * ) & hentropy, 32);
} }
} }
else else
@@ -581,9 +585,9 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid)
} }
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 ) if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
{ {
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0) if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=0 && funds-txfee>0)
{ {
mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, funds, mypk, destpub)); mtx.vout.push_back(MakeCC1of2vout(EVAL_CHANNELS, funds-txfee, mypk, destpub));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',opentxid,mypk,destpub,funds/payment,payment,zeroid))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('C',opentxid,mypk,destpub,funds/payment,payment,zeroid)));
@@ -645,7 +649,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
} }
if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 ) if ( AddNormalinputs(mtx,mypk,2*txfee,1) > 0 )
{ {
if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid)) !=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)
{ {
@@ -659,7 +663,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
endiancpy((uint8_t * ) & secret, hashdest, 32); endiancpy((uint8_t * ) & secret, hashdest, 32);
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,mypk));
mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub)); mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,txfee,destpub));
mtx.vout.push_back(CTxOut(funds,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); mtx.vout.push_back(CTxOut(funds-txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',opentxid,mypk,destpub,param1,payment,closetxid))); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeChannelsOpRet('R',opentxid,mypk,destpub,param1,payment,closetxid)));
} }
else else
@@ -677,52 +681,79 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
return(""); return("");
} }
UniValue ChannelsInfo() UniValue ChannelsInfo(char *CCaddr)
{ {
UniValue result(UniValue::VOBJ); CTransaction tx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain; struct CCcontract_info *cp,C; char myCCaddr[64],addr[64],str1[100],str2[100]; int32_t vout,numvouts,param1,numpayments; int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk; 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;
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids; std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
result.push_back(Pair("result","success")); result.push_back(Pair("result","success"));
result.push_back(Pair("name","Channel Info"));
cp = CCinit(&C,EVAL_CHANNELS); cp = CCinit(&C,EVAL_CHANNELS);
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
GetCCaddress(cp,myCCaddr,mypk); if (strcmp(CCaddr,"")==0)
SetCCtxids(txids,myCCaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{ {
//int height = it->first.blockHeight; result.push_back(Pair("name","Channels Info"));
txid = it->first.txhash; GetCCaddress(cp,myCCaddr,mypk);
vout = (int32_t)it->first.index; SetCCtxids(txids,myCCaddr);
nValue = (int64_t)it->second; for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
if ( (vout==0 || vout == 1 || vout == 2) && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
{ {
if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'O') //int height = it->first.blockHeight;
txid = it->first.txhash;
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second;
if ( (vout == 1 || vout == 2) && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
{ {
GetCCaddress1of2(cp,addr,srcpub,destpub); if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'O')
sprintf(str1,"Channel - %s",addr); {
result.push_back(Pair(str1,"Open")); GetCCaddress1of2(cp,addr,srcpub,destpub);
sprintf(str1,"%s - %lld payments of %lld satoshi",addr,(long long)param1,(long long)param2);
result.push_back(Pair("Channel", str1));
}
} }
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'P') }
}
else
{
sprintf(str1,"Channel %s",CCaddr);
result.push_back(Pair("name",str1));
strcpy(myCCaddr,CCaddr);
SetCCtxids(txids,myCCaddr);
prevtxid=zeroid;
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
//int height = it->first.blockHeight;
txid = it->first.txhash;
nValue = (int64_t)it->second;
if (txid!=prevtxid && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
{ {
if (GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,tmp_txid,srcpub,destpub,numpayments,payment,hashchain) == 'O') if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'O')
sprintf(str1,"Channel - %s",addr); {
sprintf(str2,"Payment -> %s %lld payments of %lld",destpub.GetHash().ToString().c_str(),(long long)param2,(long long)payment); sprintf(str1,"%lld payments of %lld satoshi",(long long)param1,(long long)param2);
result.push_back(Pair(str1,str2)); result.push_back(Pair("Open", str1));
} }
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'C') else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'P')
{ {
GetCCaddress1of2(cp,addr,srcpub,destpub); 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')
sprintf(str1,"Channel - %s",addr); {
result.push_back(Pair(str1,"Close")); Getscriptaddress(str2,tx.vout[3].scriptPubKey);
} sprintf(str1,"%lld satoshi to %s, %lld payments left",(long long)(param2*payment),str2,(long long)param1);
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'C') result.push_back(Pair("Payment",str1));
{ }
GetCCaddress1of2(cp,addr,srcpub,destpub); }
sprintf(str1,"Channel - %s",addr); else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'C')
sprintf(str2,"Refund -> %s %lld payments of %lld",srcpub.GetHash().ToString().c_str(),(long long)param1,(long long)param2); {
result.push_back(Pair(str1,"Refund")); result.push_back(Pair("Close","channel"));
}
else if (DecodeChannelsOpRet(tx.vout[numvouts-1].scriptPubKey,opentxid,srcpub,destpub,param1,param2,param3) == 'R')
{
Getscriptaddress(str2,tx.vout[2].scriptPubKey);
sprintf(str1,"%lld satoshi back to %s",(long long)(param1*param2),str2);
result.push_back(Pair("Refund",str1));
}
} }
prevtxid=txid;
} }
} }
return(result); return(result);
} }

View File

@@ -5124,11 +5124,15 @@ UniValue tokenaddress(const UniValue& params, bool fHelp)
UniValue channelsinfo(const UniValue& params, bool fHelp) UniValue channelsinfo(const UniValue& params, bool fHelp)
{ {
if ( fHelp || params.size() != 0 ) char addr[100];
if ( fHelp || params.size() > 1 )
throw runtime_error("channelsinfo\n"); throw runtime_error("channelsinfo\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");
return(ChannelsInfo()); strcpy(addr,"");
if (params.size() > 0 && !params[0].isNull() && !params[0].get_str().empty())
strcpy(addr,params[0].get_str().c_str());
return(ChannelsInfo(addr));
} }
UniValue channelsopen(const UniValue& params, bool fHelp) UniValue channelsopen(const UniValue& params, bool fHelp)