]> Git Repo - VerusCoin.git/commitdiff
Properly vaidate stakeguard in new CC version
authormiketout <[email protected]>
Tue, 7 Apr 2020 22:02:44 +0000 (15:02 -0700)
committermiketout <[email protected]>
Tue, 7 Apr 2020 22:02:44 +0000 (15:02 -0700)
src/cc/CCinclude.h
src/cc/CCutils.cpp
src/cc/StakeGuard.cpp
src/script/interpreter.cpp

index 7b237bef5a248bf9a3ba1690647877825d208143..ae13eb4297434cfd5153033ee57d23fbad6dc045 100644 (file)
@@ -143,6 +143,7 @@ CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2);
 CC *MakeCCcondMofN(uint8_t evalcode, const std::vector<CTxDestination> &dests, int M);
 CC *MakeCCcondMofN(uint8_t evalcode, const std::vector<CC*> &conditions, int M);
 CC *GetCryptoCondition(CScript const& scriptSig);
+std::vector<unsigned char> GetFulfillmentVector(CScript const& scriptSig);
 void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
 void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
 bool IsCCInput(CScript const& scriptSig);
index d30decb9841b8100fe3020c3ee8480a7d6825e07..ec5ddf59089903462800092f98376859a8d9f69b 100644 (file)
@@ -105,6 +105,16 @@ CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2)
     return(vout);
 }
 
+std::vector<unsigned char> GetFulfillmentVector(CScript const& scriptSig)
+{
+    auto pc = scriptSig.begin();
+    opcodetype opcode;
+    std::vector<unsigned char> ffbin;
+    if (scriptSig.GetOp(pc, opcode, ffbin))
+        return ffbin;
+    return std::vector<unsigned char>();
+}
+
 CC* GetCryptoCondition(CScript const& scriptSig)
 {
     auto pc = scriptSig.begin();
index 69592be0118497ab7be28e8efb75a563e35166ee..82b8f79704d3c6fd98dbf4eb177a3bfaa46819e8 100644 (file)
@@ -264,8 +264,8 @@ bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxO
 }
 
 // validates if a stake transaction is both valid and cheating, defined by:
