From: Scott Sadler Date: Fri, 6 Apr 2018 17:35:46 +0000 (-0300) Subject: * make interface for getting tx safer in Eval X-Git-Url: https://repo.jachan.dev/VerusCoin.git/commitdiff_plain/4729632250df4d9d5360de0d72494cb57f1a56f3 * make interface for getting tx safer in Eval * restrict lengths in cryptoconditions to avoid ridiculous situations --- diff --git a/src/cc/disputepayout.cpp b/src/cc/disputepayout.cpp index 9bd765c62..e36f4781d 100644 --- a/src/cc/disputepayout.cpp +++ b/src/cc/disputepayout.cpp @@ -33,29 +33,27 @@ bool Eval::DisputePayout(AppVM &vm, const CC *cond, const CTransaction &disputeT // load dispute header DisputeHeader disputeHeader; - std::vector headerData(cond->paramsBin, - cond->paramsBin+cond->paramsBinLength); + std::vector headerData( + cond->paramsBin, cond->paramsBin+cond->paramsBinLength); if (!CheckDeserialize(headerData, disputeHeader)) return Invalid("invalid-dispute-header"); // ensure that enough time has passed - CTransaction sessionTx; - uint256 sessionBlockHash; - CBlockIndex sessionBlock; - - if (!GetTx(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlockHash, false)) - return Error("couldnt-get-parent"); - // TODO: This may not be an error, if both txs are to go into the same block... - // Probably change it to Invalid - if (!GetBlock(sessionBlockHash, sessionBlock)) - return Error("couldnt-get-block"); + { + CTransaction sessionTx; + CBlockIndex sessionBlock; + + // if unconformed its too soon + if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock)) + return Error("couldnt-get-parent"); - if (GetCurrentHeight() < sessionBlock.nHeight + disputeHeader.waitBlocks) - return Invalid("dispute-too-soon"); // Not yet + if (GetCurrentHeight() < sessionBlock.nHeight + disputeHeader.waitBlocks) + return Invalid("dispute-too-soon"); // Not yet + } // get spends std::vector spends; - if (!GetSpends(disputeTx.vin[0].prevout.hash, spends)) + if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends)) return Error("couldnt-get-spends"); // verify result from VM diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index eeb84311b..503507160 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -57,19 +57,31 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) } -bool Eval::GetSpends(uint256 hash, std::vector &spends) const +bool Eval::GetSpendsConfirmed(uint256 hash, std::vector &spends) const { // NOT IMPLEMENTED return false; } -bool Eval::GetTx(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) const +bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const { + bool fAllowSlow = false; // Don't allow slow return GetTransaction(hash, txOut, hashBlock, fAllowSlow); } +bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const +{ + uint256 hashBlock; + if (!GetTxUnconfirmed(hash, txOut, hashBlock)) + return false; + if (hashBlock.IsNull() || !GetBlock(hashBlock, block)) + return false; + return true; +} + + unsigned int Eval::GetCurrentHeight() const { return chainActive.Height(); @@ -83,6 +95,7 @@ bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const blockIdx = *r->second; return true; } + fprintf(stderr, "CC Eval Error: Can't get block from index\n"); return false; } @@ -109,7 +122,7 @@ bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t t // Get notary pubkey CTransaction tx; uint256 hashBlock; - if (!GetTx(txIn.prevout.hash, tx, hashBlock, false)) return false; + if (!GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false; if (tx.vout.size() < txIn.prevout.n) return false; CScript spk = tx.vout[txIn.prevout.n].scriptPubKey; if (spk.size() != 35) return false; @@ -173,10 +186,8 @@ bool NotarisationData::Parse(const CScript scriptPK) bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const { CTransaction notarisationTx; - uint256 notarisationBlock; - if (!GetTx(notaryHash, notarisationTx, notarisationBlock, true)) return false; CBlockIndex block; - if (!GetBlock(notarisationBlock, block)) return false; + if (!GetTxConfirmed(notaryHash, notarisationTx, block)) return false; if (!CheckNotaryInputs(notarisationTx, block.nHeight, block.nTime)) return false; if (notarisationTx.vout.size() < 2) return false; if (!data.Parse(notarisationTx.vout[1].scriptPubKey)) return false; diff --git a/src/cc/eval.h b/src/cc/eval.h index 3eb4350b1..b884da5d8 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -41,9 +41,10 @@ public: /* * IO functions */ - virtual bool GetTx(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) const; + virtual bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const; + virtual bool GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const; virtual unsigned int GetCurrentHeight() const; - virtual bool GetSpends(uint256 hash, std::vector &spends) const; + virtual bool GetSpendsConfirmed(uint256 hash, std::vector &spends) const; virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const; virtual int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const; virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const; diff --git a/src/cryptoconditions/include/cryptoconditions.h b/src/cryptoconditions/include/cryptoconditions.h index a192b06c2..1c70441b3 100644 --- a/src/cryptoconditions/include/cryptoconditions.h +++ b/src/cryptoconditions/include/cryptoconditions.h @@ -42,14 +42,14 @@ typedef struct CC { // public key types struct { unsigned char *publicKey, *signature; }; // preimage - struct { unsigned char *preimage; size_t preimageLength; }; + struct { unsigned char *preimage; uint16_t preimageLength; }; // threshold - struct { long threshold; int size; struct CC **subconditions; }; + struct { long threshold; uint8_t size; struct CC **subconditions; }; // prefix - struct { unsigned char *prefix; size_t prefixLength; struct CC *subcondition; - unsigned long maxMessageLength; }; + struct { unsigned char *prefix; uint16_t prefixLength; struct CC *subcondition; + uint16_t maxMessageLength; }; // eval - struct { char method[64]; unsigned char *paramsBin; size_t paramsBinLength; }; + struct { char method[64]; unsigned char *paramsBin; uint16_t paramsBinLength; }; // anon struct { unsigned char fingerprint[32]; uint32_t subtypes; unsigned long cost; struct CCType *conditionType; }; @@ -78,7 +78,7 @@ int cc_verify(const struct CC *cond, const unsigned char *msg, size_ VerifyEval verifyEval, void *evalContext); int cc_visit(CC *cond, struct CCVisitor visitor); int cc_signTreeEd25519(CC *cond, const unsigned char *privateKey, - const unsigned char *msg, size_t msgLength); + const unsigned char *msg, uint16_t msgLength); int cc_signTreeSecp256k1Msg32(CC *cond, const unsigned char *privateKey, const unsigned char *msg32); size_t cc_conditionBinary(const CC *cond, unsigned char *buf); size_t cc_fulfillmentBinary(const CC *cond, unsigned char *buf, size_t bufLength); diff --git a/src/cryptoconditions/src/ed25519.c b/src/cryptoconditions/src/ed25519.c index 18a75fd5c..18cee0768 100644 --- a/src/cryptoconditions/src/ed25519.c +++ b/src/cryptoconditions/src/ed25519.c @@ -58,7 +58,7 @@ static int ed25519Sign(CC *cond, CCVisitor visitor) { /* * Sign ed25519 conditions in a tree */ -int cc_signTreeEd25519(CC *cond, const unsigned char *privateKey, const unsigned char *msg, size_t msgLength) { +int cc_signTreeEd25519(CC *cond, const unsigned char *privateKey, const unsigned char *msg, uint16_t msgLength) { unsigned char pk[32], skpk[64]; ed25519_create_keypair(pk, skpk, privateKey); diff --git a/src/test-komodo/test_eval_bet.cpp b/src/test-komodo/test_eval_bet.cpp index 5da437646..cff8a972c 100644 --- a/src/test-komodo/test_eval_bet.cpp +++ b/src/test-komodo/test_eval_bet.cpp @@ -89,7 +89,7 @@ public: return Invalid("invalid-method"); } - bool GetSpends(uint256 hash, std::vector &spendsOut) const + bool GetSpendsConfirmed(uint256 hash, std::vector &spendsOut) const { auto r = spends.find(hash); if (r != spends.end()) { @@ -99,12 +99,13 @@ public: return false; } - bool GetTx(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) const + bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const { auto r = txs.find(hash); if (r != txs.end()) { txOut = r->second; - hashBlock = hash; + if (blocks.count(hash) > 0) + hashBlock = hash; return true; } return false; diff --git a/src/test-komodo/test_eval_notarisation.cpp b/src/test-komodo/test_eval_notarisation.cpp index 736e28931..7fc2f1b4d 100644 --- a/src/test-komodo/test_eval_notarisation.cpp +++ b/src/test-komodo/test_eval_notarisation.cpp @@ -36,12 +36,13 @@ public: return nNotaries; } - bool GetTx(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) const + bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const { auto r = txs.find(hash); if (r != txs.end()) { txOut = r->second; - hashBlock = hash; + if (blocks.count(hash) > 0) + hashBlock = hash; return true; } return false;