Prepare to create settlement tx
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#define MARMARA_MINLOCK (1440 * 3 * 30)
|
||||
#define MARMARA_MAXLOCK (1440 * 24 * 30)
|
||||
|
||||
extern uint8_t ASSETCHAINS_MARMARA;
|
||||
uint64_t komodo_block_prg(uint32_t nHeight);
|
||||
int32_t MarmaraGetcreatetxid(uint256 &createtxid,uint256 txid);
|
||||
int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,uint256 txid);
|
||||
|
||||
@@ -245,6 +245,8 @@ int32_t MarmaraValidateCoinbase(int32_t height,CTransaction tx)
|
||||
bool MarmaraValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
std::vector<uint8_t> vopret; CTransaction vinTx; uint256 hashBlock; int32_t numvins,numvouts,i,ht,unlockht,vht,vunlockht; uint8_t funcid,vfuncid,*script; CPubKey pk,vpk;
|
||||
if ( ASSETCHAINS_MARMARA == 0 )
|
||||
return eval->Invalid("-ac_marmara must be set for marmara CC");
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
if ( numvouts < 1 )
|
||||
@@ -344,6 +346,116 @@ int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount,remaining,change,avail; CPubKey Marmarapk,mypk,pk; std::string currency,refcurrency,rawtx; CTransaction tx,batontx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
cp = CCinit(&C,EVAL_MARMARA);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Marmarapk = GetUnspendable(cp,0);
|
||||
remaining = change = 0;
|
||||
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
|
||||
{
|
||||
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
|
||||
{
|
||||
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
|
||||
{
|
||||
if ( refcreatetxid != creditloop[0] )
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"invalid refcreatetxid, setting to creditloop[0]"));
|
||||
return(result);
|
||||
}
|
||||
if ( chainActive.LastTip()->GetHeight() < refmatures )
|
||||
{
|
||||
fprintf(stderr,"doesnt mature for another %d blocks\n",refmatures - chainActive.LastTip()->GetHeight())'
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"cant settle immature creditloop"));
|
||||
return(result);
|
||||
}
|
||||
remaining = refamount;
|
||||
GetCCaddress(cp,myCCaddr,Mypubkey());
|
||||
Getscriptaddress(batonCCaddr,batontx.vout[0].scriptPubKey);
|
||||
if ( strcmp(myCCaddr,batonCCaddr) == 0 )
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(batontxid,0,CScript()));
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
|
||||
{
|
||||
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
|
||||
avail = CCaddress_balance(coinaddr);
|
||||
if ( avail > remaining )
|
||||
{
|
||||
// add remaining
|
||||
change = (avail - remaining);
|
||||
mtx.vout.push_back(CTxOut(amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
if ( change > txfee )
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_MARMARA,change,Marmarapk,pk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('S',createtxid,mypk,amount,matures,currency));
|
||||
result.push_back(Pair("result",(char *)"success"));
|
||||
result.push_back(Pair("rawtx",rawtx));
|
||||
return(result);
|
||||
}
|
||||
else if ( avail > txfee )
|
||||
{
|
||||
// add all utxos
|
||||
remaining -= avail;
|
||||
}
|
||||
fprintf(stderr,"get locked funds of %s %.8f\n",coinaddr,(double)avail/COIN);
|
||||
} else fprintf(stderr,"null funcid for creditloop[%d]\n",i);
|
||||
} else fprintf(stderr,"couldnt get creditloop[%d]\n",i);
|
||||
}
|
||||
if ( amount - remaining > 2*txfee )
|
||||
{
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr,createtxid))) << OP_CHECKSIG)); // failure marker
|
||||
if ( amount-remaining > 3*txfee )
|
||||
mtx.vout.push_back(CTxOut(amount-remaining-2*txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,MarmaraLoopOpret('S',createtxid,mypk,amount-remaining,-remaining,currency));
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"insufficient funds"));
|
||||
result.push_back(Pair("rawtx",rawtx));
|
||||
result.push_back(Pair("remaining",ValueFromAmount(remaining)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// jl777: maybe fund a txfee to report no funds avail
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"no funds available at all"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"this node does not have the baton"));
|
||||
result.push_back(Pair("myCCaddr",myCCaddr));
|
||||
result.push_back(Pair("batonCCaddr",batonCCaddr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"couldnt get batontxid opret"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"couldnt find batontxid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"couldnt get creditloop"));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
int32_t MarmaraGetCreditloops(int64_t &totalamount,std::vector<uint256> &issuances,struct CCcontract_info *cp,int32_t firstheight,int32_t lastheight,int64_t minamount,int64_t maxamount,CPubKey refpk,std::string refcurrency)
|
||||
{
|
||||
char coinaddr[64]; CPubKey Marmarapk,senderpk; int64_t amount; uint256 createtxid,txid,hashBlock; CTransaction tx; int32_t numvouts,vout,matures,n=0; std::string currency;
|
||||
@@ -489,70 +601,6 @@ UniValue MarmaraIssue(uint64_t txfee,uint8_t funcid,CPubKey receiverpk,int64_t a
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue MarmaraSettlement(uint64_t txfee,uint256 refbatontxid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey Marmarapk,pk; std::string currency,refcurrency; CTransaction tx,batontx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
cp = CCinit(&C,EVAL_MARMARA);
|
||||
Marmarapk = GetUnspendable(cp,0);
|
||||
if ( (n= MarmaraGetbatontxid(creditloop,batontxid,refbatontxid)) > 0 )
|
||||
{
|
||||
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && (numvouts= batontx.vout.size()) > 1 )
|
||||
{
|
||||
if ( (funcid= MarmaraDecodeLoopOpret(batontx.vout[numvouts-1].scriptPubKey,refcreatetxid,pk,refamount,refmatures,refcurrency)) != 0 )
|
||||
{
|
||||
if ( refcreatetxid != creditloop[0] )
|
||||
{
|
||||
fprintf(stderr,"invalid refcreatetxid, setting to creditloop[0]\n");
|
||||
refcreatetxid = creditloop[0];
|
||||
numerrs++;
|
||||
}
|
||||
GetCCaddress(cp,myCCaddr,Mypubkey());
|
||||
Getscriptaddress(batonCCaddr,batontx.vout[0].scriptPubKey);
|
||||
if ( strcmp(myCCaddr,batonCCaddr) == 0 )
|
||||
{
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ( GetTransaction(creditloop[i],tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
if ( (funcid= MarmaraDecodeLoopOpret(tx.vout[numvouts-1].scriptPubKey,createtxid,pk,amount,matures,currency)) != 0 )
|
||||
{
|
||||
GetCCaddress1of2(cp,coinaddr,Marmarapk,pk);
|
||||
//make tx here
|
||||
fprintf(stderr,"get locked funds of %s %.8f\n",coinaddr,(double)CCaddress_balance(coinaddr)/COIN);
|
||||
} else fprintf(stderr,"null funcid for creditloop[%d]\n",i);
|
||||
} else fprintf(stderr,"couldnt get creditloop[%d]\n",i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"this node does not have the baton"));
|
||||
result.push_back(Pair("myCCaddr",myCCaddr));
|
||||
result.push_back(Pair("batonCCaddr",batonCCaddr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"couldnt get batontxid opret"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"couldnt find batontxid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result",(char *)"error"));
|
||||
result.push_back(Pair("error",(char *)"couldnt get creditloop"));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue MarmaraCreditloop(uint256 txid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector<uint256> creditloop; uint256 batontxid,createtxid,refcreatetxid,hashBlock; uint8_t funcid; int32_t numerrs=0,i,n,numvouts,matures,refmatures; int64_t amount,refamount; CPubKey pk; std::string currency,refcurrency; CTransaction tx; char coinaddr[64],myCCaddr[64],destaddr[64],batonCCaddr[64],str[2]; struct CCcontract_info *cp,C;
|
||||
|
||||
@@ -643,6 +643,10 @@ int32_t komodo_isPoS(CBlock *pblock)
|
||||
{
|
||||
txid = pblock->vtx[n-1].vin[0].prevout.hash;
|
||||
vout = pblock->vtx[n-1].vin[0].prevout.n;
|
||||
if ( ASSETCHAINS_MARMARA != 0 )
|
||||
{
|
||||
// need to verify it was signed by the non-Marmarapk of the 1of2
|
||||
}
|
||||
txtime = komodo_txtime(&value,txid,vout,destaddr);
|
||||
if ( ExtractDestination(pblock->vtx[n-1].vout[0].scriptPubKey,voutaddress) )
|
||||
{
|
||||
@@ -2112,34 +2116,42 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
maxkp = numkp = 0;
|
||||
lasttime = 0;
|
||||
}
|
||||
BOOST_FOREACH(const COutput& out, vecOutputs)
|
||||
if ( ASSETCHAINS_MARMARA == 0 || 1 )
|
||||
{
|
||||
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
|
||||
BOOST_FOREACH(const COutput& out, vecOutputs)
|
||||
{
|
||||
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
|
||||
return(0);
|
||||
}
|
||||
counter++;
|
||||
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
|
||||
{
|
||||
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
|
||||
continue;
|
||||
}
|
||||
CAmount nValue = out.tx->vout[out.i].nValue;
|
||||
if ( nValue < COIN || !out.fSpendable )
|
||||
continue;
|
||||
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
|
||||
if ( ExtractDestination(pk,address) != 0 )
|
||||
{
|
||||
if ( IsMine(*pwalletMain,address) == 0 )
|
||||
continue;
|
||||
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
|
||||
if ( (tipindex= chainActive.Tip()) == 0 || tipindex->GetHeight()+1 > nHeight )
|
||||
{
|
||||
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
|
||||
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
|
||||
fprintf(stderr,"chain tip changed during staking loop t.%u counter.%d\n",(uint32_t)time(NULL),counter);
|
||||
return(0);
|
||||
}
|
||||
counter++;
|
||||
if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth )
|
||||
{
|
||||
fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth);
|
||||
continue;
|
||||
}
|
||||
CAmount nValue = out.tx->vout[out.i].nValue;
|
||||
if ( nValue < COIN || !out.fSpendable )
|
||||
continue;
|
||||
const CScript& pk = out.tx->vout[out.i].scriptPubKey;
|
||||
if ( ExtractDestination(pk,address) != 0 )
|
||||
{
|
||||
if ( IsMine(*pwalletMain,address) == 0 )
|
||||
continue;
|
||||
if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 )
|
||||
{
|
||||
array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk);
|
||||
//fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// calc 1of2 address
|
||||
// iterate all unspents not spent in mempool and komodo_addutxo
|
||||
}
|
||||
lasttime = (uint32_t)time(NULL);
|
||||
//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp);
|
||||
}
|
||||
@@ -2218,7 +2230,14 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
||||
txNew.vout[0].nValue = *utxovaluep - txfee;
|
||||
txNew.nLockTime = earliest;
|
||||
CTransaction txNewConst(txNew);
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
|
||||
if ( ASSETCHAINS_MARMARA == 0 || 1 )
|
||||
{
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, *utxovaluep, SIGHASH_ALL), best_scriptPubKey, sigdata, consensusBranchId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// signSuccess = CCFinalizetx(...)
|
||||
}
|
||||
if (!signSuccess)
|
||||
fprintf(stderr,"failed to create signature\n");
|
||||
else
|
||||
|
||||
@@ -5554,7 +5554,7 @@ UniValue marmara_receive(const UniValue& params, bool fHelp)
|
||||
if ( fHelp || (params.size() != 5 && params.size() != 4) )
|
||||
{
|
||||
// 1st marmarareceive 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1440
|
||||
// after marmarareceive 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 3903 bf6b4d42aa3ce974c853d73b06c78597dd3b5fb493d5d0d944f72c2017f561ad
|
||||
// after marmarareceive 039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775 7.5 MARMARA 1168 d72d87aa0d50436de695c93e2bf3d7273c63c92ef6307913aa01a6ee6a16548b
|
||||
throw runtime_error("marmarareceive senderpk amount currency matures batontxid\n");
|
||||
}
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5604,7 +5604,7 @@ UniValue marmara_transfer(const UniValue& params, bool fHelp)
|
||||
UniValue result(UniValue::VOBJ); uint256 approvaltxid,batontxid; std::vector<uint8_t> receiverpub; int64_t amount; int32_t matures; std::string currency; std::vector<uint256> creditloop;
|
||||
if ( fHelp || params.size() != 5 )
|
||||
{
|
||||
// marmaratransfer 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 3903 748a4c80e6f6b725340fb0f52738f38a11c422d59b3034c8366b3d7b33c99a1e
|
||||
// marmaratransfer 028076d42eb20efc10007fafb5ca66a2052523c0d2221e607adf958d1a332159f6 7.5 MARMARA 1168 1506c774e4b2804a6e25260920840f4cfca8d1fb400e69fe6b74b8e593dbedc5
|
||||
throw runtime_error("marmaratransfer receiverpk amount currency matures approvaltxid\n");
|
||||
}
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
@@ -5674,7 +5674,7 @@ UniValue marmara_settlement(const UniValue& params, bool fHelp)
|
||||
if ( fHelp || params.size() != 1 )
|
||||
{
|
||||
// marmarasettlement 010ff7f9256cefe3b5dee3d72c0eeae9fc6f34884e6f32ffe5b60916df54a9be
|
||||
// marmarasettlement cc23bf81733556dc06db2fd9c9f4178cad44bdc237d6e62101cf0cdafb5195f7
|
||||
// marmarasettlement ff3e259869196f3da9b5ea3f9e088a76c4fc063cf36ab586b652e121d441a603
|
||||
throw runtime_error("marmarasettlement batontxid\n");
|
||||
}
|
||||
if ( ensure_CCrequirements() < 0 )
|
||||
|
||||
Reference in New Issue
Block a user