-// the same exact utxo source, a target block height of later than that of this tx that is also targeting a fork
-// of the chain. we know the transaction is a coinbase
+// the same exact utxo source, a target block height of later than that of the provided coinbase tx that is also targeting a fork
+// of the chain. the source transaction must be a coinbase
 bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating)
 {
     // an invalid or non-matching stake transaction cannot cheat
@@ -439,63 +439,86 @@ bool StakeGuardValidate(struct CCcontract_info *cp, Eval* eval, const CTransacti
 
     CC *cc = GetCryptoCondition(tx.vin[nIn].scriptSig);
 
-    if (cc)
+    // tx is the spending tx, the cc transaction comes back in txOut
+    bool validCCParams = GetCCParams(eval, tx, nIn, txOut, preConditions, params);
+    COptCCParams ccp;
+    if (preConditions.size() > 0)
+    {
+        ccp = COptCCParams(preConditions[0]);
+    }
+
+    if (validCCParams && ccp.IsValid() && ((cc && ccp.version < COptCCParams::VERSION_V3) || (!cc && ccp.version >= COptCCParams::VERSION_V3)))
     {
-        COptCCParams ccp;
         signedByFirstKey = false;
         validCheat = false;
 
-        // tx is the spending tx, the cc transaction comes back in txOut
-        if (GetCCParams(eval, tx, nIn, txOut, preConditions, params))
+        if (ccp.m == 1 && ccp.n == 2 && ccp.vKeys.size() == 2)
         {
-            if (preConditions.size() > 0)
-            {
-                ccp = COptCCParams(preConditions[0]);
-            }
+            std::vector<uint32_t> vc = {0, 0};
+            std::vector<CPubKey> keys;
 
-            if (ccp.IsValid() && ccp.m == 1 && ccp.n == 2 && ccp.vKeys.size() == 2)
+            for (auto pk : ccp.vKeys)
             {
-                std::vector<uint32_t> vc = {0, 0};
-
-                std::vector<CPubKey> keys;
-                for (auto pk : ccp.vKeys)
+                uint160 keyID = GetDestinationID(pk);
+                std::vector<unsigned char> vkch = GetDestinationBytes(pk);
+                if (vkch.size() == 33)
                 {
-                    uint160 keyID = GetDestinationID(pk);
-                    std::vector<unsigned char> vkch = GetDestinationBytes(pk);
-                    if (vkch.size() == 33)
-                    {
-                        keys.push_back(CPubKey(vkch));
-                    }
+                    keys.push_back(CPubKey(vkch));
                 }
+            }
 
-                if (keys.size() == 2)
+            if (keys.size() == 2)
+            {
+                if (cc && ccp.version < COptCCParams::VERSION_V3)
                 {
                     ccFulfillmentCheck fc = {keys, vc};
-
                     signedByFirstKey = (IsCCFulfilled(cc, &fc) != 0);
-
-                    if ((!signedByFirstKey && ccp.evalCode == EVAL_STAKEGUARD && ccp.vKeys.size() == 2 && ccp.version == COptCCParams::VERSION_V1) &&
-                        params.size() == 2 && params[0].size() > 0 && params[0][0] == OPRETTYPE_STAKECHEAT)
+                }
+                else if (ccp.version >= COptCCParams::VERSION_V3)
+                {
+                    CSmartTransactionSignatures smartSigs;
+                    if (!cc)
                     {
-                        CDataStream s = CDataStream(std::vector<unsigned char>(params[1].begin(), params[1].end()), SER_DISK, PROTOCOL_VERSION);
-                        bool checkOK = false;
-                        CTransaction cheatTx;
-                        try
+                        std::vector<unsigned char> ffVec = GetFulfillmentVector(tx.vin[nIn].scriptSig);
+                        smartSigs = CSmartTransactionSignatures(std::vector<unsigned char>(ffVec.begin(), ffVec.end()));
+                        uint160 checkHash = GetDestinationID(keys[0]);
+                        for (auto &keySig : smartSigs.signatures)
                         {
-                            cheatTx.Unserialize(s);
-                            checkOK = true;
-                        }
-                        catch (...)
-                        {
-                        }
-                        if (checkOK && !ValidateMatchingStake(txOut, tx.vin[0].prevout.n, cheatTx, validCheat))
-                        {
-                            validCheat = false;
+                            CPubKey thisKey;
+                            thisKey.Set(keySig.second.pubKeyData.begin(), keySig.second.pubKeyData.end());
+                            if (thisKey.GetID() == checkHash)
+                            {
+                                signedByFirstKey = true;
+                                break;
+                            }
                         }
                     }
                 }
+
+                if ((!signedByFirstKey && ccp.evalCode == EVAL_STAKEGUARD && ccp.vKeys.size() == 2 && ccp.version == COptCCParams::VERSION_V1) &&
+                    params.size() == 2 && params[0].size() > 0 && params[0][0] == OPRETTYPE_STAKECHEAT)
+                {
+                    CDataStream s = CDataStream(std::vector<unsigned char>(params[1].begin(), params[1].end()), SER_DISK, PROTOCOL_VERSION);
+                    bool checkOK = false;
+                    CTransaction cheatTx;
+                    try
+                    {
+                        cheatTx.Unserialize(s);
+                        checkOK = true;
+                    }
+                    catch (...)
+                    {
+                    }
+                    if (checkOK && !ValidateMatchingStake(txOut, tx.vin[0].prevout.n, cheatTx, validCheat))
+                    {
+                        validCheat = false;
+                    }
+                }
             }
         }
+    }
+    if (cc)
+    {
         cc_free(cc);
     }
     if (!(signedByFirstKey || validCheat))
index 25f12cab9d1e785193e09ac1bf47528f34b71d18..3bb7c8075368d4d472d01d48435ab44949469609 100644 (file)
@@ -5,21 +5,15 @@
 
 #include <cryptoconditions.h>
 
-#include "interpreter.h"
 #include "standard.h"
 
 #include "consensus/upgrades.h"
 #include "primitives/transaction.h"
+#include "pbaas/pbaas.h"
 #include "cc/eval.h"
 #include "crypto/ripemd160.h"
 #include "crypto/sha1.h"
 #include "crypto/sha256.h"
-#include "pubkey.h"
-#include "script/script.h"
-#include "uint256.h"
-#include "pbaas/pbaas.h"
-#include "pbaas/identity.h"
-
 
 using namespace std;
 
@@ -1878,7 +1872,6 @@ bool EvalCryptoConditionSig(
     return true;
 }
 
-
 bool VerifyScript(
     const CScript& scriptSig,
     const CScript& scriptPubKey,
@@ -1894,7 +1887,16 @@ bool VerifyScript(
     }
 
     vector<vector<unsigned char> > stack, stackCopy;
-    if (IsCryptoConditionsEnabled() && scriptPubKey.IsPayToCryptoCondition()) {
+    COptCCParams p;
+    if (IsCryptoConditionsEnabled() && scriptPubKey.IsPayToCryptoCondition(p)) {
+
+        //UniValue r;
+        //printf("eval code: %d, keys:\n", p.evalCode);
+        //for (auto &key : p.vKeys)
+        //{
+        //    printf("%s\n", EncodeDestination(key).c_str());
+        //}
+
         if (!EvalCryptoConditionSig(stack, scriptSig, serror))
             // serror is set
             return false;
This page took 0.059027 seconds and 4 git commands to generate.