Browse Source

allow larger PUSHDATA for CC fulfillment

pull/4/head
Scott Sadler 6 years ago
parent
commit
e625be68a9
  1. 41
      src/komodo_cc.cpp
  2. 10
      src/komodo_cc.h
  3. 38
      src/script/interpreter.cpp
  4. 3
      src/script/script.h
  5. 27
      src/test-komodo/test_cryptoconditions.cpp

41
src/komodo_cc.cpp

@ -32,6 +32,43 @@ bool IsSignedCryptoCondition(const CC *cond)
}
static unsigned char* CopyPubKey(CPubKey pkIn)
{
unsigned char* pk = (unsigned char*) malloc(33);
memcpy(pk, pkIn.begin(), 33); // TODO: compressed?
return pk;
}
CC* CCNewThreshold(int t, std::vector<CC*> v)
{
CC *cond = cc_new(CC_Threshold);
cond->threshold = t;
cond->size = v.size();
cond->subconditions = (CC**) calloc(v.size(), sizeof(CC*));
memcpy(cond->subconditions, v.data(), v.size() * sizeof(CC*));
return cond;
}
CC* CCNewSecp256k1(CPubKey k)
{
CC *cond = cc_new(CC_Secp256k1);
cond->publicKey = CopyPubKey(k);
return cond;
}
CC* CCNewEval(std::string method, std::vector<unsigned char> paramsBin)
{
CC *cond = cc_new(CC_Eval);
strcpy(cond->method, method.data());
cond->paramsBin = (unsigned char*) malloc(paramsBin.size());
memcpy(cond->paramsBin, paramsBin.data(), paramsBin.size());
cond->paramsBinLength = paramsBin.size();
return cond;
}
CScript CCPubKey(const CC *cond)
{
@ -43,8 +80,8 @@ CScript CCPubKey(const CC *cond)
CScript CCSig(const CC *cond)
{
unsigned char buf[1000];
size_t len = cc_fulfillmentBinary(cond, buf, 1000);
unsigned char buf[10000];
size_t len = cc_fulfillmentBinary(cond, buf, 10000);
auto ffill = std::vector<unsigned char>(buf, buf+len);
ffill.push_back(1); // SIGHASH_ALL
return CScript() << ffill;

10
src/komodo_cc.h

@ -1,6 +1,7 @@
#ifndef KOMODO_CC_H
#define KOMODO_CC_H
#include "pubkey.h"
#include "script/script.h"
#include "cryptoconditions/include/cryptoconditions.h"
@ -32,6 +33,15 @@ bool IsSupportedCryptoCondition(const CC *cond);
bool IsSignedCryptoCondition(const CC *cond);
/*
* Construct crypto conditions
*/
CC* CCNewPreimage(std::vector<unsigned char> preimage);
CC* CCNewEval(std::string method, std::vector<unsigned char> paramsBin);
CC* CCNewSecp256k1(CPubKey k);
CC* CCNewThreshold(int t, std::vector<CC*> v);
/*
* Turn a condition into a scriptPubKey
*/

38
src/script/interpreter.cpp

@ -1372,6 +1372,37 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con
}
/*
* Allow larger opcode in case of crypto condition scriptSig
*/
bool EvalCryptoConditionSig(
vector<vector<unsigned char> >& stack,
const CScript& scriptSig,
ScriptError* serror)
{
CScript::const_iterator pc = scriptSig.begin();
opcodetype opcode;
valtype vchPushValue;
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
if (!scriptSig.GetOp(pc, opcode, vchPushValue))
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
if (opcode == 0 || opcode > OP_PUSHDATA4)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
if (pc != scriptSig.end())
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
if (vchPushValue.size() > MAX_SCRIPT_CRYPTOCONDITION_FULFILLMENT_SIZE)
return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
stack.push_back(vchPushValue);
return true;
}
bool VerifyScript(
const CScript& scriptSig,
const CScript& scriptPubKey,
@ -1387,7 +1418,12 @@ bool VerifyScript(
}
vector<vector<unsigned char> > stack, stackCopy;
if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror))
if (IsCryptoConditionsEnabled() && scriptPubKey.IsPayToCryptoCondition()) {
if (!EvalCryptoConditionSig(stack, scriptSig, serror))
// serror is set
return false;
}
else if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror))
// serror is set
return false;
if (flags & SCRIPT_VERIFY_P2SH)

3
src/script/script.h

@ -19,6 +19,9 @@
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
// Max size of pushdata in a CC sig in bytes
static const unsigned int MAX_SCRIPT_CRYPTOCONDITION_FULFILLMENT_SIZE = 2048;
// Maximum script length in bytes
static const int MAX_SCRIPT_SIZE = 10000;

27
src/test-komodo/test_cryptoconditions.cpp

@ -199,3 +199,30 @@ TEST_F(CCTest, testCryptoConditionsDisabled)
ASSETCHAINS_CC = 0;
ASSERT_FALSE(Verify(cond));
}
TEST_F(CCTest, testLargeCondition)
{
CC *cond;
ScriptError error;
CMutableTransaction mtxTo;
auto Verify = [&] (const CC *cond) {
CAmount amount;
CTransaction txTo(mtxTo);
PrecomputedTransactionData txdata(txTo);
auto checker = ServerTransactionSignatureChecker(&txTo, 0, amount, false, txdata);
return VerifyScript(CCSig(cond), CCPubKey(cond), 0, checker, 0, &error);
};
std::vector<CC*> ccs;
for (int i=0; i<18; i++) {
ccs.push_back(CCNewSecp256k1(notaryKey.GetPubKey()));
}
cond = CCNewThreshold(16, ccs);
CCSign(mtxTo, cond);
EXPECT_EQ("(16 of 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,A5,A5)",
CCShowStructure(CCPrune(cond)));
EXPECT_EQ(1744, CCSig(cond).size());
ASSERT_TRUE(Verify(cond));
}

Loading…
Cancel
Save