corr DecodeHeirEitherOpRet in validators

added EVAL_TOKENS check in DecodeTokenOpRet
This commit is contained in:
dimxy
2019-01-14 17:26:42 +05:00
parent 08c0a5a8c6
commit 1fb94e5a34
3 changed files with 33 additions and 164 deletions

View File

@@ -125,6 +125,9 @@ uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCode, uint256
bool isEof = true;
evalCode = script[0];
if (evalCode != EVAL_TOKENS)
return (uint8_t)0;
funcId = script[1];
//fprintf(stderr,"decode.[%c]\n",funcId);

View File

@@ -125,23 +125,10 @@ bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction
uint256 fundingTxidInOpret = zeroid, latestTxid = zeroid, dummyTokenid, tokenid = zeroid;
CScript fundingTxOpRetScript;
uint8_t hasHeirSpendingBegun = 0, dummyHasHeirSpendingBegun;
uint8_t hasHeirSpendingBegun = 0, hasHeirSpendingBegunDummy;
uint8_t evalCodeTokens = 0;
std::vector<CPubKey> voutPubkeys;
std::vector<uint8_t> vopretExtra;
CScript heirScript = tx.vout[tx.vout.size() - 1].scriptPubKey;
int32_t heirType = HEIR_COINS;
uint8_t funcId = DecodeTokenOpRet(heirScript, evalCodeTokens, tokenid, voutPubkeys, vopretExtra);
if (funcId != 0) {
heirScript = CScript(vopretExtra);
heirType = HEIR_TOKENS;
}
funcId = DecodeHeirOpRet(heirScript, fundingTxidInOpret, dummyHasHeirSpendingBegun, true);
CScript opret = (tx.vout.size() > 0) ? tx.vout[tx.vout.size() - 1].scriptPubKey : CScript(); // check boundary
uint8_t funcId = DecodeHeirEitherOpRet(opret, tokenid, fundingTxidInOpret, hasHeirSpendingBegunDummy, true);
if (funcId == 0)
return eval->Invalid("invalid opreturn format");
@@ -149,7 +136,7 @@ bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction
if (fundingTxidInOpret == zeroid) {
return eval->Invalid("invalid tx opreturn format: no fundingtxid present");
}
if (heirType == HEIR_COINS)
if (tokenid == zeroid)
latestTxid = FindLatestFundingTx<CoinHelper>(fundingTxidInOpret, dummyTokenid, fundingTxOpRetScript, hasHeirSpendingBegun);
else
latestTxid = FindLatestFundingTx<TokenHelper>(fundingTxidInOpret, tokenid, fundingTxOpRetScript, hasHeirSpendingBegun);
@@ -159,7 +146,7 @@ bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction
}
}
else {
fundingTxOpRetScript = tx.vout[numvouts - 1].scriptPubKey;
fundingTxOpRetScript = opret;
}
std::cerr << "HeirValidate funcid=" << (char)funcId << " evalcode=" << (int)cpHeir->evalcode << std::endl;
@@ -185,7 +172,7 @@ bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction
// vout.1: txfee for CC addr used as a marker
// vout.2: normal change
// vout.n-1: opreturn 't' tokenid 'F' ownerpk heirpk inactivitytime heirname tokenid
if (heirType == HEIR_TOKENS)
if (tokenid != zeroid)
return RunValidationPlans<TokenHelper>(funcId, cpTokens, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun);
else
return eval->Invalid("unexpected HeirValidate for heirfund");
@@ -206,7 +193,7 @@ bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction
// vout.0: funding CC 1of2 addr for the owner and heir
// vout.1: normal change
// vout.n-1: opreturn 't' tokenid 'A' ownerpk heirpk inactivitytime fundingtx
if (heirType == HEIR_TOKENS)
if (tokenid != zeroid)
return RunValidationPlans<TokenHelper>(funcId, cpTokens, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun);
else
return eval->Invalid("unexpected HeirValidate for heiradd");
@@ -230,7 +217,7 @@ bool HeirValidate(struct CCcontract_info* cpHeir, Eval* eval, const CTransaction
// vout.1: change to CC 1of2 addr
// vout.2: change to normal from txfee input if any
// vout.n-1: opreturn 't' tokenid 'C' ownerpk heirpk inactivitytime fundingtx
if (heirType == HEIR_TOKENS)
if (tokenid != zeroid)
return RunValidationPlans<TokenHelper>(funcId, cpTokens, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun);
else
return RunValidationPlans<CoinHelper>(funcId, cpHeir, eval, tx, latestTxid, fundingTxOpRetScript, hasHeirSpendingBegun);
@@ -267,44 +254,6 @@ template <class Helper> int64_t IsHeirFundingVout(struct CCcontract_info* cp, co
return (0);
}
// not used
bool HeirExactAmounts(struct CCcontract_info* cp, Eval* eval, const CTransaction& tx, int32_t minage, uint64_t txfee)
{
static uint256 zerohash;
CTransaction vinTx;
uint256 hashBlock, activehash;
int32_t i, numvins, numvouts;
int64_t inputs = 0, outputs = 0, assetoshis;
numvins = tx.vin.size();
numvouts = tx.vout.size();
for (i = 0; i < numvins; i++) {
//fprintf(stderr,"HeirExactAmounts() vini.%d\n",i);
if ((*cp->ismyvin)(tx.vin[i].scriptSig) != 0) {
//fprintf(stderr,"HeirExactAmounts() vini.%d check mempool\n",i);
if (eval->GetTxUnconfirmed(tx.vin[i].prevout.hash, vinTx, hashBlock) == 0)
return eval->Invalid("cant find vinTx");
else {
//fprintf(stderr,"HeirExactAmounts() vini.%d check hash and vout\n",i);
if (hashBlock == zerohash)
return eval->Invalid("cant Heir from mempool");
////if ( (assetoshis= IsHeirCCvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
//// inputs += assetoshis;
}
}
}
for (i = 0; i < numvouts; i++) {
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
////if ( (assetoshis= IsHeirvout(cp,tx,i)) != 0 )
//// outputs += assetoshis;
}
if (inputs != outputs + txfee) {
fprintf(stderr, "HeirExactAmounts() inputs %llu vs outputs %llu\n", (long long)inputs, (long long)outputs);
return eval->Invalid("mismatched inputs != outputs + txfee");
}
else
return (true);
}
// makes coin initial tx opret
CScript EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName)
{
@@ -373,9 +322,8 @@ uint8_t _DecodeHeirOpRet(std::vector<uint8_t> vopret, CPubKey& ownerPubkey, CPub
return (uint8_t)0;
}
/**
* overload for 'F' opret
*/
/* not used, see DecodeHeirOpRet(vopret,...)
// overload for 'F' opret
uint8_t DecodeHeirOpRet(CScript scriptPubKey, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, bool noLogging)
{
uint256 dummytxid;
@@ -388,11 +336,11 @@ uint8_t DecodeHeirOpRet(CScript scriptPubKey, CPubKey& ownerPubkey, CPubKey& hei
return (uint8_t)0;
}
return _DecodeHeirOpRet(vopret, ownerPubkey, heirPubkey, inactivityTime, heirName, dummytxid, dummyHasHeirSpendingBegun, noLogging);
}
}*/
/**
* overload for A, C oprets and AddHeirContractInputs
*/
/* not used, see DecodeHeirOpRet(vopret,...)
// overload for A, C oprets and AddHeirContractInputs
uint8_t DecodeHeirOpRet(CScript scriptPubKey, uint256& fundingtxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging)
{
CPubKey dummyOwnerPubkey, dummyHeirPubkey;
@@ -407,7 +355,7 @@ uint8_t DecodeHeirOpRet(CScript scriptPubKey, uint256& fundingtxidInOpret, uint8
}
return _DecodeHeirOpRet(vopret, dummyOwnerPubkey, dummyHeirPubkey, dummyInactivityTime, dummyHeirName, fundingtxidInOpret, hasHeirSpendingBegun, noLogging);
}
} */
// decode combined opret:
uint8_t _DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, uint256& fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging)
@@ -473,8 +421,8 @@ template <class Helper> uint256 _FindLatestFundingTx(uint256 fundingtxid, uint8_
// get initial funding tx and set it as initial lasttx:
if (myGetTransaction(fundingtxid, fundingtx, hashBlock) && fundingtx.vout.size()) {
CScript heirScript = (fundingtx.vout.size() > 0) ? fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey : CScript();
CScript heirScript = (fundingtx.vout.size() > 0) ? fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey : CScript();
uint8_t funcId = DecodeHeirEitherOpRet(heirScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, true);
if (funcId != 0) {
// found at least funding tx!
@@ -979,8 +927,6 @@ UniValue HeirClaimTokenCaller(uint256 fundingtxid, uint64_t txfee, int64_t amoun
return HeirClaim<TokenHelper>(fundingtxid, txfee, amount);
}
/**
* heirinfo rpc call implementation
* returns some information about heir CC contract plan by a handle of initial fundingtxid:
@@ -1160,23 +1106,15 @@ template <typename Helper>void _HeirList(struct CCcontract_info *cp, UniValue &r
//std::cerr << "HeirList() checking txid=" << txid.GetHex() << " vout=" << vout << '\n';
CTransaction fundingtx;
if (GetTransaction(txid, fundingtx, hashBlock, false) != 0 && (fundingtx.vout.size() - 1) > 0) {
if (GetTransaction(txid, fundingtx, hashBlock, false)) {
CPubKey ownerPubkey, heirPubkey;
std::string heirName;
int64_t inactivityTimeSec;
const bool noLogging = true;
uint8_t evalCodeTokens = 0;
uint256 tokenid;
std::vector<uint8_t> vopretExtra;
std::vector<CPubKey> voutPubkeys;
CScript heirScript = fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey;
uint8_t funcId = DecodeTokenOpRet(heirScript, evalCodeTokens, tokenid, voutPubkeys, vopretExtra);
if (funcId != 0) {
heirScript = CScript(vopretExtra);
}
funcId = DecodeHeirOpRet(heirScript, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, noLogging);
CScript opret = (fundingtx.vout.size() > 0) ? fundingtx.vout[fundingtx.vout.size() - 1].scriptPubKey : CScript();
uint8_t funcId = DecodeHeirEitherOpRet(opret, tokenid, ownerPubkey, heirPubkey, inactivityTimeSec, heirName, true);
// note: if it is not Heir token funcId would be equal to 0
if (funcId == 'F') {

View File

@@ -4,29 +4,21 @@
#include "CCinclude.h"
#include "CCHeir.h"
#define NOT_HEIR (-1)
#define HEIR_COINS 1
#define HEIR_TOKENS 2
#define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos)
// makes coin initial tx opret
CScript EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName);
CScript EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t isHeirSpendingBegan);
// makes token opret
//CScript EncodeHeirTokensCreateOpRet(uint8_t funcid, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string hearName);
//CScript EncodeHeirTokensOpRet(uint8_t funcid, uint256 tokenid, std::vector<CPubKey> voutPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan);
template <class Helper> uint256 FindLatestFundingTx(uint256 fundingtxid, uint256 &tokenid, CScript& opRetScript, uint8_t &isHeirSpendingBegan);
uint8_t DecodeHeirOpRet(CScript scriptPubKey, uint256& fundingtxid, uint8_t &isHeirSpendingBegan, bool noLogging = false);
uint8_t DecodeHeirOpRet(CScript scriptPubKey, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, bool noLogging = false);
uint8_t DecodeHeirEitherOpret(CScript scriptPubKey, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, bool noLogging = false);
uint8_t DecodeHeirEitherOpret(CScript scriptPubKey, uint256 &tokenid, uint256 &fundingTxidInOpret, uint8_t hasHeirSpendingBegun, bool noLogging = false);
//uint8_t DecodeHeirOpRet(CScript scriptPubKey, uint256& fundingtxid, uint8_t &isHeirSpendingBegan, bool noLogging = false);
//uint8_t DecodeHeirOpRet(CScript scriptPubKey, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, bool noLogging = false);
uint8_t DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, bool noLogging = false);
uint8_t DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, uint256 &fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging = false);
inline static bool isMyFuncId(uint8_t funcid) { return IS_CHARINSTR(funcid, "FAC"); }
inline static bool isSpendingTx(uint8_t funcid) { return (funcid == 'C'); }
// helper class to allow polymorphic behaviour for HeirXXX() functions in case of coins
class CoinHelper {
public:
@@ -411,22 +403,7 @@ public:
std::string heirName;
uint256 tokenid;
uint8_t evalCodeTokens = 0;
std::vector<uint8_t> vopretExtra;
std::vector<CPubKey> dummyVoutPubkeys;
CScript heirScript = m_fundingOpretScript;
if (typeid(Helper) == typeid(TokenHelper)) {
if (DecodeTokenOpRet(heirScript, evalCodeTokens, tokenid, dummyVoutPubkeys, vopretExtra) != 0) {
heirScript = CScript(vopretExtra);
}
else {
message = m_customMessage + std::string(" invalid token opreturn format");
std::cerr << "CCC1of2AddressValidator::validateVout() exits with false: " << message << std::endl;
return false;
}
}
uint8_t funcId = DecodeHeirOpRet(heirScript, ownerPubkey, heirPubkey, inactivityTime, heirName, false);
uint8_t funcId = DecodeHeirEitherOpRet(m_fundingOpretScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, true);
if (funcId == 0) {
message = m_customMessage + std::string(" invalid opreturn format");
std::cerr << "CCC1of2AddressValidator::validateVout() exits with false: " << message << std::endl;
@@ -481,28 +458,15 @@ public:
///std::cerr << "CMyPubkeyVoutValidator::validateVout() m_opRetScript=" << m_opRetScript.ToString() << std::endl;
uint8_t evalCodeTokens = 0;
std::vector<uint8_t> vopretExtra;
std::vector<CPubKey> dummyVoutPubkeys;
CScript ownerScript;
CScript heirScript = m_fundingOpretScript;
if (typeid(Helper) == typeid(TokenHelper)) {
if (DecodeTokenOpRet(heirScript, evalCodeTokens, tokenid, dummyVoutPubkeys, vopretExtra) != 0) {
heirScript = CScript(vopretExtra);
}
else {
message = std::string("invalid token opreturn format");
return false;
}
}
// get both pubkeys:
uint8_t funcId = DecodeHeirOpRet(heirScript, ownerPubkey, heirPubkey, inactivityTime, heirName, false);
uint8_t funcId = DecodeHeirEitherOpRet(m_fundingOpretScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, true);
if (funcId == 0) {
message = std::string("invalid opreturn format");
return false;
}
CScript ownerScript;
CScript heirScript;
if (m_checkNormals) {
ownerScript = CoinHelper::makeUserVout(vout.nValue, ownerPubkey).scriptPubKey;
heirScript = CoinHelper::makeUserVout(vout.nValue, heirPubkey).scriptPubKey;
@@ -552,22 +516,8 @@ public:
std::string heirName;
uint256 tokenid;
uint8_t evalCodeTokens = 0;
std::vector<uint8_t> vopretExtra;
std::vector<CPubKey> dummyVoutPubkeys;
CScript heirScript = m_fundingOpretScript;
if (typeid(Helper) == typeid(TokenHelper)) {
if (DecodeTokenOpRet(heirScript, evalCodeTokens, tokenid, dummyVoutPubkeys, vopretExtra) != 0) {
heirScript = CScript(vopretExtra);
} else {
message = std::string("invalid token opreturn format");
return false;
}
}
// get heir pubkey:
uint8_t funcId = DecodeHeirOpRet(heirScript, ownerPubkey, heirPubkey, inactivityTime, heirName, false);
uint8_t funcId = DecodeHeirEitherOpRet(m_fundingOpretScript, tokenid, ownerPubkey, heirPubkey, inactivityTime, heirName, true);
if (funcId == 0) {
message = std::string("invalid opreturn format");
return false;
@@ -620,35 +570,13 @@ public:
uint256 fundingTxidInOpret = zeroid, dummyTxid, tokenid = zeroid, initialTokenid = zeroid;
uint8_t dummyIsHeirSpendingBegan;
uint8_t evalCodeTokens = 0;
std::vector<uint8_t> vopretExtra;
std::vector<CPubKey> dummyVoutPubkeys;
CScript heirScript = vout.scriptPubKey;
if (typeid(Helper) == typeid(TokenHelper)) {
if (DecodeTokenOpRet(heirScript, evalCodeTokens, tokenid, dummyVoutPubkeys, vopretExtra) != 0) {
heirScript = CScript(vopretExtra);
} else {
message = std::string("invalid token opreturn format");
return false;
}
}
uint8_t funcId = DecodeHeirOpRet(heirScript, fundingTxidInOpret, dummyIsHeirSpendingBegan);
uint8_t funcId = DecodeHeirEitherOpRet(vout.scriptPubKey, tokenid, fundingTxidInOpret, dummyIsHeirSpendingBegan, true);
if (funcId == 0) {
message = std::string("invalid opreturn format");
return false;
}
heirScript = m_fundingOpretScript;
if (typeid(Helper) == typeid(TokenHelper)) {
if (DecodeTokenOpRet(heirScript, evalCodeTokens, initialTokenid, dummyVoutPubkeys, vopretExtra) != 0) {
heirScript = CScript(vopretExtra);
} else {
message = std::string("invalid initial token opreturn format");
return false;
}
}
uint8_t initialFuncId = DecodeHeirOpRet(heirScript, dummyTxid, dummyIsHeirSpendingBegan);
uint8_t initialFuncId = DecodeHeirEitherOpRet(m_fundingOpretScript, initialTokenid, dummyTxid, dummyIsHeirSpendingBegan, true);
if (initialFuncId == 0) {
message = std::string("invalid initial tx opreturn format");
return false;