Prepare to create settlement tx

This commit is contained in:
jl777
2019-01-15 23:22:00 -11:00
parent 8ef46649e5
commit e1037c704c
4 changed files with 158 additions and 90 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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 )