@@ -1,8 +1,9 @@
|
||||
package=boost
|
||||
$(package)_version=1_69_0
|
||||
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.69.0/source
|
||||
|
||||
$(package)_version=1_66_0
|
||||
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.66.0/source
|
||||
$(package)_sha256_hash=5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts_release=variant=release
|
||||
|
||||
@@ -170,7 +170,7 @@ static int32_t ignorevin;
|
||||
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
|
||||
int32_t is_hexstr(char *str,int32_t n);
|
||||
bool myAddtomempool(CTransaction &tx, CValidationState *pstate = NULL, bool fSkipExpiry = false);
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag);
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag);
|
||||
bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout);
|
||||
bool mytxid_inmempool(uint256 txid);
|
||||
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
|
||||
|
||||
@@ -347,17 +347,29 @@ int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag)
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag)
|
||||
{
|
||||
CCoins coins;
|
||||
//fprintf(stderr,"CCgettxoud %s/v%d\n",txid.GetHex().c_str(),vout);
|
||||
if ( mempoolflag != 0 )
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
||||
if (!view.GetCoins(txid, coins))
|
||||
return(-1);
|
||||
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
|
||||
return(-1);
|
||||
if ( lockflag != 0 )
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
||||
if (!view.GetCoins(txid, coins))
|
||||
return(-1);
|
||||
else if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
||||
if (!view.GetCoins(txid, coins))
|
||||
return(-1);
|
||||
else if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -87,6 +87,7 @@ CClib_methods[] =
|
||||
{ (char *)"dilithium", (char *)"verify", (char *)"pubtxid msg sig", 3, 3, 'V', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"send", (char *)"handle pubtxid amount", 3, 3, 'x', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"spend", (char *)"sendtxid scriptPubKey [hexseed]", 2, 3, 'y', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"Qsend", (char *)"mypubtxid hexseed/'mypriv' destpubtxid,amount, ...", 4, 66, 'Q', EVAL_DILITHIUM },
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -134,6 +135,7 @@ UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
|
||||
UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -261,7 +263,9 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
|
||||
}
|
||||
else if ( cp->evalcode == EVAL_DILITHIUM )
|
||||
{
|
||||
if ( strcmp(method,"send") == 0 )
|
||||
if ( strcmp(method,"Qsend") == 0 )
|
||||
return(dilithium_Qsend(txfee,cp,params));
|
||||
else if ( strcmp(method,"send") == 0 )
|
||||
return(dilithium_send(txfee,cp,params));
|
||||
else if ( strcmp(method,"spend") == 0 )
|
||||
return(dilithium_spend(txfee,cp,params));
|
||||
|
||||
@@ -2908,6 +2908,20 @@ int32_t main(void)
|
||||
this generates a really big hex, broadcast it and if all went well it will get confirmed.
|
||||
a dilithium spend!
|
||||
|
||||
to generate a seed that wont be directly derivable from an secp256k1 keypair, do:
|
||||
cclib keypair 19 \"[%22rand%22]\"
|
||||
|
||||
to do a Qsend (multiple dilithium inputs and outputs)
|
||||
|
||||
cclib Qsend 19 \"[%22mypubtxid%22,%22<hexseed>%22,%22<destpubtxid>%22,0.777]\"
|
||||
there can be up to 64 outputs, where each one can be a different destpubtxid or scriptPubKey. The only restriction is that scriptPubKey hex cant be 32 bytes.
|
||||
|
||||
Qsend is able to spend many Qvins as long as they are for the same dilithium bigpub + secp pub33. And the outputs can be to many different Qvouts or normal vouts. This allows to keep funds totally within the dilithium system and also to transfer back to normal taddrs. Qsend currently only sends from Qfunds, though it could also use funds from normal inputs.
|
||||
|
||||
Currently, to get funds from normal inputs to a dilithium, the send rpc can be used as above. So that provides a way to push funds into dilithium. The spend rpc becomes redundant with Qsend.
|
||||
|
||||
To properly test this, we need to make sure that transactions Qsend can use send outputs, and Qsend outputs and a combination. Of course, it needs to be validated that funds are not lost, Qsends work properly, etc.
|
||||
|
||||
*/
|
||||
|
||||
#define DILITHIUM_TXFEE 10000
|
||||
@@ -2915,6 +2929,28 @@ int32_t main(void)
|
||||
void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen);
|
||||
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
|
||||
|
||||
int32_t dilithium_Qmsghash(uint8_t *msg,CTransaction tx,std::vector<uint256> voutpubtxids)
|
||||
{
|
||||
CScript data; uint256 hash; int32_t i,numvins,numvouts,len = 0; std::vector<uint256> vintxids; std::vector<int32_t> vinprevns; std::vector<CTxOut> vouts;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
if ( tx.vout[numvouts-1].scriptPubKey[0] == 0x6a )
|
||||
{
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
vintxids.push_back(tx.vin[i].prevout.hash);
|
||||
vinprevns.push_back(tx.vin[i].prevout.n);
|
||||
}
|
||||
for (i=0; i<numvouts-1; i++)
|
||||
vouts.push_back(tx.vout[i]);
|
||||
data << E_MARSHAL(ss << vintxids << vinprevns << vouts << voutpubtxids);
|
||||
fprintf(stderr,"size of data.%d\n",(int32_t)data.size());
|
||||
hash = Hash(data.begin(),data.end());
|
||||
memcpy(msg,&hash,sizeof(hash));
|
||||
return(0);
|
||||
} else return(-1);
|
||||
}
|
||||
|
||||
CScript dilithium_registeropret(std::string handle,CPubKey pk,std::vector<uint8_t> bigpub)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_DILITHIUM;
|
||||
@@ -2969,6 +3005,24 @@ uint8_t dilithium_spendopretdecode(uint256 &destpubtxid,std::vector<uint8_t> &si
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript dilithium_Qsendopret(uint256 destpubtxid,std::vector<uint8_t>sig,std::vector<uint256> voutpubtxids)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_DILITHIUM;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'Q' << destpubtxid << sig << voutpubtxids);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t dilithium_Qsendopretdecode(uint256 &destpubtxid,std::vector<uint8_t>&sig,std::vector<uint256> &voutpubtxids,CScript scriptPubKey)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t e,f;
|
||||
GetOpReturnData(scriptPubKey,vopret);
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> destpubtxid; ss >> sig; ss >> voutpubtxids) != 0 && e == EVAL_DILITHIUM && f == 'Q' )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
UniValue dilithium_rawtxresult(UniValue &result,std::string rawtx)
|
||||
{
|
||||
CTransaction tx;
|
||||
@@ -3014,14 +3068,17 @@ char *dilithium_hexstr(char *str,uint8_t *buf,int32_t len)
|
||||
|
||||
int32_t dilithium_bigpubget(std::string &handle,CPubKey &pk33,uint8_t *pk,uint256 pubtxid)
|
||||
{
|
||||
CTransaction tx; uint256 hashBlock; int32_t numvouts; std::vector<uint8_t> bigpub;
|
||||
if ( myGetTransaction(pubtxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
CTransaction tx; uint8_t funcid; uint256 hashBlock; int32_t numvouts=0; std::vector<uint8_t> bigpub;
|
||||
if ( myGetTransaction(pubtxid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( dilithium_registeropretdecode(handle,pk33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' && bigpub.size() == CRYPTO_PUBLICKEYBYTES )
|
||||
if ( (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
memcpy(pk,&bigpub[0],CRYPTO_PUBLICKEYBYTES);
|
||||
return(0);
|
||||
} else return(-2);
|
||||
if ( (funcid= dilithium_registeropretdecode(handle,pk33,bigpub,tx.vout[numvouts-1].scriptPubKey)) == 'R' && bigpub.size() == CRYPTO_PUBLICKEYBYTES )
|
||||
{
|
||||
memcpy(pk,&bigpub[0],CRYPTO_PUBLICKEYBYTES);
|
||||
return(0);
|
||||
} else return(-2);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
@@ -3169,16 +3226,6 @@ UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
} else return(cclib_error(result,"not enough parameters"));
|
||||
}
|
||||
|
||||
/*
|
||||
ultimately what is needed is to be able to scan all utxos to the CC address and be able to spend many vins in the same tx. to do this the opreturn would need to be able to have txid of special with the sigs. However, it is complicated by the need to create a specific message to sign that is the desired outputs and all the inputs. Also, to properly be able to do change and keep everything in dilithium outputs, there needs to be a second destpub.
|
||||
|
||||
so the proposed opreturn for spend would be:
|
||||
|
||||
destpubtxid0, destpubtxid1 (zeroid if only 1), vector of sigs/sigtxid where if it is len 32 it is a txid that just has the sig in the opreturn.
|
||||
|
||||
however, for now, to keep things simple we will only support spending a specific txid to normal output to avoid needing a combined opreturn and other complications.
|
||||
*/
|
||||
|
||||
UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
@@ -3229,14 +3276,179 @@ UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
|
||||
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
|
||||
}
|
||||
|
||||
int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 pubtxid,int64_t total,int32_t maxinputs,char *cmpaddr)
|
||||
{
|
||||
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 checktxid,txid,hashBlock; std::vector<uint8_t> origpubkey,tmpsig; CTransaction vintx; int32_t vout,numvouts,n = 0; std::vector<uint256> voutpubtxids;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
|
||||
if ( it->second.satoshis < threshold || it->second.satoshis == DILITHIUM_TXFEE )
|
||||
continue;
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts= vintx.vout.size()) > 1 )
|
||||
{
|
||||
if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) > DILITHIUM_TXFEE && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
{
|
||||
if ( (dilithium_Qsendopretdecode(checktxid,tmpsig,voutpubtxids,vintx.vout[numvouts-1].scriptPubKey) == 'Q' || dilithium_sendopretdecode(checktxid,vintx.vout[numvouts-1].scriptPubKey) == 'x') && desttxid == checktxid )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
}
|
||||
} //else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN);
|
||||
} else fprintf(stderr,"couldnt get tx\n");
|
||||
}
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig; std::vector<uint256> voutpubtxids;
|
||||
if ( txfee == 0 )
|
||||
txfee = DILITHIUM_TXFEE;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
GetCCaddress(cp,myCCaddr,mypk);
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 4 && (n & 1) == 0 )
|
||||
{
|
||||
mypubtxid = juint256(jitem(params,0));
|
||||
if ( cclib_parsehash(seed,jitem(params,1),32) < 0 )
|
||||
{
|
||||
Myprivkey(seed);
|
||||
result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!"));
|
||||
}
|
||||
_dilithium_keypair(pk,sk,seed);
|
||||
outputsum = 0;
|
||||
for (i=2; i<n; i+=2)
|
||||
{
|
||||
amount = jdouble(jitem(params,i+1),0)*COIN + 0.0000000049;
|
||||
scriptstr = jstr(jitem(params,i),0);
|
||||
if ( is_hexstr(scriptstr,0) == 64 )
|
||||
{
|
||||
prevhash = juint256(jitem(params,i));
|
||||
if ( dilithium_bigpubget(handle,destpub33,pk2,prevhash) < 0 )
|
||||
{
|
||||
result.push_back(Pair("destpubtxid",prevhash.GetHex().c_str()));
|
||||
return(cclib_error(result,"couldnt find bigpub at destpubtxid"));
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,destpub33));
|
||||
voutpubtxids.push_back(prevhash); // binds destpub22 CC addr with dilithium bigpub
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey.resize(strlen(scriptstr)/2);
|
||||
decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr);
|
||||
vout.nValue = amount;
|
||||
vout.scriptPubKey = scriptPubKey;
|
||||
mtx.vout.push_back(vout);
|
||||
voutpubtxids.push_back(zeroid);
|
||||
}
|
||||
outputsum += amount;
|
||||
}
|
||||
if ( (inputsum= dilithium_inputs(cp,mtx,mypk,mypubtxid,outputsum+txfee,64,myCCaddr)) >= outputsum+txfee )
|
||||
{
|
||||
change = (inputsum - outputsum - txfee);
|
||||
if ( change >= txfee )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,mypk));
|
||||
voutpubtxids.push_back(mypubtxid);
|
||||
}
|
||||
tx = mtx;
|
||||
dilithium_Qmsghash(msg,tx,voutpubtxids);
|
||||
sig.resize(32+CRYPTO_BYTES);
|
||||
if ( dilithium_bigpubget(handle,destpub33,pk2,mypubtxid) < 0 )
|
||||
return(cclib_error(result,"couldnt get bigpub"));
|
||||
else if ( memcmp(pk,pk2,sizeof(pk)) != 0 )
|
||||
return(cclib_error(result,"dilithium bigpub mismatch"));
|
||||
else if ( destpub33 != mypk )
|
||||
return(cclib_error(result,"destpub33 is not for this -pubkey"));
|
||||
else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 )
|
||||
return(cclib_error(result,"dilithium signing error"));
|
||||
else if ( smlen != 32+CRYPTO_BYTES )
|
||||
return(cclib_error(result,"siglen error"));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids));
|
||||
return(dilithium_rawtxresult(result,rawtx));
|
||||
} else return(cclib_error(result,"Q couldnt find enough Q or x inputs"));
|
||||
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
|
||||
}
|
||||
|
||||
bool dilithium_Qvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
int32_t i,numvins,numvouts,mlen,smlen=CRYPTO_BYTES+32; CPubKey destpub33; std::string handle; uint256 tmptxid,hashBlock,destpubtxid,signerpubtxid; CTransaction vintx; std::vector<uint8_t> tmpsig,sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script; std::vector<uint256> voutpubtxids;
|
||||
numvins = tx.vin.size();
|
||||
signerpubtxid = zeroid;
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
if ( IsCCInput(tx.vin[i].scriptSig) != 0 )
|
||||
{
|
||||
if ( myGetTransaction(tx.vin[i].prevout.hash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 )
|
||||
{
|
||||
GetOpReturnData(vintx.vout[numvouts-1].scriptPubKey,vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[1] == 'Q' )
|
||||
{
|
||||
if ( dilithium_Qsendopretdecode(tmptxid,tmpsig,voutpubtxids,vintx.vout[numvouts-1].scriptPubKey) != 'Q' )
|
||||
return eval->Invalid("couldnt decode destpubtxid from Qsend");
|
||||
else if ( vintx.vin[i].prevout.n > voutpubtxids.size() )
|
||||
return eval->Invalid("no destpubtxid for prevout.n");
|
||||
destpubtxid = voutpubtxids[vintx.vin[i].prevout.n];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) != 'x' )
|
||||
return eval->Invalid("couldnt decode destpubtxid from send");
|
||||
}
|
||||
if ( signerpubtxid == zeroid )
|
||||
signerpubtxid = destpubtxid;
|
||||
else if ( destpubtxid != signerpubtxid )
|
||||
return eval->Invalid("destpubtxid of vini doesnt match first one");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( signerpubtxid != zeroid )
|
||||
{
|
||||
numvouts = tx.vout.size();
|
||||
if ( dilithium_Qsendopretdecode(destpubtxid,sig,voutpubtxids,tx.vout[numvouts-1].scriptPubKey) == 'Q' && destpubtxid == signerpubtxid && sig.size() == smlen )
|
||||
{
|
||||
if ( dilithium_Qmsghash(msg,tx,voutpubtxids) < 0 )
|
||||
return eval->Invalid("couldnt get Qmsghash");
|
||||
else if ( dilithium_bigpubget(handle,destpub33,pk,signerpubtxid) < 0 )
|
||||
return eval->Invalid("couldnt get bigpub");
|
||||
else
|
||||
{
|
||||
if ( _dilithium_verify(msg2,&mlen,&sig[0],smlen,pk) < 0 )
|
||||
return eval->Invalid("failed dilithium verify");
|
||||
else if ( mlen != 32 || memcmp(msg,msg2,32) != 0 )
|
||||
return eval->Invalid("failed dilithium msg verify");
|
||||
else return true;
|
||||
}
|
||||
} else return eval->Invalid("failed decode Qsend");
|
||||
} else return eval->Invalid("unexpected zero signerpubtxid");
|
||||
}
|
||||
|
||||
bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
CPubKey destpub33; std::string handle; uint256 hashBlock,destpubtxid,checktxid; CTransaction vintx; int32_t numvouts,numvins,mlen,smlen=CRYPTO_BYTES+32; std::vector<uint8_t> sig; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES];
|
||||
CPubKey destpub33; std::string handle; uint256 hashBlock,destpubtxid,checktxid; CTransaction vintx; int32_t numvouts,mlen,smlen=CRYPTO_BYTES+32; std::vector<uint8_t> sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script;
|
||||
// if all dilithium tx -> do multispend/send, else:
|
||||
numvouts = tx.vout.size();
|
||||
numvins = tx.vin.size();
|
||||
|
||||
if ( tx.vout.size() != 2 )
|
||||
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[1] == 'Q' )
|
||||
return(dilithium_Qvalidate(cp,height,eval,tx));
|
||||
else if ( tx.vout.size() != 2 )
|
||||
return eval->Invalid("numvouts != 2");
|
||||
else if ( tx.vin.size() != 1 )
|
||||
return eval->Invalid("numvins != 1");
|
||||
|
||||
@@ -167,7 +167,7 @@ int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,
|
||||
creditloop.push_back(txid);
|
||||
//fprintf(stderr,"%d: %s\n",n,txid.GetHex().c_str());
|
||||
n++;
|
||||
if ( (value= CCgettxout(spenttxid,vout,1)) == 10000 )
|
||||
if ( (value= CCgettxout(spenttxid,vout,1,1)) == 10000 )
|
||||
{
|
||||
batontxid = spenttxid;
|
||||
//fprintf(stderr,"got baton %s %.8f\n",batontxid.GetHex().c_str(),(double)value/COIN);
|
||||
|
||||
@@ -708,11 +708,60 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port)
|
||||
|
||||
#include "rogue.h"
|
||||
|
||||
void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_t num)
|
||||
int32_t rogue_sendrawtransaction(char *rawtx)
|
||||
{
|
||||
char cmd[16384],hexstr[16384],params[32768],*retstr; int32_t i;
|
||||
char params[512],*retstr; cJSON *retjson; int32_t numconfs = -1;
|
||||
sprintf(params,"[\"%s\"]",rawtx);
|
||||
if ( (retstr= komodo_issuemethod(USERPASS,"sendrawtransaction",params,ROGUE_PORT)) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"params.(%s) -> %s\n",params,retstr);
|
||||
if ( is_hexstr(retstr,64) == 64 )
|
||||
{
|
||||
free(retstr);
|
||||
return(0);
|
||||
}
|
||||
{
|
||||
static FILE *fp;
|
||||
if ( fp == 0 )
|
||||
fp = fopen("rogue.sendlog","wb");
|
||||
if ( fp != 0 )
|
||||
{
|
||||
fprintf(fp,"%s\n",retstr);
|
||||
fflush(fp);
|
||||
}
|
||||
}
|
||||
if ( (retjson= cJSON_Parse(retstr)) != 0 )
|
||||
{
|
||||
free_json(retjson);
|
||||
}
|
||||
free(retstr);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num)
|
||||
{
|
||||
char cmd[16384],hexstr[16384],params[32768],*retstr,*rawtx; int32_t i; cJSON *retjson;
|
||||
//fprintf(stderr,"rogue_progress num.%d\n",num);
|
||||
if ( rs->guiflag != 0 && Gametxidstr[0] != 0 )
|
||||
{
|
||||
if ( rs->keystrokeshex != 0 )
|
||||
{
|
||||
if ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 )
|
||||
{
|
||||
if ( waitflag == 0 )
|
||||
return;
|
||||
else if ( 0 )
|
||||
{
|
||||
while ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"pre-rebroadcast\n");
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(rs->keystrokeshex), rs->keystrokeshex = 0;
|
||||
}
|
||||
for (i=0; i<num; i++)
|
||||
sprintf(&hexstr[i<<1],"%02x",keystrokes[i]&0xff);
|
||||
hexstr[i<<1] = 0;
|
||||
@@ -736,9 +785,29 @@ void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_
|
||||
fprintf(fp,"%s\n",retstr);
|
||||
fflush(fp);
|
||||
}
|
||||
if ( (retjson= cJSON_Parse(retstr)) != 0 )
|
||||
{
|
||||
if ( (rawtx= jstr(retjson,"hex")) != 0 )
|
||||
{
|
||||
if ( rs->keystrokeshex != 0 )
|
||||
free(rs->keystrokeshex);
|
||||
rs->keystrokeshex = (char *)malloc(strlen(rawtx)+1);
|
||||
strcpy(rs->keystrokeshex,rawtx);
|
||||
//fprintf(stderr,"set keystrokestx <- %s\n",rs->keystrokeshex);
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
free(retstr);
|
||||
}
|
||||
sleep(1);
|
||||
if ( 0 && waitflag != 0 && rs->keystrokeshex != 0 )
|
||||
{
|
||||
while ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"post-rebroadcast\n");
|
||||
sleep(3);
|
||||
}
|
||||
free(rs->keystrokeshex), rs->keystrokeshex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ wanderer(struct rogue_state *rs)
|
||||
tp = new_item();
|
||||
do
|
||||
{
|
||||
find_floor((struct room *) NULL, &cp, FALSE, TRUE);
|
||||
find_floor(rs,(struct room *) NULL, &cp, FALSE, TRUE);
|
||||
} while (roomin(rs,&cp) == proom);
|
||||
new_monster(rs,tp, randmonster(TRUE), &cp);
|
||||
if (on(player, SEEMONST))
|
||||
|
||||
@@ -74,7 +74,7 @@ new_level(struct rogue_state *rs)
|
||||
*/
|
||||
do
|
||||
{
|
||||
find_floor((struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
} while (chat(stairs.y, stairs.x) != FLOOR);
|
||||
sp = &flat(stairs.y, stairs.x);
|
||||
*sp &= ~F_REAL;
|
||||
@@ -84,14 +84,14 @@ new_level(struct rogue_state *rs)
|
||||
/*
|
||||
* Place the staircase down.
|
||||
*/
|
||||
find_floor((struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
chat(stairs.y, stairs.x) = STAIRS;
|
||||
seenstairs = FALSE;
|
||||
|
||||
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||
tp->t_room = roomin(rs,&tp->t_pos);
|
||||
|
||||
find_floor((struct room *) NULL, &hero, FALSE, TRUE);
|
||||
find_floor(rs,(struct room *) NULL, &hero, FALSE, TRUE);
|
||||
enter_room(rs,&hero);
|
||||
mvaddch(hero.y, hero.x, PLAYER);
|
||||
if (on(player, SEEMONST))
|
||||
@@ -153,7 +153,7 @@ put_things(struct rogue_state *rs)
|
||||
/*
|
||||
* Put it somewhere
|
||||
*/
|
||||
find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
chat(obj->o_pos.y, obj->o_pos.x) = (char) obj->o_type;
|
||||
}
|
||||
/*
|
||||
@@ -173,7 +173,7 @@ put_things(struct rogue_state *rs)
|
||||
/*
|
||||
* Put it somewhere
|
||||
*/
|
||||
find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
chat(obj->o_pos.y, obj->o_pos.x) = AMULET;
|
||||
}
|
||||
}
|
||||
@@ -201,7 +201,7 @@ treas_room(struct rogue_state *rs)
|
||||
num_monst = nm = rnd(spots) + MINTREAS;
|
||||
while (nm--)
|
||||
{
|
||||
find_floor(rp, &mp, 2 * MAXTRIES, FALSE);
|
||||
find_floor(rs,rp, &mp, 2 * MAXTRIES, FALSE);
|
||||
//fprintf(stderr,"treas_room\n");
|
||||
tp = new_thing(rs);
|
||||
tp->o_pos = mp;
|
||||
@@ -222,7 +222,7 @@ treas_room(struct rogue_state *rs)
|
||||
while (nm--)
|
||||
{
|
||||
spots = 0;
|
||||
if (find_floor(rp, &mp, MAXTRIES, TRUE))
|
||||
if (find_floor(rs,rp, &mp, MAXTRIES, TRUE))
|
||||
{
|
||||
tp = new_item();
|
||||
new_monster(rs,tp, randmonster(FALSE), &mp);
|
||||
|
||||
@@ -422,6 +422,8 @@ get_item(struct rogue_state *rs,char *purpose, int type)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return(NULL);
|
||||
if (!terse)
|
||||
addmsg(rs,"which object do you want to ");
|
||||
addmsg(rs,purpose);
|
||||
|
||||
@@ -130,24 +130,26 @@ int
|
||||
gethand(struct rogue_state *rs)
|
||||
{
|
||||
int c;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (terse)
|
||||
msg(rs,"left or right ring? ");
|
||||
else
|
||||
msg(rs,"left hand or right hand? ");
|
||||
if ((c = readchar(rs)) == ESCAPE)
|
||||
return -1;
|
||||
mpos = 0;
|
||||
if (c == 'l' || c == 'L')
|
||||
return LEFT;
|
||||
else if (c == 'r' || c == 'R')
|
||||
return RIGHT;
|
||||
if (terse)
|
||||
msg(rs,"L or R");
|
||||
else
|
||||
msg(rs,"please type L or R");
|
||||
if ( rs->replaydone != 0 )
|
||||
return(-1);
|
||||
if (terse)
|
||||
msg(rs,"left or right ring? ");
|
||||
else
|
||||
msg(rs,"left hand or right hand? ");
|
||||
if ((c = readchar(rs)) == ESCAPE)
|
||||
return -1;
|
||||
mpos = 0;
|
||||
if (c == 'l' || c == 'L')
|
||||
return LEFT;
|
||||
else if (c == 'r' || c == 'R')
|
||||
return RIGHT;
|
||||
if (terse)
|
||||
msg(rs,"L or R");
|
||||
else
|
||||
msg(rs,"please type L or R");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ death(struct rogue_state *rs,char monst)
|
||||
//struct tm *localtime(const time_t *);
|
||||
if ( rs->guiflag == 0 )
|
||||
{
|
||||
fprintf(stderr,"death during replay by (%c)\n",monst); //sleep(3);
|
||||
//fprintf(stderr,"death during replay by (%c)\n",monst); //sleep(3);
|
||||
rs->replaydone = (uint32_t)time(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ int32_t roguefname(char *fname,uint64_t seed,int32_t counter)
|
||||
}
|
||||
|
||||
#ifdef test
|
||||
int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
int32_t flushkeystrokes(struct rogue_state *rs,int32_t waitflag)
|
||||
{
|
||||
char fname[1024]; FILE *fp; int32_t i,retflag = -1;
|
||||
roguefname(fname,rs->seed,rs->counter);
|
||||
@@ -155,7 +155,7 @@ int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
#ifdef BUILD_ROGUE
|
||||
// stubs for inside daemon
|
||||
|
||||
void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_t num)
|
||||
void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -165,14 +165,18 @@ int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr)
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
int32_t flushkeystrokes(struct rogue_state *rs,int32_t waitflag)
|
||||
{
|
||||
if ( rs->num > 0 )
|
||||
{
|
||||
rogue_progress(rs,rs->seed,rs->buffered,rs->num);
|
||||
// need to get existing keystrokes including mempool
|
||||
// create keystrokes that are not saved
|
||||
//rs->keytxid = rogue_progress(rs,waitflag,rs->seed,&rs->buffered[rs->lastnum],rs->num - rs->lastnum);
|
||||
//rs->lastnum = rs->num;
|
||||
rogue_progress(rs,waitflag,rs->seed,rs->buffered,rs->num);
|
||||
memset(rs->buffered,0,sizeof(rs->buffered));
|
||||
rs->counter++;
|
||||
rs->num = 0;
|
||||
rs->counter++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -180,7 +184,7 @@ int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
void rogue_bailout(struct rogue_state *rs)
|
||||
{
|
||||
char cmd[512];
|
||||
flushkeystrokes(rs);
|
||||
flushkeystrokes(rs,1);
|
||||
//sleep(5);
|
||||
return;
|
||||
/*fprintf(stderr,"bailing out\n");
|
||||
@@ -229,7 +233,7 @@ int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t nu
|
||||
if ( (fp= fopen("checkfile","wb")) != 0 )
|
||||
{
|
||||
save_file(rs,fp,0);
|
||||
fprintf(stderr,"gold.%d hp.%d strength.%d/%d level.%d exp.%d dungeon.%d data[%d]\n",rs->P.gold,rs->P.hitpoints,rs->P.strength&0xffff,rs->P.strength>>16,rs->P.level,rs->P.experience,rs->P.dungeonlevel,rs->playersize);
|
||||
//fprintf(stderr,"gold.%d hp.%d strength.%d/%d level.%d exp.%d dungeon.%d data[%d]\n",rs->P.gold,rs->P.hitpoints,rs->P.strength&0xffff,rs->P.strength>>16,rs->P.level,rs->P.experience,rs->P.dungeonlevel,rs->playersize);
|
||||
if ( newdata != 0 && rs->playersize > 0 )
|
||||
memcpy(newdata,rs->playerdata,rs->playersize);
|
||||
}
|
||||
@@ -315,6 +319,7 @@ int rogue(int argc, char **argv, char **envp)
|
||||
{
|
||||
rs->seed = atol(argv[1]);
|
||||
strcpy(Gametxidstr,argv[2]);
|
||||
fprintf(stderr,"setplayerdata\n");
|
||||
if ( rogue_setplayerdata(rs,Gametxidstr) < 0 )
|
||||
{
|
||||
fprintf(stderr,"invalid gametxid, or already started\n");
|
||||
@@ -410,7 +415,7 @@ int rogue(int argc, char **argv, char **envp)
|
||||
#endif
|
||||
printf("Hello %s, just a moment while I dig the dungeon... seed.%llu", whoami,(long long)rs->seed);
|
||||
fflush(stdout);
|
||||
|
||||
fprintf(stderr,"rogueiterate\n");
|
||||
rogueiterate(rs);
|
||||
return(0);
|
||||
}
|
||||
@@ -560,15 +565,15 @@ playit(struct rogue_state *rs)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( rs->needflush != 0 && rs->num > 1000 )
|
||||
if ( rs->needflush != 0 )
|
||||
{
|
||||
if ( flushkeystrokes(rs) == 0 )
|
||||
if ( flushkeystrokes(rs,0) == 0 )
|
||||
rs->needflush = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( rs->guiflag != 0 )
|
||||
flushkeystrokes(rs);
|
||||
flushkeystrokes(rs,1);
|
||||
endit(0);
|
||||
}
|
||||
|
||||
@@ -593,13 +598,13 @@ int32_t _quit()
|
||||
if ( rs->sleeptime != 0 )
|
||||
refresh();
|
||||
score(rs,purse, 1, 0);
|
||||
flushkeystrokes(rs);
|
||||
flushkeystrokes(rs,1);
|
||||
my_exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//score(rs,purse, 1, 0);
|
||||
fprintf(stderr,"done! (%c)\n",c);
|
||||
//fprintf(stderr,"done! (%c)\n",c);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -362,11 +362,11 @@ typedef union _bits256 bits256;
|
||||
struct rogue_state
|
||||
{
|
||||
uint64_t seed;
|
||||
char *keystrokes;
|
||||
char *keystrokes,*keystrokeshex;
|
||||
uint32_t needflush,replaydone;
|
||||
int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring;
|
||||
int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum;
|
||||
struct rogue_player P;
|
||||
char buffered[8192];
|
||||
char buffered[10000];
|
||||
uint8_t playerdata[10000];
|
||||
};
|
||||
extern struct rogue_state globalR;
|
||||
@@ -374,12 +374,12 @@ extern struct rogue_state globalR;
|
||||
int rogue(int argc, char **argv, char **envp);
|
||||
void rogueiterate(struct rogue_state *rs);
|
||||
int32_t roguefname(char *fname,uint64_t seed,int32_t counter);
|
||||
int32_t flushkeystrokes(struct rogue_state *rs);
|
||||
int32_t flushkeystrokes(struct rogue_state *rs,int32_t waitflag);
|
||||
int32_t rogue_restorepack(struct rogue_state *rs);
|
||||
void restore_player(struct rogue_state *rs);
|
||||
int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis);
|
||||
void rogue_bailout(struct rogue_state *rs);
|
||||
void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_t num);
|
||||
void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num);
|
||||
int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr);
|
||||
|
||||
#define ROGUE_MAXTOTAL (pstats.s_str*2)
|
||||
@@ -612,7 +612,7 @@ void current(struct rogue_state *rs,THING *cur, char *how, char *where);
|
||||
void d_level(struct rogue_state *rs);
|
||||
void death(struct rogue_state *rs,char monst);
|
||||
char death_monst(void);
|
||||
void dig(int y, int x);
|
||||
void dig(struct rogue_state *rs,int y, int x);
|
||||
void discard(THING *item);
|
||||
void discovered(struct rogue_state *rs);
|
||||
int dist(int y1, int x1, int y2, int x2);
|
||||
@@ -620,7 +620,7 @@ int dist_cp(coord *c1, coord *c2);
|
||||
int do_chase(struct rogue_state *rs,THING *th);
|
||||
void do_daemons(struct rogue_state *rs,int flag);
|
||||
void do_fuses(struct rogue_state *rs,int flag);
|
||||
void do_maze(struct room *rp);
|
||||
void do_maze(struct rogue_state *rs,struct room *rp);
|
||||
void do_motion(struct rogue_state *rs,THING *obj, int ydelta, int xdelta);
|
||||
void do_move(struct rogue_state *rs,int dy, int dx);
|
||||
void do_passages(struct rogue_state *rs);
|
||||
@@ -632,7 +632,7 @@ void doadd(struct rogue_state *rs,char *fmt, va_list args);
|
||||
void door(struct room *rm, coord *cp);
|
||||
void door_open(struct rogue_state *rs,struct room *rp);
|
||||
void drain(struct rogue_state *rs);
|
||||
void draw_room(struct room *rp);
|
||||
void draw_room(struct rogue_state *rs,struct room *rp);
|
||||
void drop(struct rogue_state *rs);
|
||||
void eat(struct rogue_state *rs);
|
||||
size_t encread(char *start, size_t size, FILE *inf);
|
||||
@@ -761,7 +761,7 @@ bool chase(THING *tp, coord *ee);
|
||||
bool diag_ok(coord *sp, coord *ep);
|
||||
bool dropcheck(struct rogue_state *rs,THING *obj);
|
||||
bool fallpos(coord *pos, coord *newpos);
|
||||
bool find_floor(struct room *rp, coord *cp, int limit, bool monst);
|
||||
bool find_floor(struct rogue_state *rs,struct room *rp, coord *cp, int limit, bool monst);
|
||||
bool is_magic(THING *obj);
|
||||
bool is_symlink(char *sp);
|
||||
bool levit_check(struct rogue_state *rs);
|
||||
|
||||
@@ -112,7 +112,7 @@ do_rooms(struct rogue_state *rs)
|
||||
rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
|
||||
rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
|
||||
} until (rp->r_pos.y != 0);
|
||||
draw_room(rp);
|
||||
draw_room(rs,rp);
|
||||
/*
|
||||
* Put the gold in
|
||||
*/
|
||||
@@ -122,7 +122,7 @@ do_rooms(struct rogue_state *rs)
|
||||
|
||||
gold = new_item();
|
||||
gold->o_goldval = rp->r_goldval = GOLDCALC;
|
||||
find_floor(rp, &rp->r_gold, FALSE, FALSE);
|
||||
find_floor(rs,rp, &rp->r_gold, FALSE, FALSE);
|
||||
gold->o_pos = rp->r_gold;
|
||||
chat(rp->r_gold.y, rp->r_gold.x) = GOLD;
|
||||
gold->o_flags = ISMANY;
|
||||
@@ -136,7 +136,7 @@ do_rooms(struct rogue_state *rs)
|
||||
if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25))
|
||||
{
|
||||
tp = new_item();
|
||||
find_floor(rp, &mp, FALSE, TRUE);
|
||||
find_floor(rs,rp, &mp, FALSE, TRUE);
|
||||
new_monster(rs,tp, randmonster(FALSE), &mp);
|
||||
give_pack(rs,tp);
|
||||
}
|
||||
@@ -150,12 +150,12 @@ do_rooms(struct rogue_state *rs)
|
||||
*/
|
||||
|
||||
void
|
||||
draw_room(struct room *rp)
|
||||
draw_room(struct rogue_state *rs,struct room *rp)
|
||||
{
|
||||
int y, x;
|
||||
|
||||
if (rp->r_flags & ISMAZE)
|
||||
do_maze(rp);
|
||||
do_maze(rs,rp);
|
||||
else
|
||||
{
|
||||
vert(rp, rp->r_pos.x); /* Draw left side */
|
||||
@@ -211,7 +211,7 @@ static SPOT maze[NUMLINES/3+1][NUMCOLS/3+1];
|
||||
|
||||
|
||||
void
|
||||
do_maze(struct room *rp)
|
||||
do_maze(struct rogue_state *rs,struct room *rp)
|
||||
{
|
||||
SPOT *sp;
|
||||
int starty, startx;
|
||||
@@ -232,7 +232,7 @@ do_maze(struct room *rp)
|
||||
pos.y = starty + Starty;
|
||||
pos.x = startx + Startx;
|
||||
putpass(&pos);
|
||||
dig(starty, startx);
|
||||
dig(rs,starty, startx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -241,7 +241,7 @@ do_maze(struct room *rp)
|
||||
*/
|
||||
|
||||
void
|
||||
dig(int y, int x)
|
||||
dig(struct rogue_state *rs,int y, int x)
|
||||
{
|
||||
coord *cp;
|
||||
int cnt, newy, newx, nexty = 0, nextx = 0;
|
||||
@@ -252,6 +252,8 @@ dig(int y, int x)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return;
|
||||
cnt = 0;
|
||||
for (cp = del; cp <= &del[3]; cp++)
|
||||
{
|
||||
@@ -291,7 +293,7 @@ dig(int y, int x)
|
||||
pos.y = nexty + Starty;
|
||||
pos.x = nextx + Startx;
|
||||
putpass(&pos);
|
||||
dig(nexty, nextx);
|
||||
dig(rs,nexty, nextx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +334,7 @@ rnd_pos(struct room *rp, coord *cp)
|
||||
* pick a new room each time around the loop.
|
||||
*/
|
||||
bool
|
||||
find_floor(struct room *rp, coord *cp, int limit, bool monst)
|
||||
find_floor(struct rogue_state *rs,struct room *rp, coord *cp, int limit, bool monst)
|
||||
{
|
||||
PLACE *pp;
|
||||
int cnt;
|
||||
@@ -346,6 +348,8 @@ find_floor(struct room *rp, coord *cp, int limit, bool monst)
|
||||
cnt = limit;
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return(FALSE);
|
||||
if (limit && cnt-- == 0)
|
||||
return FALSE;
|
||||
if (pickroom)
|
||||
|
||||
@@ -158,7 +158,7 @@ do_zap(struct rogue_state *rs)
|
||||
{
|
||||
do
|
||||
{
|
||||
find_floor(NULL, &new_pos, FALSE, TRUE);
|
||||
find_floor(rs,NULL, &new_pos, FALSE, TRUE);
|
||||
} while (ce(new_pos, hero));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -81,6 +81,8 @@ do_motion(struct rogue_state *rs,THING *obj, int ydelta, int xdelta)
|
||||
obj->o_pos = hero;
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return;
|
||||
/*
|
||||
* Erase the old one
|
||||
*/
|
||||
|
||||
@@ -35,19 +35,21 @@ whatis(struct rogue_state *rs,bool insist, int type)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
obj = get_item(rs,"identify", type);
|
||||
if (insist)
|
||||
{
|
||||
if (n_objs == 0)
|
||||
return;
|
||||
else if (obj == NULL)
|
||||
msg(rs,"you must identify something");
|
||||
else if (type && obj->o_type != type &&
|
||||
!(type == R_OR_S && (obj->o_type == RING || obj->o_type == STICK)) )
|
||||
msg(rs,"you must identify a %s", type_name(type));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ( rs->replaydone != 0 )
|
||||
return;
|
||||
obj = get_item(rs,"identify", type);
|
||||
if (insist)
|
||||
{
|
||||
if (n_objs == 0)
|
||||
return;
|
||||
else if (obj == NULL)
|
||||
msg(rs,"you must identify something");
|
||||
else if (type && obj->o_type != type &&
|
||||
!(type == R_OR_S && (obj->o_type == RING || obj->o_type == STICK)) )
|
||||
msg(rs,"you must identify a %s", type_name(type));
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -202,7 +204,7 @@ teleport(struct rogue_state *rs)
|
||||
static coord c;
|
||||
|
||||
mvaddch(hero.y, hero.x, floor_at());
|
||||
find_floor((struct room *) NULL, &c, FALSE, TRUE);
|
||||
find_floor(rs,(struct room *) NULL, &c, FALSE, TRUE);
|
||||
if (roomin(rs,&c) != proom)
|
||||
{
|
||||
leave_room(rs,&hero);
|
||||
|
||||
@@ -282,54 +282,6 @@ int32_t rogue_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx,
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t rogue_playersalive(int32_t &numplayers,uint256 gametxid,int32_t maxplayers)
|
||||
{
|
||||
int32_t i,alive = 0; uint64_t txfee = 10000;
|
||||
numplayers = 0;
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
if ( CCgettxout(gametxid,1+i,1) < 0 )
|
||||
{
|
||||
numplayers++;
|
||||
if (CCgettxout(gametxid,1+maxplayers+i,1) == txfee )
|
||||
alive++;
|
||||
}
|
||||
}
|
||||
return(alive);
|
||||
}
|
||||
|
||||
uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *myrogueaddr)
|
||||
{
|
||||
CBlockIndex *pindex; int32_t ht,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx;
|
||||
if ( myGetTransaction(gametxid,tx,hashBlock) != 0 && (pindex= komodo_blockindex(hashBlock)) != 0 )
|
||||
{
|
||||
ht = pindex->GetHeight();
|
||||
delay = ROGUE_REGISTRATION * (maxplayers > 1);
|
||||
obj.push_back(Pair("height",ht));
|
||||
obj.push_back(Pair("start",ht+delay));
|
||||
if ( komodo_nextheight() > ht+delay )
|
||||
{
|
||||
if ( (pindex= komodo_chainactive(ht+delay)) != 0 )
|
||||
{
|
||||
hashBlock = pindex->GetBlockHash();
|
||||
obj.push_back(Pair("starthash",hashBlock.ToString()));
|
||||
memcpy(&seed,&hashBlock,sizeof(seed));
|
||||
seed &= (1LL << 62) - 1;
|
||||
obj.push_back(Pair("seed",(int64_t)seed));
|
||||
if ( rogue_iamregistered(maxplayers,gametxid,tx,myrogueaddr) > 0 )
|
||||
sprintf(cmd,"cc/rogue/rogue %llu %s",(long long)seed,gametxid.ToString().c_str());
|
||||
else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str());
|
||||
obj.push_back(Pair("run",cmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.push_back(Pair("alive",rogue_playersalive(numplayers,gametxid,maxplayers)));
|
||||
obj.push_back(Pair("numplayers",numplayers));
|
||||
obj.push_back(Pair("maxplayers",maxplayers));
|
||||
obj.push_back(Pair("buyin",ValueFromAmount(buyin)));
|
||||
return(seed);
|
||||
}
|
||||
|
||||
int32_t rogue_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransaction &tx,int64_t &buyin,int32_t &maxplayers,uint256 txid,int32_t unspentv0)
|
||||
{
|
||||
uint256 hashBlock; int32_t i,numvouts; char coinaddr[64]; CPubKey roguepk; uint64_t txfee = 10000;
|
||||
@@ -343,7 +295,7 @@ int32_t rogue_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransa
|
||||
txid = tx.GetHash();
|
||||
//fprintf(stderr,"set txid %s %llu\n",txid.GetHex().c_str(),(long long)CCgettxout(txid,0,1));
|
||||
}
|
||||
if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) == txfee && (unspentv0 == 0 || CCgettxout(txid,0,1) == txfee) )
|
||||
if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) == txfee && (unspentv0 == 0 || CCgettxout(txid,0,1,0) == txfee) )
|
||||
{
|
||||
if ( rogue_newgameopreturndecode(buyin,maxplayers,tx.vout[numvouts-1].scriptPubKey) == 'G' )
|
||||
{
|
||||
@@ -369,9 +321,9 @@ int32_t rogue_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransa
|
||||
} else return(-1);
|
||||
}
|
||||
|
||||
UniValue rogue_playerobj(std::vector<uint8_t> playerdata,uint256 playertxid,uint256 tokenid,std::string symbol,std::string pname)
|
||||
UniValue rogue_playerobj(std::vector<uint8_t> playerdata,uint256 playertxid,uint256 tokenid,std::string symbol,std::string pname,uint256 gametxid)
|
||||
{
|
||||
int32_t i; struct rogue_player P; char packitemstr[512],*datastr=0; UniValue obj(UniValue::VOBJ),a(UniValue::VARR);
|
||||
int32_t i,vout,spentvini,numvouts,n=0; uint256 txid,spenttxid,hashBlock; struct rogue_player P; char packitemstr[512],*datastr=0; UniValue obj(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx;
|
||||
memset(&P,0,sizeof(P));
|
||||
if ( playerdata.size() > 0 )
|
||||
{
|
||||
@@ -389,6 +341,37 @@ UniValue rogue_playerobj(std::vector<uint8_t> playerdata,uint256 playertxid,uint
|
||||
rogue_packitemstr(packitemstr,&P.roguepack[i]);
|
||||
a.push_back(packitemstr);
|
||||
}
|
||||
txid = playertxid;
|
||||
vout = 1;
|
||||
while ( CCgettxout(txid,vout,1,0) < 0 )
|
||||
{
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,vout)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,vout) == 0 || spenttxid == zeroid )
|
||||
{
|
||||
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
|
||||
break;
|
||||
}
|
||||
txid = spenttxid;
|
||||
vout = 0;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
for (i=0; i<numvouts; i++)
|
||||
if ( tx.vout[i].nValue == 1 )
|
||||
{
|
||||
vout = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"trace spend to %s/v%d\n",txid.GetHex().c_str(),vout);
|
||||
if ( n++ > ROGUE_MAXITERATIONS )
|
||||
break;
|
||||
}
|
||||
obj.push_back(Pair("gametxid",gametxid.GetHex()));
|
||||
if ( txid != playertxid )
|
||||
obj.push_back(Pair("batontxid",txid.GetHex()));
|
||||
obj.push_back(Pair("playertxid",playertxid.GetHex()));
|
||||
if ( tokenid != zeroid )
|
||||
obj.push_back(Pair("tokenid",tokenid.GetHex()));
|
||||
@@ -452,6 +435,7 @@ int32_t rogue_playerdata(struct CCcontract_info *cp,uint256 &origplayergame,uint
|
||||
{
|
||||
if ( (f= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,playertx.vout[numvouts-1].scriptPubKey)) == 'H' || f == 'Q' )
|
||||
{
|
||||
origplayergame = gametxid;
|
||||
if ( tokenid != zeroid )
|
||||
{
|
||||
playertxid = tokenid;
|
||||
@@ -478,7 +462,7 @@ int32_t rogue_playerdata(struct CCcontract_info *cp,uint256 &origplayergame,uint
|
||||
int32_t rogue_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,int32_t vout,uint256 origplayergame)
|
||||
{
|
||||
int64_t txfee = 10000; CTransaction tx; uint256 hashBlock;
|
||||
if ( CCgettxout(playertxid,vout,1) == 1 ) // not sure if this is enough validation
|
||||
if ( CCgettxout(playertxid,vout,1,0) == 1 ) // not sure if this is enough validation
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(playertxid,vout,CScript()));
|
||||
return(0);
|
||||
@@ -488,7 +472,7 @@ int32_t rogue_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,int32_
|
||||
vout = 0;
|
||||
if ( myGetTransaction(playertxid,tx,hashBlock) != 0 && tx.vout[vout].nValue == 1 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
if ( CCgettxout(playertxid,vout,1) == 1 ) // not sure if this is enough validation
|
||||
if ( CCgettxout(playertxid,vout,1,0) == 1 ) // not sure if this is enough validation
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(playertxid,vout,CScript()));
|
||||
return(0);
|
||||
@@ -501,8 +485,8 @@ int32_t rogue_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,int32_
|
||||
int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **keystrokesp,int32_t &numkeys,int32_t ®slot,std::vector<uint8_t> &playerdata,uint256 &batontxid,int32_t &batonvout,int64_t &batonvalue,int32_t &batonht,uint256 gametxid,CTransaction gametx,int32_t maxplayers,char *destaddr,int32_t &numplayers,std::string &symbol,std::string &pname)
|
||||
{
|
||||
int32_t i,numvouts,spentvini,n,matches = 0; CPubKey pk; uint256 tid,active,spenttxid,tokenid,hashBlock,txid,origplayergame; CTransaction spenttx,matchtx,batontx; std::vector<uint8_t> checkdata; CBlockIndex *pindex; char ccaddr[64],*keystrokes=0;
|
||||
numkeys = numplayers = 0;
|
||||
playertxid = zeroid;
|
||||
batonvalue = numkeys = numplayers = batonht = 0;
|
||||
playertxid = batontxid = zeroid;
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
//fprintf(stderr,"findbaton.%d of %d\n",i,maxplayers);
|
||||
@@ -523,83 +507,172 @@ int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **ke
|
||||
}
|
||||
if ( matches == 1 )
|
||||
{
|
||||
if ( 1 || myIsutxo_spent(spenttxid,gametxid,maxplayers+i+1) < 0 )
|
||||
numvouts = matchtx.vout.size();
|
||||
//fprintf(stderr,"matchtxid.%s matches.%d numvouts.%d\n",matchtx.GetHash().GetHex().c_str(),matches,numvouts);
|
||||
if ( rogue_registeropretdecode(txid,tokenid,playertxid,matchtx.vout[numvouts-1].scriptPubKey) == 'R' )//&& txid == gametxid )
|
||||
{
|
||||
numvouts = matchtx.vout.size();
|
||||
//fprintf(stderr,"matchtxid.%s matches.%d numvouts.%d\n",matchtx.GetHash().GetHex().c_str(),matches,numvouts);
|
||||
if ( rogue_registeropretdecode(txid,tokenid,playertxid,matchtx.vout[numvouts-1].scriptPubKey) == 'R' )//&& txid == gametxid )
|
||||
//fprintf(stderr,"tokenid.%s txid.%s vs gametxid.%s player.%s\n",tokenid.GetHex().c_str(),txid.GetHex().c_str(),gametxid.GetHex().c_str(),playertxid.GetHex().c_str());
|
||||
if ( tokenid != zeroid )
|
||||
active = tokenid;
|
||||
else active = playertxid;
|
||||
if ( active == zeroid || rogue_playerdata(cp,origplayergame,tid,pk,playerdata,symbol,pname,active) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"tokenid.%s txid.%s vs gametxid.%s player.%s\n",tokenid.GetHex().c_str(),txid.GetHex().c_str(),gametxid.GetHex().c_str(),playertxid.GetHex().c_str());
|
||||
if ( tokenid != zeroid )
|
||||
active = tokenid;
|
||||
else active = playertxid;
|
||||
if ( active == zeroid || rogue_playerdata(cp,origplayergame,tid,pk,playerdata,symbol,pname,active) == 0 )
|
||||
txid = matchtx.GetHash();
|
||||
//fprintf(stderr,"scan forward active.%s spenttxid.%s\n",active.GetHex().c_str(),txid.GetHex().c_str());
|
||||
n = 0;
|
||||
while ( CCgettxout(txid,0,1,0) < 0 )
|
||||
{
|
||||
txid = matchtx.GetHash();
|
||||
//fprintf(stderr,"scan forward active.%s spenttxid.%s\n",active.GetHex().c_str(),txid.GetHex().c_str());
|
||||
n = 0;
|
||||
while ( CCgettxout(txid,0,1) < 0 )
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,0)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else
|
||||
{
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,0)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,0) == 0 || spenttxid == zeroid )
|
||||
if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,0) == 0 || spenttxid == zeroid )
|
||||
{
|
||||
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
|
||||
return(-2);
|
||||
}
|
||||
txid = spenttxid;
|
||||
//fprintf(stderr,"next txid.%s/v%d\n",txid.GetHex().c_str(),spentvini);
|
||||
if ( spentvini != 0 )
|
||||
return(-3);
|
||||
if ( keystrokesp != 0 && myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() >= 2 )
|
||||
{
|
||||
uint256 g,b; CPubKey p; std::vector<uint8_t> k;
|
||||
if ( rogue_keystrokesopretdecode(g,b,p,k,spenttx.vout[spenttx.vout.size()-1].scriptPubKey) == 'K' )
|
||||
{
|
||||
keystrokes = (char *)realloc(keystrokes,numkeys + (int32_t)k.size());
|
||||
for (i=0; i<k.size(); i++)
|
||||
keystrokes[numkeys+i] = (char)k[i];
|
||||
numkeys += (int32_t)k.size();
|
||||
(*keystrokesp) = keystrokes;
|
||||
}
|
||||
}
|
||||
if ( ++n >= ROGUE_MAXITERATIONS )
|
||||
{
|
||||
fprintf(stderr,"rogue_findbaton n.%d, seems something is wrong\n",n);
|
||||
return(-5);
|
||||
}
|
||||
//fprintf(stderr,"n.%d txid.%s\n",n,txid.GetHex().c_str());
|
||||
}
|
||||
//fprintf(stderr,"set baton %s\n",txid.GetHex().c_str());
|
||||
batontxid = txid;
|
||||
batonvout = 0; // not vini
|
||||
// how to detect timeout, bailedout, highlander
|
||||
hashBlock = zeroid;
|
||||
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 0 )
|
||||
txid = spenttxid;
|
||||
//fprintf(stderr,"n.%d next txid.%s/v%d\n",n,txid.GetHex().c_str(),spentvini);
|
||||
if ( spentvini != 0 ) // game is over?
|
||||
{
|
||||
if ( hashBlock == zeroid )
|
||||
batonht = komodo_nextheight();
|
||||
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 )
|
||||
return(-4);
|
||||
else batonht = pindex->GetHeight();
|
||||
batonvalue = batontx.vout[0].nValue;
|
||||
//printf("batonht.%d keystrokes[%d]\n",batonht,numkeys);
|
||||
return(0);
|
||||
} else fprintf(stderr,"couldnt find baton\n");
|
||||
} else fprintf(stderr,"error with playerdata\n");
|
||||
} else fprintf(stderr,"findbaton opret error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"already played\n");
|
||||
return(-6);
|
||||
}
|
||||
}
|
||||
if ( keystrokesp != 0 && myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() >= 2 )
|
||||
{
|
||||
uint256 g,b; CPubKey p; std::vector<uint8_t> k;
|
||||
if ( rogue_keystrokesopretdecode(g,b,p,k,spenttx.vout[spenttx.vout.size()-1].scriptPubKey) == 'K' )
|
||||
{
|
||||
keystrokes = (char *)realloc(keystrokes,numkeys + (int32_t)k.size());
|
||||
for (i=0; i<k.size(); i++)
|
||||
keystrokes[numkeys+i] = (char)k[i];
|
||||
numkeys += (int32_t)k.size();
|
||||
(*keystrokesp) = keystrokes;
|
||||
//fprintf(stderr,"updated keystrokes.%p[%d]\n",keystrokes,numkeys);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"n.%d txid.%s\n",n,txid.GetHex().c_str());
|
||||
if ( ++n >= ROGUE_MAXITERATIONS )
|
||||
{
|
||||
fprintf(stderr,"rogue_findbaton n.%d, seems something is wrong\n",n);
|
||||
return(-5);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"set baton %s\n",txid.GetHex().c_str());
|
||||
batontxid = txid;
|
||||
batonvout = 0; // not vini
|
||||
// how to detect timeout, bailedout, highlander
|
||||
hashBlock = zeroid;
|
||||
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 0 )
|
||||
{
|
||||
if ( hashBlock == zeroid )
|
||||
batonht = komodo_nextheight();
|
||||
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 )
|
||||
return(-4);
|
||||
else batonht = pindex->GetHeight();
|
||||
batonvalue = batontx.vout[0].nValue;
|
||||
//printf("batonht.%d keystrokes[%d]\n",batonht,numkeys);
|
||||
return(0);
|
||||
} else fprintf(stderr,"couldnt find baton\n");
|
||||
} else fprintf(stderr,"error with playerdata\n");
|
||||
} else fprintf(stderr,"findbaton opret error\n");
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int32_t rogue_playersalive(int32_t &openslots,int32_t &numplayers,uint256 gametxid,int32_t maxplayers,int32_t gameht,CTransaction gametx)
|
||||
{
|
||||
int32_t i,n,vout,spentvini,registration_open = 0,alive = 0; CTransaction tx; uint256 txid,spenttxid,hashBlock; CBlockIndex *pindex; uint64_t txfee = 10000;
|
||||
numplayers = openslots = 0;
|
||||
if ( komodo_nextheight() <= gameht+ROGUE_MAXKEYSTROKESGAP )
|
||||
registration_open = 1;
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
//fprintf(stderr,"players alive %d of %d\n",i,maxplayers);
|
||||
if ( CCgettxout(gametxid,1+i,1,0) < 0 )
|
||||
{
|
||||
numplayers++;
|
||||
//fprintf(stderr,"players alive %d spent baton\n",i);
|
||||
if ( CCgettxout(gametxid,1+maxplayers+i,1,0) == txfee )
|
||||
{
|
||||
txid = gametxid;
|
||||
vout = 1+i;
|
||||
//fprintf(stderr,"rogue_playersalive scan forward active.%s spenttxid.%s\n",gametxid.GetHex().c_str(),txid.GetHex().c_str());
|
||||
n = 0;
|
||||
while ( CCgettxout(txid,vout,1,0) < 0 )
|
||||
{
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,vout)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,vout) == 0 || spenttxid == zeroid )
|
||||
{
|
||||
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
|
||||
break;
|
||||
}
|
||||
txid = spenttxid;
|
||||
vout = 0;
|
||||
//fprintf(stderr,"n.%d next txid.%s/v%d\n",n,txid.GetHex().c_str(),spentvini);
|
||||
if ( spentvini != 0 )
|
||||
break;
|
||||
if ( n++ > ROGUE_MAXITERATIONS )
|
||||
break;
|
||||
}
|
||||
if ( txid != zeroid )
|
||||
{
|
||||
if ( myGetTransaction(txid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( (pindex= komodo_blockindex(hashBlock)) != 0 )
|
||||
{
|
||||
if ( pindex->GetHeight() <= gameht+ROGUE_MAXKEYSTROKESGAP )
|
||||
alive++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( registration_open != 0 )
|
||||
openslots++;
|
||||
}
|
||||
//fprintf(stderr,"numalive.%d openslots.%d\n",alive,openslots);
|
||||
return(alive);
|
||||
}
|
||||
|
||||
uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *myrogueaddr)
|
||||
{
|
||||
CBlockIndex *pindex; int32_t ht,openslots,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx;
|
||||
if ( myGetTransaction(gametxid,tx,hashBlock) != 0 && (pindex= komodo_blockindex(hashBlock)) != 0 )
|
||||
{
|
||||
ht = pindex->GetHeight();
|
||||
delay = ROGUE_REGISTRATION * (maxplayers > 1);
|
||||
obj.push_back(Pair("height",ht));
|
||||
obj.push_back(Pair("start",ht+delay));
|
||||
if ( komodo_nextheight() > ht+delay )
|
||||
{
|
||||
if ( (pindex= komodo_chainactive(ht+delay)) != 0 )
|
||||
{
|
||||
hashBlock = pindex->GetBlockHash();
|
||||
obj.push_back(Pair("starthash",hashBlock.ToString()));
|
||||
memcpy(&seed,&hashBlock,sizeof(seed));
|
||||
seed &= (1LL << 62) - 1;
|
||||
obj.push_back(Pair("seed",(int64_t)seed));
|
||||
if ( rogue_iamregistered(maxplayers,gametxid,tx,myrogueaddr) > 0 )
|
||||
sprintf(cmd,"cc/rogue/rogue %llu %s",(long long)seed,gametxid.ToString().c_str());
|
||||
else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str());
|
||||
obj.push_back(Pair("run",cmd));
|
||||
}
|
||||
}
|
||||
obj.push_back(Pair("alive",rogue_playersalive(openslots,numplayers,gametxid,maxplayers,ht,tx)));
|
||||
obj.push_back(Pair("openslots",openslots));
|
||||
obj.push_back(Pair("numplayers",numplayers));
|
||||
}
|
||||
obj.push_back(Pair("maxplayers",maxplayers));
|
||||
obj.push_back(Pair("buyin",ValueFromAmount(buyin)));
|
||||
return(seed);
|
||||
}
|
||||
|
||||
void rogue_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gametxid,CTransaction gametx,int32_t vout,int32_t maxplayers,char *myrogueaddr)
|
||||
{
|
||||
// identify if bailout or quit or timed out
|
||||
@@ -613,7 +686,7 @@ void rogue_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gamet
|
||||
obj.push_back(Pair("slot",(int64_t)vout-1));
|
||||
if ( (retval= rogue_findbaton(cp,playertxid,0,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,destaddr,numplayers,symbol,pname)) == 0 )
|
||||
{
|
||||
if ( CCgettxout(gametxid,maxplayers+vout,1) == 10000 )
|
||||
if ( CCgettxout(gametxid,maxplayers+vout,1,0) == 10000 )
|
||||
{
|
||||
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 1 )
|
||||
{
|
||||
@@ -630,7 +703,7 @@ void rogue_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gamet
|
||||
obj.push_back(Pair("batonvalue",ValueFromAmount(batonvalue)));
|
||||
obj.push_back(Pair("batonht",(int64_t)batonht));
|
||||
if ( playerdata.size() > 0 )
|
||||
obj.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname)));
|
||||
obj.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname,gametxid)));
|
||||
} else fprintf(stderr,"findbaton err.%d\n",retval);
|
||||
}
|
||||
|
||||
@@ -643,7 +716,7 @@ int64_t rogue_registrationbaton(CMutableTransaction &mtx,uint256 gametxid,CTrans
|
||||
for (j=0; j<maxplayers; j++)
|
||||
{
|
||||
vout = ((r + j) % maxplayers) + 1;
|
||||
if ( CCgettxout(gametxid,vout,1) == ROGUE_REGISTRATIONSIZE )
|
||||
if ( CCgettxout(gametxid,vout,1,0) == ROGUE_REGISTRATIONSIZE )
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(gametxid,vout,CScript()));
|
||||
return(ROGUE_REGISTRATIONSIZE);
|
||||
@@ -719,7 +792,7 @@ UniValue rogue_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
playertxid = juint256(jitem(params,0));
|
||||
if ( rogue_playerdata(cp,origplayergame,tokenid,pk,playerdata,symbol,pname,playertxid) < 0 )
|
||||
return(cclib_error(result,"invalid playerdata"));
|
||||
result.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname)));
|
||||
result.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname,origplayergame)));
|
||||
} else return(cclib_error(result,"no playertxid"));
|
||||
return(result);
|
||||
} else return(cclib_error(result,"couldnt reparse params"));
|
||||
@@ -857,15 +930,16 @@ UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
|
||||
char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vector<uint8_t> &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *rogueaddr)
|
||||
{
|
||||
CPubKey roguepk; int32_t i,num,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector<uint8_t> playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct rogue_player P,endP;
|
||||
CPubKey roguepk; int32_t i,num,retval,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector<uint8_t> playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct rogue_player P,endP;
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
*numkeysp = 0;
|
||||
seed = 0;
|
||||
num = numkeys = 0;
|
||||
playertxid = zeroid;
|
||||
str[0] = 0;
|
||||
if ( (err= rogue_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0)) == 0 )
|
||||
{
|
||||
if ( rogue_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,rogueaddr,numplayers,symbol,pname) == 0 )
|
||||
if ( (retval= rogue_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,rogueaddr,numplayers,symbol,pname)) == 0 )
|
||||
{
|
||||
UniValue obj;
|
||||
seed = rogue_gamefields(obj,maxplayers,buyin,gametxid,rogueaddr);
|
||||
@@ -904,7 +978,7 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
}
|
||||
if ( endP.gold <= 0 || endP.hitpoints <= 0 || (endP.strength&0xffff) <= 0 || endP.level <= 0 || endP.experience <= 0 || endP.dungeonlevel <= 0 )
|
||||
{
|
||||
//fprintf(stderr,"zero value character was killed -> no playerdata\n");
|
||||
fprintf(stderr,"zero value character was killed -> no playerdata\n");
|
||||
newdata.resize(0);
|
||||
//P.gold = (P.gold * 8) / 10;
|
||||
if ( keystrokes != 0 )
|
||||
@@ -912,12 +986,13 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
free(keystrokes);
|
||||
keystrokes = 0;
|
||||
*numkeysp = 0;
|
||||
return(keystrokes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"extracted $$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel);
|
||||
fprintf(stderr,"%s\n",str);
|
||||
sprintf(str,"$$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel);
|
||||
//fprintf(stderr,"%s\n",str);
|
||||
*numkeysp = numkeys;
|
||||
return(keystrokes);
|
||||
}
|
||||
@@ -925,7 +1000,7 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"extractgame: couldnt find baton keystrokes.%p\n",keystrokes);
|
||||
fprintf(stderr,"extractgame: couldnt find baton keystrokes.%p retval.%d\n",keystrokes,retval);
|
||||
if ( keystrokes != 0 )
|
||||
free(keystrokes), keystrokes = 0;
|
||||
}
|
||||
@@ -936,11 +1011,12 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
|
||||
UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); CPubKey pk,roguepk; int32_t i,n,numkeys,flag = 0; uint64_t seed; char str[512],rogueaddr[64],*pubstr,*keystrokes = 0; std::vector<uint8_t> newdata; uint256 gametxid,playertxid; FILE *fp; uint8_t pub33[33];
|
||||
UniValue result(UniValue::VOBJ); CPubKey pk,roguepk; int32_t i,n,numkeys,flag = 0; uint64_t seed; char str[512],rogueaddr[64],*pubstr,*hexstr,*keystrokes = 0; std::vector<uint8_t> newdata; uint256 gametxid,playertxid; FILE *fp; uint8_t pub33[33];
|
||||
pk = pubkey2pk(Mypubkey());
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
result.push_back(Pair("name","rogue"));
|
||||
result.push_back(Pair("method","extract"));
|
||||
rogueaddr[0] = 0;
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
|
||||
{
|
||||
if ( n > 0 )
|
||||
@@ -949,23 +1025,35 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
result.push_back(Pair("gametxid",gametxid.GetHex()));
|
||||
if ( n == 2 )
|
||||
{
|
||||
if ( (pubstr= jstr(jitem(params,1),0)) != 0 && strlen(pubstr) == 66 )
|
||||
if ( (pubstr= jstr(jitem(params,1),0)) != 0 )
|
||||
{
|
||||
decode_hex(pub33,33,pubstr);
|
||||
pk = buf2pk(pub33);
|
||||
if (strlen(pubstr) == 66 )
|
||||
{
|
||||
decode_hex(pub33,33,pubstr);
|
||||
pk = buf2pk(pub33);
|
||||
}
|
||||
else if ( strlen(pubstr) < 36 )
|
||||
strcpy(rogueaddr,pubstr);
|
||||
}
|
||||
//fprintf(stderr,"gametxid.%s %s\n",gametxid.GetHex().c_str(),pubstr);
|
||||
}
|
||||
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
|
||||
if ( rogueaddr[0] == 0 )
|
||||
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
|
||||
result.push_back(Pair("rogueaddr",rogueaddr));
|
||||
str[0] = 0;
|
||||
if ( (keystrokes= rogue_extractgame(1,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
|
||||
{
|
||||
result.push_back(Pair("status","success"));
|
||||
flag = 1;
|
||||
hexstr = (char *)malloc(numkeys*2 + 1);
|
||||
for (i=0; i<numkeys; i++)
|
||||
sprintf(&hexstr[i<<1],"%02x",keystrokes[i]);
|
||||
hexstr[i<<1] = 0;
|
||||
result.push_back(Pair("keystrokes",hexstr));
|
||||
free(hexstr);
|
||||
result.push_back(Pair("numkeys",(int64_t)numkeys));
|
||||
result.push_back(Pair("playertxid",playertxid.GetHex()));
|
||||
result.push_back(Pair("extracted",str));
|
||||
result.push_back(Pair("numkeys",(int64_t)numkeys));
|
||||
result.push_back(Pair("seed",(int64_t)seed));
|
||||
sprintf(str,"cc/rogue/rogue %llu",(long long)seed);
|
||||
result.push_back(Pair("replay",str));
|
||||
@@ -1129,8 +1217,6 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
}
|
||||
else
|
||||
{
|
||||
//if ( maxplayers == 1 )
|
||||
// mult /= 2;
|
||||
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cpTokens,NULL))); // marker to token cc addr, burnable and validated
|
||||
mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode,1,mypk));
|
||||
@@ -1143,8 +1229,13 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
fprintf(stderr,"\nextracted $$$gold.%d -> %.8f ROGUE hp.%d strength.%d/%d level.%d exp.%d dl.%d n.%d amulet.%d\n",P.gold,(double)cashout/COIN,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel,n,P.amulet);
|
||||
if ( funcid == 'H' && maxplayers > 1 )
|
||||
{
|
||||
if ( (numplayers != maxplayers || (numplayers - rogue_playersalive(tmp,gametxid,maxplayers)) > 1) && P.amulet == 0 )
|
||||
return(cclib_error(result,"highlander must be a winner or last one standing"));
|
||||
if ( P.amulet == 0 )
|
||||
{
|
||||
if ( numplayers != maxplayers )
|
||||
return(cclib_error(result,"numplayers != maxplayers"));
|
||||
else if ( rogue_playersalive(tmp,tmp,gametxid,maxplayers,gameheight,gametx) > 1 )
|
||||
return(cclib_error(result,"highlander must be a winner or last one standing"));
|
||||
}
|
||||
cashout += numplayers * buyin;
|
||||
}
|
||||
if ( cashout >= txfee )
|
||||
@@ -1197,7 +1288,7 @@ UniValue rogue_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
|
||||
UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,gameheight,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin; uint64_t seed; bits256 t; char myrogueaddr[64]; CPubKey mypk,roguepk;
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,gameheight,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin; uint64_t seed; bits256 t; char myrogueaddr[64],str[64]; CPubKey mypk,roguepk;
|
||||
result.push_back(Pair("name","rogue"));
|
||||
result.push_back(Pair("method","gameinfo"));
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
|
||||
@@ -1218,12 +1309,17 @@ UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
result.push_back(Pair("seed",(int64_t)seed));
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
if ( CCgettxout(txid,i+1,1) < 0 )
|
||||
if ( CCgettxout(txid,i+1,1,0) < 0 )
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
rogue_gameplayerinfo(cp,obj,txid,tx,i+1,maxplayers,myrogueaddr);
|
||||
a.push_back(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"vout %d+1 is unspent",i);
|
||||
result.push_back(Pair("unspent",str));
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("players",a));
|
||||
} else return(cclib_error(result,"couldnt find valid game"));
|
||||
@@ -1234,7 +1330,7 @@ UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
|
||||
UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t maxplayers,numplayers,gameheight,nextheight,vout,numvouts; CPubKey roguepk; char coinaddr[64];
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t openslots,maxplayers,numplayers,gameheight,nextheight,vout,numvouts; CPubKey roguepk; char coinaddr[64];
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
GetCCaddress(cp,coinaddr,roguepk);
|
||||
@@ -1249,8 +1345,8 @@ UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
continue;
|
||||
if ( rogue_isvalidgame(cp,gameheight,tx,buyin,maxplayers,txid,1) == 0 && nextheight <= gameheight+ROGUE_MAXKEYSTROKESGAP )
|
||||
{
|
||||
rogue_playersalive(numplayers,txid,maxplayers);
|
||||
if ( numplayers < maxplayers )
|
||||
rogue_playersalive(openslots,numplayers,txid,maxplayers,gameheight,tx);
|
||||
if ( openslots > 0 )
|
||||
a.push_back(txid.GetHex());
|
||||
}
|
||||
}
|
||||
@@ -1313,7 +1409,7 @@ UniValue rogue_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
if ( rogue_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0) == 0 )
|
||||
{
|
||||
if ( CCgettxout(txid,vout,1) < 0 )
|
||||
if ( CCgettxout(txid,vout,1,0) < 0 )
|
||||
b.push_back(gametxid.GetHex());
|
||||
else a.push_back(gametxid.GetHex());
|
||||
}
|
||||
@@ -1445,7 +1541,15 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
if ( funcid == 'H' )
|
||||
cashout *= 2;
|
||||
if ( tx.vout.size() > 3 ) // orig of 't' has 0 cashout
|
||||
fprintf(stderr,"ht.%d txid.%s cashout %.8f vs vout2 %.8f\n",height,txid.GetHex().c_str(),(double)cashout/COIN,(double)tx.vout[2].nValue/COIN);
|
||||
{
|
||||
static char laststr[512]; char cashstr[512];
|
||||
sprintf(cashstr,"ht.%d txid.%s %d,%d %.8f vs vout2 %.8f",height,txid.GetHex().c_str(),tokentx,decoded,(double)cashout/COIN,(double)tx.vout[2].nValue/COIN);
|
||||
if ( strcmp(laststr,cashstr) != 0 )
|
||||
{
|
||||
strcpy(laststr,cashstr);
|
||||
fprintf(stderr,"%s\n",cashstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( funcid == 'Q' )
|
||||
{
|
||||
|
||||
@@ -2859,7 +2859,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
|
||||
decode_hex((uint8_t *)&txid,32,txidstr);
|
||||
txid = revuint256(txid);
|
||||
result.push_back(Pair("txid",txid.GetHex()));
|
||||
if ( CCgettxout(txid,0,1) < 0 )
|
||||
if ( CCgettxout(txid,0,1,0) < 0 )
|
||||
result.push_back(Pair("error","already solved"));
|
||||
else if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
|
||||
@@ -129,7 +129,7 @@ int32_t komodo_baseid(char *origbase)
|
||||
#ifndef SATOSHIDEN
|
||||
#define SATOSHIDEN ((uint64_t)100000000L)
|
||||
#endif
|
||||
int64_t komodo_current_supply(uint32_t nHeight)
|
||||
uint64_t komodo_current_supply(uint32_t nHeight)
|
||||
{
|
||||
uint64_t cur_money;
|
||||
int32_t baseid;
|
||||
@@ -264,5 +264,19 @@ int64_t komodo_current_supply(uint32_t nHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
return((int64_t)(cur_money + (cur_money * ASSETCHAINS_COMMISSION)));
|
||||
#define KOMODO_MAXNVALUE (((uint64_t)1 << 63) - 1)
|
||||
#define KOMODO_BIT63SET(x) ((x) & ((uint64_t)1 << 63))
|
||||
|
||||
if ( KOMODO_BIT63SET(cur_money) != 0 )
|
||||
return(KOMODO_MAXNVALUE);
|
||||
if ( ASSETCHAINS_COMMISSION != 0 )
|
||||
{
|
||||
uint64_t newval = (cur_money + (cur_money * ASSETCHAINS_COMMISSION));
|
||||
if ( KOMODO_BIT63SET(newval) != 0 )
|
||||
return(KOMODO_MAXNVALUE);
|
||||
else if ( newval < cur_money ) // check for underflow
|
||||
return(KOMODO_MAXNVALUE);
|
||||
return(newval);
|
||||
}
|
||||
return(cur_money);
|
||||
}
|
||||
|
||||
@@ -1562,7 +1562,7 @@ char *argv0names[] =
|
||||
(char *)"MNZ", (char *)"MNZ", (char *)"MNZ", (char *)"MNZ", (char *)"BTCH", (char *)"BTCH", (char *)"BTCH", (char *)"BTCH"
|
||||
};
|
||||
|
||||
int64_t komodo_max_money()
|
||||
uint64_t komodo_max_money()
|
||||
{
|
||||
return komodo_current_supply(10000000);
|
||||
}
|
||||
@@ -1787,6 +1787,11 @@ void komodo_args(char *argv0)
|
||||
ASSETCHAINS_FOUNDERS = GetArg("-ac_founders",0);// & 1;
|
||||
ASSETCHAINS_FOUNDERS_REWARD = GetArg("-ac_founders_reward",0);
|
||||
ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10);
|
||||
if ( ASSETCHAINS_SUPPLY > (uint64_t)90*1000*1000000 )
|
||||
{
|
||||
fprintf(stderr,"-ac_supply must be less than 90 billion\n");
|
||||
exit(0);
|
||||
}
|
||||
ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0);
|
||||
ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey","");
|
||||
ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script","");
|
||||
|
||||
@@ -2083,14 +2083,14 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo
|
||||
memset(&hashBlock,0,sizeof(hashBlock));
|
||||
// need a GetTransaction without lock so the validation code for assets can run without deadlock
|
||||
{
|
||||
//fprintf(stderr,"check mempool\n");
|
||||
//fprintf(stderr,"check mempool %s\n",hash.GetHex().c_str());
|
||||
if (mempool.lookup(hash, txOut))
|
||||
{
|
||||
//fprintf(stderr,"found in mempool\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"check disk\n");
|
||||
//fprintf(stderr,"check disk %s\n",hash.GetHex().c_str());
|
||||
|
||||
if (fTxIndex) {
|
||||
CDiskTxPos postx;
|
||||
@@ -2112,11 +2112,11 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo
|
||||
hashBlock = header.GetHash();
|
||||
if (txOut.GetHash() != hash)
|
||||
return error("%s: txid mismatch", __func__);
|
||||
//fprintf(stderr,"found on disk\n");
|
||||
//fprintf(stderr,"found on disk %s\n",hash.GetHex().c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"not found\n");
|
||||
//fprintf(stderr,"not found on disk %s\n",hash.GetHex().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ UniValue geterablockheights(const UniValue& params, bool fHelp)
|
||||
{
|
||||
char str[16];
|
||||
sprintf(str, "%d", era);
|
||||
ret.push_back(Pair(str,i));
|
||||
ret.push_back(Pair(str,(int64_t)i));
|
||||
lastera = era;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user