Merge pull request #133 from jl777/jl777

sync jl777
This commit is contained in:
ca333
2019-02-18 12:55:02 +01:00
committed by GitHub
14 changed files with 597 additions and 112 deletions

View File

@@ -177,7 +177,7 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
// find single-eval token user cc addr:
//GetCCaddress(cpTokens, signleEvalTokensCCaddr, pubkey2pk(origpubkey));
fprintf(stderr,"AssetValidate (%c)\n",funcid);
//fprintf(stderr,"AssetValidate (%c)\n",funcid);
if( funcid != 'o' && funcid != 'x' && eval->GetTxUnconfirmed(assetid, createTx, hashBlock) == 0 )
return eval->Invalid("cant find asset create txid");

View File

@@ -20,6 +20,10 @@
#include "primitives/transaction.h"
#include "cc/CCinclude.h"
//#define LEV_INFO 0
//#define LEV_DEBUG1 1
//#define LOGSTREAM(category, level, logoperator) { std::ostringstream stream; logoperator; for(int i = 0; i < level; i ++) if( LogAcceptCategory( (std::string(category) + (level > 0 ? std::string("-")+std::to_string(level) : std::string("") )).c_str() ) ) LogPrintStr(stream.str()); }
/*
* CC Eval method for import coin.
*
@@ -33,63 +37,299 @@ extern std::string ASSETCHAINS_SELFIMPORT;
extern uint16_t ASSETCHAINS_CODAPORT,ASSETCHAINS_BEAMPORT;
extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33];
int32_t GetSelfimportProof(std::string source,CMutableTransaction &mtx,CScript &scriptPubKey,TxProof &proof,uint64_t burnAmount,std::vector<uint8_t> rawtx,uint256 txid,std::vector<uint8_t> rawproof) // find burnTx with hash from "other" daemon
// utilities from gateways.cpp
uint256 BitcoinGetProofMerkleRoot(const std::vector<uint8_t> &proofData, std::vector<uint256> &txids);
uint256 GatewaysReverseScan(uint256 &txid, int32_t height, uint256 reforacletxid, uint256 batontxid);
int32_t GatewaysCointxidExists(struct CCcontract_info *cp, uint256 cointxid);
uint8_t DecodeGatewaysBindOpRet(char *depositaddr, const CScript &scriptPubKey, std::string &coin, uint256 &tokenid, int64_t &totalsupply, uint256 &oracletxid, uint8_t &M, uint8_t &N, std::vector<CPubKey> &pubkeys, uint8_t &taddr, uint8_t &prefix, uint8_t &prefix2);
// ac_import=chain support:
// encode opret for gateways import
CScript EncodeGatewaysImportTxOpRet(uint32_t targetCCid, std::string coin, uint256 bindtxid, std::vector<CPubKey> publishers, std::vector<uint256>txids, int32_t height, uint256 cointxid, int32_t claimvout, std::string rawburntx, std::vector<uint8_t>proof, CPubKey destpub, int64_t amount)
{
MerkleBranch newBranch; CMutableTransaction tmpmtx; CTransaction tx,vintx; uint256 blockHash; char destaddr[64],pkaddr[64];
tmpmtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight());
if ( source == "BEAM" )
CScript opret;
opret << OP_RETURN << E_MARSHAL(ss << targetCCid << coin << bindtxid << publishers << txids << height << cointxid << claimvout << rawburntx << proof << destpub << amount);
return(opret);
}
bool ImportCoinGatewaysVerify(char *refdepositaddr, uint256 oracletxid, int32_t claimvout, std::string refcoin, uint256 burntxid, const std::string rawburntx, std::vector<uint8_t>proof, uint256 merkleroot)
{
std::vector<uint256> txids;
uint256 proofroot, hashBlock, foundtxid = zeroid;
CTransaction oracletx, burntx;
std::string name, description, format;
char destaddr[64], destpubaddr[64], claimaddr[64];
int32_t i, numvouts;
int64_t nValue = 0;
if (myGetTransaction(oracletxid, oracletx, hashBlock) == 0 || (numvouts = oracletx.vout.size()) <= 0)
{
if ( ASSETCHAINS_BEAMPORT == 0 )
return(-1);
// confirm via ASSETCHAINS_BEAMPORT that burnTx/hash is a valid BEAM burn
// return(0);
LOGSTREAM("importcoin", CCLOG_INFO, stream << "ImportCoinGatewaysVerify can't find oracletxid=" << oracletxid.GetHex() << std::endl);
return false;
}
else if ( source == "CODA" )
if (DecodeOraclesCreateOpRet(oracletx.vout[numvouts - 1].scriptPubKey, name, description, format) != 'C' || name != refcoin)
{
if ( ASSETCHAINS_CODAPORT == 0 )
return(-1);
// confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn
// return(0);
LOGSTREAM("importcoin", CCLOG_INFO, stream << "ImportCoinGatewaysVerify mismatched oracle name=" << name.c_str() << " != " << refcoin.c_str() << std::endl);
return false;
}
else
proofroot = BitcoinGetProofMerkleRoot(proof, txids);
if (proofroot != merkleroot)
{
if ( !E_UNMARSHAL(rawtx, ss >> tx) )
return(-1);
scriptPubKey = tx.vout[0].scriptPubKey;
mtx = tx;
mtx.fOverwintered = tmpmtx.fOverwintered;
mtx.nExpiryHeight = tmpmtx.nExpiryHeight;
mtx.nVersionGroupId = tmpmtx.nVersionGroupId;
mtx.nVersion = tmpmtx.nVersion;
mtx.vout.clear();
mtx.vout.resize(1);
mtx.vout[0].nValue = burnAmount;
mtx.vout[0].scriptPubKey = scriptPubKey;
if ( tx.GetHash() != txid )
return(-1);
if ( source == "PUBKEY" )
LOGSTREAM("importcoin", CCLOG_INFO, stream << "ImportCoinGatewaysVerify mismatched proof merkleroot=" << proofroot.GetHex() << " and oracles merkleroot=" << merkleroot.GetHex() << std::endl);
return false;
}
// check the burntxid is in the proof:
if (std::find(txids.begin(), txids.end(), burntxid) == txids.end()) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "ImportCoinGatewaysVerify invalid proof for this burntxid=" << burntxid.GetHex() << std::endl);
return false;
}
/*
if (DecodeHexTx(burntx, rawburntx) != 0)
{
Getscriptaddress(claimaddr, burntx.vout[claimvout].scriptPubKey);
Getscriptaddress(destpubaddr, CScript() << ParseHex(HexStr(destpub)) << OP_CHECKSIG);
if (strcmp(claimaddr, destpubaddr) == 0)
{
// make sure vin0 is signed by ASSETCHAINS_OVERRIDE_PUBKEY33
if ( myGetTransaction(tx.vin[0].prevout.hash,vintx,blockHash) == 0 )
return(-1);
if ( tx.vin[0].prevout.n < vintx.vout.size() && Getscriptaddress(destaddr,vintx.vout[tx.vin[0].prevout.n].scriptPubKey) != 0 )
for (i = 0; i<numvouts; i++)
{
pubkey2addr(pkaddr,ASSETCHAINS_OVERRIDE_PUBKEY33);
if ( strcmp(pkaddr,destaddr) == 0 )
Getscriptaddress(destaddr, burntx.vout[i].scriptPubKey);
if (strcmp(refdepositaddr, destaddr) == 0)
{
proof = std::make_pair(txid,newBranch);
return(0);
foundtxid = burntx.GetHash();
nValue = burntx.vout[i].nValue;
break;
}
fprintf(stderr,"mismatched vin0[%d] -> %s vs %s\n",tx.vin[0].prevout.n,destaddr,pkaddr);
}
}
else if ( source == ASSETCHAINS_SELFIMPORT )
else fprintf(stderr, "claimaddr.(%s) != destpubaddr.(%s)\n", claimaddr, destpubaddr);
}*/
/*
if (foundtxid == burntxid) {
LOGSTREAM("importcoin", LEV_DEBUG1, stream << "verified proof for burntxid=" << burntxid.GetHex() << " in merkleroot merkleroot" << std::endl);
return(nValue);
}
else {
LOGSTREAM("importcoin", LEV_INFO, stream << "verified proof for burntxid=" << burntxid.GetHex() << " in merkleroot merkleroot" << std::endl);
fprintf(stderr, "(%s) != (%s) or txid %s mismatch.%d or script mismatch\n", refdepositaddr, destaddr, uint256_str(str, foundtxid), foundtxid != burntxid);
*/
LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "verified proof for burntxid=" << burntxid.GetHex() << " in trusted merkleroot" << std::endl);
return true;
}
// make import tx with burntx and its proof of existence
std::string MakeGatewaysImportTx(uint64_t txfee, uint256 bindtxid, int32_t height, std::string refcoin, std::vector<uint8_t>proof, std::string rawburntx, int32_t ivout, uint256 burntxid)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
CTransaction burntx, bindtx;
CPubKey mypk, gatewayspk;
uint256 oracletxid, merkleroot, mhash, hashBlock, tokenid, txid;
int64_t totalsupply;
int32_t i, m, n, numvouts;
uint8_t M, N, taddr, prefix, prefix2;
std::string coin;
struct CCcontract_info *cp, C;
std::vector<CPubKey> pubkeys, publishers;
std::vector<uint256>txids;
char depositaddr[64], txidaddr[64];
cp = CCinit(&C, EVAL_GATEWAYS);
/*if (txfee == 0)
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp, 0); */
if (!E_UNMARSHAL(ParseHex(rawburntx), ss >> burntx))
return std::string("");
CAmount amount = GetCoinImportValue(burntx); // equal to int64_t
LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeGatewaysImportTx height=" << height << " coin=" << refcoin << " amount=" << (double)amount / COIN << " pubkeys num=" << pubkeys.size() << std::endl);
if (GetTransaction(bindtxid, bindtx, hashBlock, false) == 0 || (numvouts = bindtx.vout.size()) <= 0)
{
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeGatewaysImportTx cant find bindtxid=" << bindtxid.GetHex() << std::endl);
return("");
}
/* if (DecodeGatewaysBindOpRet(depositaddr, bindtx.vout[numvouts - 1].scriptPubKey, coin, tokenid, totalsupply, oracletxid, M, N, pubkeys, taddr, prefix, prefix2) != 'B' || refcoin != coin)
{
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeGatewaysImportTx invalid coin - bindtxid=" << bindtxid.GetHex() << " coin=" << coin.c_str() << std::endl);
return("");
} eliminate link err */
n = (int32_t)pubkeys.size();
merkleroot = zeroid;
for (i = m = 0; i < n; i++)
{
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeGatewaysImportTx using pubkeys[" << i << "]=" << HexStr(pubkeys[i]) << std::endl);
if ((mhash = GatewaysReverseScan(txid, height, oracletxid, OraclesBatontxid(oracletxid, pubkeys[i]))) != zeroid)
{
// source is external coin is the assetchains symbol in the burnTx OP_RETURN
// burnAmount, rawtx and rawproof should be enough for gatewaysdeposit equivalent
if (merkleroot == zeroid)
merkleroot = mhash, m = 1;
else if (mhash == merkleroot)
m ++;
publishers.push_back(pubkeys[i]);
txids.push_back(txid);
}
}
return(-1);
LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "MakeGatewaysImportTx burntxid=" << burntxid.GetHex() << " nodes m=" << m << " of n=" << n << std::endl);
if (merkleroot == zeroid || m < n / 2) // none or less than half oracle nodes sent merkleroot
{
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeGatewaysImportTx couldnt find merkleroot for block height=" << height << "coin=" << coin.c_str() << " oracleid=" << oracletxid.GetHex() << " m=" << m << " vs n=" << n << std::endl );
return("");
}
if (GatewaysCointxidExists(cp, burntxid) != 0)
{
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeGatewaysImportTx burntxid=" << burntxid.GetHex() << " already exists" << std::endl);
return("");
}
if (!ImportCoinGatewaysVerify(depositaddr, oracletxid, ivout, coin, burntxid, rawburntx, proof, merkleroot))
{
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeGatewaysImportTx could not validate burntx, txid=" << burntxid.GetHex() << std::endl);
return("");
}
std::vector<uint256> leaftxids;
BitcoinGetProofMerkleRoot(proof, leaftxids);
MerkleBranch newBranch(0, leaftxids);
TxProof txProof = std::make_pair(burntxid, newBranch);
std::vector<CTxOut> vouts;
return HexStr(E_MARSHAL(ss << MakeImportCoinTransaction(txProof, burntx, vouts)));
/*if (AddNormalinputs(mtx, mypk, 3 * txfee, 4) > 0)
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode, txfee, destpub));
mtx.vout.push_back(CTxOut(txfee, CScript() << ParseHex(HexStr(CCtxidaddr(txidaddr, burntxid))) << OP_CHECKSIG));
return(FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeGatewaysImportTxOpRet(0xFFFFFFFF, coin, bindtxid, publishers, txids, height, burntxid, ivout, rawburntx, proof, destpub, amount)));
}
LOGSTREAM("importcoin", LEV_INFO, stream << "MakeGatewaysImportTx coud not find normal imputs" << std::endl);*/
return("");
}
// makes source tx for self import tx
std::string MakeSelfImportSourceTx(CTxDestination &dest, int64_t amount, CMutableTransaction &mtx)
{
const int64_t txfee = 10000;
int64_t inputs, change;
CPubKey myPubKey = Mypubkey();
struct CCcontract_info *cpDummy, C;
cpDummy = CCinit(&C, EVAL_TOKENS);
mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
if( (inputs = AddNormalinputs(mtx, myPubKey, txfee, 4)) == 0 ) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "MakeSelfImportSourceTx: cannot find normal imputs for txfee" << std::endl);
return std::string("");
}
CScript scriptPubKey = GetScriptForDestination(dest);
mtx.vout.push_back(CTxOut(txfee, scriptPubKey));
change = inputs - txfee;
if( change != 0 )
mtx.vout.push_back(CTxOut(change, CScript() << ParseHex(HexStr(myPubKey)) << OP_CHECKSIG));
//make opret with amount:
return FinalizeCCTx(0, cpDummy, mtx, myPubKey, txfee, CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN << (uint8_t)'A' << amount));
}
// make sure vin0 is signed by ASSETCHAINS_OVERRIDE_PUBKEY33
int32_t CheckVin0PubKey(const CTransaction &sourcetx)
{
CTransaction vintx;
uint256 blockHash;
char destaddr[64], pkaddr[64];
if( !myGetTransaction(sourcetx.vin[0].prevout.hash, vintx, blockHash) ) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "CheckVin0PubKey() could not load vintx" << sourcetx.vin[0].prevout.hash.GetHex() << std::endl);
return(-1);
}
if( sourcetx.vin[0].prevout.n < vintx.vout.size() && Getscriptaddress(destaddr, vintx.vout[sourcetx.vin[0].prevout.n].scriptPubKey) != 0 )
{
pubkey2addr(pkaddr, ASSETCHAINS_OVERRIDE_PUBKEY33);
if (strcmp(pkaddr, destaddr) == 0) {
return(0);
}
LOGSTREAM("importcoin", CCLOG_INFO, stream << "CheckVin0PubKey() mismatched vin0[prevout.n=" << sourcetx.vin[0].prevout.n << "] -> destaddr=" << destaddr << " vs pkaddr=" << pkaddr << std::endl);
}
return -1;
}
// ac_import=PUBKEY support:
// prepare a tx for creating import tx and quasi-burn tx
int32_t GetSelfimportProof(std::string source, CMutableTransaction &mtx, CScript &scriptPubKey, TxProof &proof, std::string rawsourcetx, int32_t &ivout, uint256 sourcetxid, uint64_t burnAmount) // find burnTx with hash from "other" daemon
{
MerkleBranch newBranch;
CMutableTransaction tmpmtx;
CTransaction sourcetx;
tmpmtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
if (!E_UNMARSHAL(ParseHex(rawsourcetx), ss >> sourcetx)) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: could not unmarshal source tx" << std::endl);
return(-1);
}
if (sourcetx.vout.size() == 0) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: vout size is 0" << std::endl);
return -1;
}
if (ivout < 0) { // "ivout < 0" means "find"
// try to find vout
CPubKey myPubkey = Mypubkey();
ivout = 0;
// skip change:
if (sourcetx.vout[ivout].scriptPubKey == (CScript() << ParseHex(HexStr(myPubkey)) << OP_CHECKSIG))
ivout++;
}
if (ivout >= sourcetx.vout.size()) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: needed vout not found" << std::endl);
return -1;
}
LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "GetSelfimportProof: using vout[" << ivout << "] of the passed rawtx" << std::endl);
scriptPubKey = sourcetx.vout[ivout].scriptPubKey;
//mtx is template for import tx
mtx = sourcetx;
mtx.fOverwintered = tmpmtx.fOverwintered;
//malleability fix for burn tx:
//mtx.nExpiryHeight = tmpmtx.nExpiryHeight;
mtx.nExpiryHeight = sourcetx.nExpiryHeight;
mtx.nVersionGroupId = tmpmtx.nVersionGroupId;
mtx.nVersion = tmpmtx.nVersion;
mtx.vout.clear();
mtx.vout.resize(1);
mtx.vout[0].nValue = burnAmount;
mtx.vout[0].scriptPubKey = scriptPubKey;
// not sure we need this now as we create sourcetx ourselves:
if (sourcetx.GetHash() != sourcetxid) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "GetSelfimportProof: passed source txid incorrect" << std::endl);
return(-1);
}
// check ac_pubkey:
if (CheckVin0PubKey(sourcetx) < 0) {
return -1;
}
proof = std::make_pair(sourcetxid, newBranch);
return 0;
}
// use proof from the above functions to validate the import
@@ -116,9 +356,52 @@ int32_t CheckGATEWAYimport(TxProof proof,std::vector<uint8_t> rawproof,CTransact
int32_t CheckPUBKEYimport(TxProof proof,std::vector<uint8_t> rawproof,CTransaction burnTx,std::vector<CTxOut> payouts)
{
// if burnTx has ASSETCHAINS_PUBKEY vin, it is valid return(0);
fprintf(stderr,"proof txid.%s\n",proof.first.GetHex().c_str());
LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "proof txid=" << proof.first.GetHex() << std::endl);
uint256 sourcetxid = proof.first, hashBlock;
CTransaction sourcetx;
if (!myGetTransaction(sourcetxid, sourcetx, hashBlock)) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "could not load source txid=" << sourcetxid.GetHex() << std::endl);
return -1;
}
if (sourcetx.vout.size() == 0) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "no vouts in source txid=" << sourcetxid.GetHex() << std::endl);
return -1;
}
// might be malleable:
if (burnTx.nExpiryHeight != sourcetx.nExpiryHeight) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "burntx nExpiryHeight incorrect for source txid=" << sourcetxid.GetHex() << std::endl);
return -1;
}
//ac_pubkey check:
if (CheckVin0PubKey(sourcetx) < 0) {
return -1;
}
// get source tx opret:
std::vector<uint8_t> vopret;
uint8_t evalCode, funcId;
int64_t amount;
GetOpReturnData(sourcetx.vout.back().scriptPubKey, vopret);
if (vopret.size() == 0 || !E_UNMARSHAL(vopret, ss >> evalCode; ss >> funcId; ss >> amount) || evalCode != EVAL_IMPORTCOIN || funcId != 'A') {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "no or incorrect opret to validate in source txid=" << sourcetxid.GetHex() << std::endl);
return -1;
}
LOGSTREAM("importcoin", CCLOG_DEBUG1, stream << "importTx amount=" << payouts[0].nValue << " burnTx amount=" << burnTx.vout[0].nValue << " opret amount=" << amount << " source txid=" << sourcetxid.GetHex() << std::endl);
// amount malleability check with the opret from the source tx:
if (payouts[0].nValue != amount) { // assume that burntx amount is checked in the common code in Eval::ImportCoin()
LOGSTREAM("importcoin", CCLOG_INFO, stream << "importTx amount != amount in the opret of source txid=" << sourcetxid.GetHex() << std::endl);
return -1;
}
return(0);
return(-1);
}
bool Eval::ImportCoin(const std::vector<uint8_t> params,const CTransaction &importTx,unsigned int nIn)
@@ -132,10 +415,10 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params,const CTransaction &impo
return Invalid("invalid-params");
// Control all aspects of this transaction
// It should not be at all malleable
if (MakeImportCoinTransaction(proof, burnTx, payouts).GetHash() != importTx.GetHash())
if (MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication
return Invalid("non-canonical");
// burn params
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash,rawproof))
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash, rawproof))
return Invalid("invalid-burn-tx");
// check burn amount
{

View File

@@ -162,7 +162,7 @@ int32_t mvaddch(int32_t y, int32_t x, chtype ch)
int32_t waddstr(WINDOW *win, const char *str)
{
int32_t i;
fprintf(stderr,"%s\n",str);
//fprintf(stderr,"%s\n",str);
for (i=0; str[i]!=0; i++)
waddch(win,str[i]);
return(0);

View File

@@ -28,9 +28,8 @@ void restore_player(struct rogue_state *rs)
//rs->P.gold = purse;
max_hp = rs->P.hitpoints;
pstats.s_str = rs->P.strength & 0xffff;
max_stats.s_str = rs->P.strength >> 16;
if ( max_stats.s_str < 12 )
max_stats.s_str = 12;
if ( (max_stats.s_str= (rs->P.strength >> 16) & 0xffff) == 0 )
max_stats.s_str = 16;
if ( pstats.s_str > max_stats.s_str )
pstats.s_str = max_stats.s_str;
pstats.s_lvl = rs->P.level;

View File

@@ -162,7 +162,7 @@ readchar(struct rogue_state *rs)
c = rs->keystrokes[rs->ind++];
while ( c == 'Q' && rs->ind < rs->numkeys )
{
fprintf(stderr,"Got 'Q' next (%c)\n",rs->keystrokes[rs->ind]); sleep(2);
//fprintf(stderr,"Got 'Q' next (%c)\n",rs->keystrokes[rs->ind]); sleep(2);
if ( rs->keystrokes[rs->ind] == 'y' )
return(c);
rs->ind++;

View File

@@ -52,9 +52,9 @@ add_pack(struct rogue_state *rs,THING *obj, bool silent)
if (pack == NULL)
{
pack = obj;
obj->o_packch = pack_char();
inpack++;
pack = obj;
obj->o_packch = pack_char();
inpack++;
}
else
{
@@ -250,9 +250,16 @@ pack_char()
int32_t num_packitems()
{
THING *list = pack;
int32_t type = 0,n = 0;
int32_t type = 0,n = 0,total = 0;
for (; list != NULL; list = next(list))
n++;
{
if ( list->o_packch != 0 )
{
n++;
total += list->o_count;
}
}
fprintf(stderr,"total.%d vs %d inventory letters\n",total,n); sleep(1);
return(n);
}
@@ -288,11 +295,11 @@ inventory(struct rogue_state *rs,THING *list, int type)
// fprintf(stderr,"n_objs.%d vs inpack.%d\n",n_objs,inpack), sleep(2);
if (n_objs == 0)
{
if (terse)
msg(rs,type == 0 ? (char *)"empty handed" : (char *)"nothing appropriate");
else
msg(rs,type == 0 ? (char *)"you are empty handed" : (char *)"you don't have anything appropriate");
return FALSE;
if (terse)
msg(rs,type == 0 ? (char *)"empty handed" : (char *)"nothing appropriate");
else
msg(rs,type == 0 ? (char *)"you are empty handed" : (char *)"you don't have anything appropriate");
return FALSE;
}
end_line(rs);
return TRUE;

View File

@@ -250,6 +250,7 @@ int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t nu
rs->restoring = 1;
//fprintf(stderr,"restore player packsize.%d HP.%d\n",rs->P.packsize,rs->P.hitpoints);
}
globalR = *rs;
uint32_t starttime = (uint32_t)time(NULL);
rogueiterate(rs);
if ( 0 )
@@ -594,7 +595,7 @@ playit(struct rogue_state *rs)
{
if ( rs->replaydone != 0 )
{
if ( rs->sleeptime != 0 )
if ( 0 && rs->sleeptime != 0 )
sleep(3);
return;
}
@@ -622,7 +623,7 @@ int32_t _quit()
//fprintf(stderr,"inside quit(%d)\n",sig);
getyx(curscr, oy, ox);
msg(rs,"really quit?");
sleep(1);
//sleep(1);
if ( (c= readchar(rs)) == 'y')
{
if ( rs->guiflag != 0 )
@@ -760,7 +761,7 @@ my_exit(int st)
exit(st);
else if ( counter++ < 10 )
{
fprintf(stderr,"would have exit.(%d)\n",st);
fprintf(stderr,"would have exit.(%d) sleeptime.%d\n",st,globalR.sleeptime);
globalR.replaydone = 1;
}
}

View File

@@ -1218,7 +1218,7 @@ UniValue rogue_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
{
CScript scriptPubKey; std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid; int32_t i,ind,errflag,dispflag,score,numvouts; CTransaction vintx; uint256 hashBlock;
CScript scriptPubKey; std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid; int32_t i,maxplayers,decoded=0,regslot,ind,errflag,dispflag,score,numvouts; CTransaction vintx; CPubKey pk; uint256 hashBlock,gametxid,tokenid,batontxid,playertxid; int64_t buyin; std::vector<uint8_t> playerdata,keystrokes; std::string symbol,pname;
if ( (numvouts= tx.vout.size()) > 1 )
{
scriptPubKey = tx.vout[numvouts-1].scriptPubKey;
@@ -1226,32 +1226,73 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
if ( vopret.size() > 2 )
{
script = (uint8_t *)vopret.data();
if ( script[0] == EVAL_ROGUE )
funcid = script[1];
if ( (e= script[0]) == EVAL_TOKENS )
{
switch ( script[1] )
if ( (funcid= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) == 0 )
{
case 'G': // newgame
case 'R': // register
case 'K': // keystrokes
case 'H': // win
case 'Q': // bailout
if ( (funcid= rogue_registeropretdecode(gametxid,tokenid,playertxid,scriptPubKey)) == 0 )
{
funcid = 'Q';
fprintf(stderr,"ht.%d couldnt decode tokens opret\n",height);
} else e = EVAL_ROGUE, decoded = 1;
} else e = EVAL_ROGUE, decoded = 1;
}
if ( e == EVAL_ROGUE )
{
if ( decoded == 0 )
{
switch ( funcid )
{
case 'G':
if ( (funcid= rogue_newgameopreturndecode(buyin,maxplayers,scriptPubKey)) != 'G' )
return eval->Invalid("couldnt decode newgame opret");
// validate newgame tx
return(true);
break;
case 'R':
if ( (funcid= rogue_registeropretdecode(gametxid,tokenid,playertxid,scriptPubKey)) != 'R' )
return eval->Invalid("couldnt decode register opret");
break;
case 'K':
if ( (funcid= rogue_keystrokesopretdecode(gametxid,batontxid,pk,keystrokes,scriptPubKey)) != 'K' )
return eval->Invalid("couldnt decode keystrokes opret");
// validate keystrokes are from the correct pk. might need to add vin
return(true);
break;
case 'H': case 'Q':
if ( (f= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) != funcid )
return eval->Invalid("couldnt decode H/Q opret");
break;
default:
return eval->Invalid("illegal rogue non-decoded funcid");
break;
}
}
switch ( funcid )
{
case 'R':
// validate register: within 60 blocks, not duplicate, etc.
return(true);
break;
case 'H': // fall through
case 'Q':
// make sure any playerdata is reproduced via replay
if ( funcid == 'Q' )
{
// validate bailout constraints
}
else // 'H'
{
// validate winner constraints
}
return(true);
break;
default:
fprintf(stderr,"ht.%d rogue.(%c)\n",height,script[1]);
return eval->Invalid("illegal rogue funcid");
break;
}
}
else if ( script[0] == EVAL_TOKENS )
{
if ( script[1] == 'c' )
{
return(true);
}
else
{
return(true);
}
} else return eval->Invalid("illegal evalcode");
} else return eval->Invalid("opret too small");
} else return eval->Invalid("not enough vouts");