1 #include <cryptoconditions.h>
2 #include <gtest/gtest.h>
8 #include "primitives/transaction.h"
9 #include "script/interpreter.h"
10 #include "script/serverchecker.h"
12 #include "testutils.h"
16 class CCTest : public ::testing::Test {
18 void CCSign(CMutableTransaction &tx, CC *cond) {
20 PrecomputedTransactionData txdata(tx);
21 uint256 sighash = SignatureHash(CCPubKey(cond), tx, 0, SIGHASH_ALL, 0, 0, &txdata);
23 int out = cc_signTreeSecp256k1Msg32(cond, notaryKey.begin(), sighash.begin());
24 tx.vin[0].scriptSig = CCSig(cond);
27 virtual void SetUp() {
34 TEST_F(CCTest, testIsPayToCryptoCondition)
36 CScript s = CScript() << VCH("a", 1);
37 ASSERT_FALSE(s.IsPayToCryptoCondition());
39 s = CScript() << VCH("a", 1) << OP_CHECKCRYPTOCONDITION;
40 ASSERT_TRUE(s.IsPayToCryptoCondition());
42 s = CScript() << OP_CHECKCRYPTOCONDITION;
43 ASSERT_FALSE(s.IsPayToCryptoCondition());
47 TEST_F(CCTest, testMayAcceptCryptoCondition)
52 CCFromJson(cond, R"!!(
53 { "type": "threshold-sha-256",
56 { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" }
59 ASSERT_TRUE(CCPubKey(cond).MayAcceptCryptoCondition());
63 CCFromJson(cond, R"!!(
64 { "type": "prefix-sha-256",
66 "maxMessageLength": 10,
68 { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" }
70 ASSERT_FALSE(CCPubKey(cond).MayAcceptCryptoCondition());
73 // has no signature nodes
74 CCFromJson(cond, R"!!(
75 { "type": "threshold-sha-256",
78 { "type": "eval-sha-256", "code": "" },
79 { "type": "eval-sha-256", "code": "" }
82 ASSERT_FALSE(CCPubKey(cond).MayAcceptCryptoCondition());
86 static bool CCVerify(const CMutableTransaction &mtxTo, const CC *cond) {
89 CTransaction txTo(mtxTo);
90 PrecomputedTransactionData txdata(txTo);
91 auto checker = ServerTransactionSignatureChecker(&txTo, 0, amount, false, txdata);
92 return VerifyScript(CCSig(cond), CCPubKey(cond), 0, checker, 0, &error);
96 TEST_F(CCTest, testVerifyCryptoCondition)
99 CMutableTransaction mtxTo;
102 cond = CCNewSecp256k1(notaryKey.GetPubKey());
103 CCFromJson(cond, R"!!({
104 "type": "secp256k1-sha-256",
105 "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47"
108 ASSERT_TRUE(CCVerify(mtxTo, cond));
111 // has signature nodes
112 CCFromJson(cond, R"!!({
113 "type": "threshold-sha-256",
116 { "type": "preimage-sha-256", "preimage": "" },
117 { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" }
122 ASSERT_TRUE(CCVerify(mtxTo, cond));
124 // no signatures; the preimage will get encoded as a fulfillment because it's cheaper
125 // and the secp256k1 node will get encoded as a condition
127 ASSERT_FALSE(CCVerify(mtxTo, cond));
129 // here the signature is set wrong
131 ASSERT_TRUE(CCVerify(mtxTo, cond));
132 memset(cond->subconditions[1]->signature, 0, 32);
133 ASSERT_FALSE(CCVerify(mtxTo, cond));
136 extern Eval* EVAL_TEST;
138 TEST_F(CCTest, testVerifyEvalCondition)
141 class EvalMock : public Eval
144 bool Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
145 { return cond->code[0] ? Valid() : Invalid(""); }
153 CMutableTransaction mtxTo;
156 cond = CCNewThreshold(2, { CCNewSecp256k1(notaryKey.GetPubKey()), CCNewEval({1}) });
158 ASSERT_TRUE(CCVerify(mtxTo, cond));
160 cond->subconditions[1]->code[0] = 0;
161 ASSERT_FALSE(CCVerify(mtxTo, cond));
165 TEST_F(CCTest, testCryptoConditionsDisabled)
169 CMutableTransaction mtxTo;
172 CCFromJson(cond, R"!!({
173 "type": "secp256k1-sha-256",
174 "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47"
177 ASSERT_TRUE(CCVerify(mtxTo, cond));
180 ASSERT_FALSE(CCVerify(mtxTo, cond));
184 TEST_F(CCTest, testLargeCondition)
188 CMutableTransaction mtxTo;
190 std::vector<CC*> ccs;
191 for (int i=0; i<18; i++) {
192 ccs.push_back(CCNewSecp256k1(notaryKey.GetPubKey()));
194 cond = CCNewThreshold(16, ccs);
196 EXPECT_EQ("(16 of 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,A5,A5)",
197 CCShowStructure(CCPrune(cond)));
198 EXPECT_EQ(1744, CCSig(cond).size());
199 ASSERT_TRUE(CCVerify(mtxTo, cond));