From 5955955d188f063f9375f2ee4a054ad9f233bd89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Sep 2018 03:49:09 -1100 Subject: [PATCH] gatewayspending --- src/cc/CCGateways.h | 1 + src/cc/gateways.cpp | 98 +++++++++++++++++++++++++++++++++++++--- src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + src/wallet/rpcwallet.cpp | 12 +++++ 5 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/cc/CCGateways.h b/src/cc/CCGateways.h index b7c653ef3..e7ab74601 100644 --- a/src/cc/CCGateways.h +++ b/src/cc/CCGateways.h @@ -25,6 +25,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vectorproof,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 withdrawpub,int64_t amount); +UniValue GatewaysPendingWithdraws(std::string refcoin,uint256 bindtxid); // CCcustom UniValue GatewaysInfo(uint256 bindtxid); diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index 9cfe9c4c9..df51e57bc 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -16,7 +16,7 @@ #include "CCGateways.h" /* - prevent duplicate bindtxid and cointxid via mempool scan + prevent duplicate bindtxid via mempool scan wait for notarization for oraclefeed and validation of gatewaysdeposit gatewayswithdraw @@ -122,8 +122,19 @@ string oracles gatewayswithdraw bindtxid coin withdrawpub amount ./c gatewayswithdraw e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD 03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828 1 + ef3cc452da006eb2edda6b6ed3d3347664be51260f3e91f59ec44ec9701367f0 + + Now there is a withdraw pending, so it needs to be processed by the signing nodes on the KMD side */ + +int32_t GatewaysAddQueue(std::string coin,uint256 txid,CScript scriptPubKey,int64_t nValue) +{ + char destaddr[64],str[65]; + GetScriptAddress(destaddr,scriptPubKey); + fprintf(stderr,"GatewaysAddQueue: %s %s %s %.8f\n",coin.c_str(),uint256_str(str,txid),destaddr,(double)nValue/COIN); +} + // start of consensus code CScript EncodeGatewaysBindOpRet(uint8_t funcid,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector pubkeys,uint8_t taddr,uint8_t prefix,uint8_t prefix2) @@ -318,18 +329,40 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 return(0); } +static int32_t myIs_coinaddr_inmempoolvout(char *coinaddr) +{ + int32_t i,n; char destaddr[64]; + BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx) + { + const CTransaction &tx = e.GetTx(); + if ( (n= tx.vout.size()) > 0 ) + { + const uint256 &txid = tx.GetHash(); + for (i=0; i > addressIndex; CCtxidaddr(txidaddr,cointxid); - fprintf(stderr," txidaddr.(%s) need to scan mempool also\n",txidaddr); SetCCtxids(addressIndex,txidaddr); for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { return(-1); } - return(0); + return(myIs_coinaddr_inmempoolvout(txidaddr)); } UniValue GatewaysInfo(uint256 bindtxid) @@ -707,7 +740,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin fprintf(stderr,"invalid bindtxid %s coin.%s\n",uint256_str(str,bindtxid),coin.c_str()); return(""); } - if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 ) + if ( AddNormalinputs(mtx,mypk,3*txfee,3) > 0 ) { if ( (inputs= AddAssetInputs(assetscp,mtx,mypk,assetid,amount,60)) > 0 ) { @@ -715,6 +748,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin CCchange = (inputs - amount); mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,amount,gatewayspk)); mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG)); + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG)); if ( CCchange != 0 ) mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk)); return(FinalizeCCTx(0,assetscp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey()))); @@ -724,6 +758,58 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin return(""); } -// withdrawtxid used on external chain to create baton address, its existence in mempool (along with the withdraw) proof that the withdraw is pending - +UniValue GatewaysPendingWithdraws(std::string refcoin,uint256 bindtxid) +{ + UniValue result(UniValue::VOBJ),pending(UniValue:VARR),obj(UniValue:VOBJ); CTransaction tx; std::string coin; CPubKey mypk,gatewayspk; std::vector 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]; int32_t i,n,numvouts,vout,numqueued,(i=0; i > unspentOutputs; + cp = CCinit(&C,EVAL_GATEWAYS); + mypk = pubkey2pk(Mypubkey()); + gatewayspk = GetUnspendable(cp,0); + _GetCCaddress(coinaddr,EVAL_ASSETS,gatewayspk); + if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) + { + fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid)); + return(result); + } + if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,coin,assetid,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2) != 'B' || coin != refcoin ) + { + fprintf(stderr,"invalid bindtxid %s coin.%s\n",uint256_str(str,bindtxid),coin.c_str()); + return(result); + } + n = msigpubkeys.size(); + queueflag = 0; + for (i=0; i >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + if ( GetTransaction(txid,tx,hashBlock,false) != 0 ) + { + Getscriptaddress(destaddr,tx.vout[0].scriptPubKey); + Getscriptaddress(withaddr,tx.vout[1].scriptPubKey); + if ( strcmp(destaddr,coinaddr) == 0 ) + { + obj.push_back("txid",uint256_str(str,txid)); + obj.push_back("withdrawaddr",withaddr); + sprintf(numstr,"%.8f",(double)tx.vout[0].nValue/COIN); + obj.push_back("amount",numstr); + pending.push_back(obj); + if ( queueflag != 0 ) + numqueued += GatewaysAddQueue(refcoin,txid,tx.vout[1].scriptPubKey,tx.vout[0].nValue); + } + } + } + result.push_back(Pair("coin",refcoin)); + result.push_back(Pair("pending",pending)); + result.push_back(Pair("queueflag",queueflag)); + return(result); +} diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index ee1d51568..49b7d529c 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -417,6 +417,7 @@ static const CRPCCommand vRPCCommands[] = { "gateways", "gatewaysdeposit", &gatewaysdeposit, true }, { "gateways", "gatewaysclaim", &gatewaysclaim, true }, { "gateways", "gatewayswithdraw", &gatewayswithdraw, true }, + { "gateways", "gatewayspending", &gatewayspending, true }, /* dice */ { "dice", "dicelist", &dicelist, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 0061956ba..bb3266881 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -242,6 +242,7 @@ extern UniValue gatewaysbind(const UniValue& params, bool fHelp); extern UniValue gatewaysdeposit(const UniValue& params, bool fHelp); extern UniValue gatewaysclaim(const UniValue& params, bool fHelp); extern UniValue gatewayswithdraw(const UniValue& params, bool fHelp); +extern UniValue gatewayspending(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); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index df2edee04..eee5e0594 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5512,6 +5512,18 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp) return(result); } +UniValue gatewayspending(const UniValue& params, bool fHelp) +{ + uint256 bindtxid; std::string coin; + if ( fHelp || params.size() != 2 ) + throw runtime_error("gatewayspending bindtxid coin\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"); + bindtxid = Parseuint256((char *)params[0].get_str().c_str()); + coin = params[1].get_str(); + return(GatewaysPendingWithdraws(bindtxid,coin)); +} + UniValue oracleslist(const UniValue& params, bool fHelp) { if ( fHelp || params.size() > 0 )