* make interface for getting tx safer in Eval
* restrict lengths in cryptoconditions to avoid ridiculous situations
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user