* make interface for getting tx safer in Eval

* restrict lengths in cryptoconditions to avoid ridiculous situations
This commit is contained in:
Scott Sadler
2018-04-06 14:35:46 -03:00
parent 56cf273faf
commit 4729632250
7 changed files with 47 additions and 35 deletions

View File

@@ -33,29 +33,27 @@ bool Eval::DisputePayout(AppVM &vm, const CC *cond, const CTransaction &disputeT
// load dispute header // load dispute header
DisputeHeader disputeHeader; DisputeHeader disputeHeader;
std::vector<unsigned char> headerData(cond->paramsBin, std::vector<unsigned char> headerData(
cond->paramsBin+cond->paramsBinLength); cond->paramsBin, cond->paramsBin+cond->paramsBinLength);
if (!CheckDeserialize(headerData, disputeHeader)) if (!CheckDeserialize(headerData, disputeHeader))
return Invalid("invalid-dispute-header"); return Invalid("invalid-dispute-header");
// ensure that enough time has passed // ensure that enough time has passed
CTransaction sessionTx; {
uint256 sessionBlockHash; CTransaction sessionTx;
CBlockIndex sessionBlock; CBlockIndex sessionBlock;
if (!GetTx(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlockHash, false)) // if unconformed its too soon
return Error("couldnt-get-parent"); if (!GetTxConfirmed(disputeTx.vin[0].prevout.hash, sessionTx, sessionBlock))
// TODO: This may not be an error, if both txs are to go into the same block... return Error("couldnt-get-parent");
// Probably change it to Invalid
if (!GetBlock(sessionBlockHash, sessionBlock))
return Error("couldnt-get-block");
if (GetCurrentHeight() < sessionBlock.nHeight + disputeHeader.waitBlocks) if (GetCurrentHeight() < sessionBlock.nHeight + disputeHeader.waitBlocks)
return Invalid("dispute-too-soon"); // Not yet return Invalid("dispute-too-soon"); // Not yet
}
// get spends // get spends
std::vector<CTransaction> spends; std::vector<CTransaction> spends;
if (!GetSpends(disputeTx.vin[0].prevout.hash, spends)) if (!GetSpendsConfirmed(disputeTx.vin[0].prevout.hash, spends))
return Error("couldnt-get-spends"); return Error("couldnt-get-spends");
// verify result from VM // verify result from VM

View File

@@ -57,19 +57,31 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
} }
bool Eval::GetSpends(uint256 hash, std::vector<CTransaction> &spends) const bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) const
{ {
// NOT IMPLEMENTED // NOT IMPLEMENTED
return false; 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); 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 unsigned int Eval::GetCurrentHeight() const
{ {
return chainActive.Height(); return chainActive.Height();
@@ -83,6 +95,7 @@ bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
blockIdx = *r->second; blockIdx = *r->second;
return true; return true;
} }
fprintf(stderr, "CC Eval Error: Can't get block from index\n");
return false; return false;
} }
@@ -109,7 +122,7 @@ bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t t
// Get notary pubkey // Get notary pubkey
CTransaction tx; CTransaction tx;
uint256 hashBlock; 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; if (tx.vout.size() < txIn.prevout.n) return false;
CScript spk = tx.vout[txIn.prevout.n].scriptPubKey; CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
if (spk.size() != 35) return false; 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 bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const
{ {
CTransaction notarisationTx; CTransaction notarisationTx;
uint256 notarisationBlock;
if (!GetTx(notaryHash, notarisationTx, notarisationBlock, true)) return false;
CBlockIndex block; 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 (!CheckNotaryInputs(notarisationTx, block.nHeight, block.nTime)) return false;
if (notarisationTx.vout.size() < 2) return false; if (notarisationTx.vout.size() < 2) return false;
if (!data.Parse(notarisationTx.vout[1].scriptPubKey)) return false; if (!data.Parse(notarisationTx.vout[1].scriptPubKey)) return false;

View File

@@ -41,9 +41,10 @@ public:
/* /*
* IO functions * 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 unsigned int GetCurrentHeight() const;
virtual bool GetSpends(uint256 hash, std::vector<CTransaction> &spends) const; virtual bool GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) const;
virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) 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 int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const;
virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const; virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const;

View File

@@ -42,14 +42,14 @@ typedef struct CC {
// public key types // public key types
struct { unsigned char *publicKey, *signature; }; struct { unsigned char *publicKey, *signature; };
// preimage // preimage
struct { unsigned char *preimage; size_t preimageLength; }; struct { unsigned char *preimage; uint16_t preimageLength; };
// threshold // threshold
struct { long threshold; int size; struct CC **subconditions; }; struct { long threshold; uint8_t size; struct CC **subconditions; };
// prefix // prefix
struct { unsigned char *prefix; size_t prefixLength; struct CC *subcondition; struct { unsigned char *prefix; uint16_t prefixLength; struct CC *subcondition;
unsigned long maxMessageLength; }; uint16_t maxMessageLength; };
// eval // eval
struct { char method[64]; unsigned char *paramsBin; size_t paramsBinLength; }; struct { char method[64]; unsigned char *paramsBin; uint16_t paramsBinLength; };
// anon // anon
struct { unsigned char fingerprint[32]; uint32_t subtypes; unsigned long cost; struct { unsigned char fingerprint[32]; uint32_t subtypes; unsigned long cost;
struct CCType *conditionType; }; struct CCType *conditionType; };
@@ -78,7 +78,7 @@ int cc_verify(const struct CC *cond, const unsigned char *msg, size_
VerifyEval verifyEval, void *evalContext); VerifyEval verifyEval, void *evalContext);
int cc_visit(CC *cond, struct CCVisitor visitor); int cc_visit(CC *cond, struct CCVisitor visitor);
int cc_signTreeEd25519(CC *cond, const unsigned char *privateKey, 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); 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_conditionBinary(const CC *cond, unsigned char *buf);
size_t cc_fulfillmentBinary(const CC *cond, unsigned char *buf, size_t bufLength); size_t cc_fulfillmentBinary(const CC *cond, unsigned char *buf, size_t bufLength);

View File

@@ -58,7 +58,7 @@ static int ed25519Sign(CC *cond, CCVisitor visitor) {
/* /*
* Sign ed25519 conditions in a tree * 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]; unsigned char pk[32], skpk[64];
ed25519_create_keypair(pk, skpk, privateKey); ed25519_create_keypair(pk, skpk, privateKey);

View File

@@ -89,7 +89,7 @@ public:
return Invalid("invalid-method"); return Invalid("invalid-method");
} }
bool GetSpends(uint256 hash, std::vector<CTransaction> &spendsOut) const bool GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spendsOut) const
{ {
auto r = spends.find(hash); auto r = spends.find(hash);
if (r != spends.end()) { if (r != spends.end()) {
@@ -99,12 +99,13 @@ public:
return false; 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); auto r = txs.find(hash);
if (r != txs.end()) { if (r != txs.end()) {
txOut = r->second; txOut = r->second;
hashBlock = hash; if (blocks.count(hash) > 0)
hashBlock = hash;
return true; return true;
} }
return false; return false;

View File

@@ -36,12 +36,13 @@ public:
return nNotaries; 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); auto r = txs.find(hash);
if (r != txs.end()) { if (r != txs.end()) {
txOut = r->second; txOut = r->second;
hashBlock = hash; if (blocks.count(hash) > 0)
hashBlock = hash;
return true; return true;
} }
return false; return false;