]>
Commit | Line | Data |
---|---|---|
4c121ffd SS |
1 | #include <cryptoconditions.h> |
2 | #include <gtest/gtest.h> | |
3 | ||
4 | #include "base58.h" | |
5 | #include "key.h" | |
8a8e10f0 | 6 | #include "script/cc.h" |
39c9911e | 7 | #include "cc/eval.h" |
4c121ffd SS |
8 | #include "primitives/transaction.h" |
9 | #include "script/interpreter.h" | |
10 | #include "script/serverchecker.h" | |
11 | ||
561f3e18 | 12 | #include "testutils.h" |
4c121ffd | 13 | |
4c121ffd | 14 | |
4c121ffd SS |
15 | |
16 | class CCTest : public ::testing::Test { | |
561f3e18 SS |
17 | public: |
18 | void CCSign(CMutableTransaction &tx, CC *cond) { | |
19 | tx.vin.resize(1); | |
20 | PrecomputedTransactionData txdata(tx); | |
21 | uint256 sighash = SignatureHash(CCPubKey(cond), tx, 0, SIGHASH_ALL, 0, 0, &txdata); | |
22 | ||
23 | int out = cc_signTreeSecp256k1Msg32(cond, notaryKey.begin(), sighash.begin()); | |
24 | tx.vin[0].scriptSig = CCSig(cond); | |
25 | } | |
4c121ffd | 26 | protected: |
561f3e18 SS |
27 | virtual void SetUp() { |
28 | // enable CC | |
29 | ASSETCHAINS_CC = 1; | |
4c121ffd | 30 | } |
4c121ffd SS |
31 | }; |
32 | ||
33 | ||
34 | TEST_F(CCTest, testIsPayToCryptoCondition) | |
35 | { | |
36 | CScript s = CScript() << VCH("a", 1); | |
37 | ASSERT_FALSE(s.IsPayToCryptoCondition()); | |
38 | ||
39 | s = CScript() << VCH("a", 1) << OP_CHECKCRYPTOCONDITION; | |
40 | ASSERT_TRUE(s.IsPayToCryptoCondition()); | |
41 | ||
42 | s = CScript() << OP_CHECKCRYPTOCONDITION; | |
43 | ASSERT_FALSE(s.IsPayToCryptoCondition()); | |
44 | } | |
45 | ||
46 | ||
47 | TEST_F(CCTest, testMayAcceptCryptoCondition) | |
48 | { | |
49 | CC *cond; | |
50 | ||
51 | // ok | |
52 | CCFromJson(cond, R"!!( | |
53 | { "type": "threshold-sha-256", | |
54 | "threshold": 2, | |
55 | "subfulfillments": [ | |
e36af93b | 56 | { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" } |
4c121ffd SS |
57 | ] |
58 | })!!"); | |
59 | ASSERT_TRUE(CCPubKey(cond).MayAcceptCryptoCondition()); | |
60 | ||
61 | ||
62 | // prefix not allowed | |
63 | CCFromJson(cond, R"!!( | |
64 | { "type": "prefix-sha-256", | |
65 | "prefix": "abc", | |
66 | "maxMessageLength": 10, | |
67 | "subfulfillment": | |
e36af93b | 68 | { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" } |
4c121ffd SS |
69 | })!!"); |
70 | ASSERT_FALSE(CCPubKey(cond).MayAcceptCryptoCondition()); | |
71 | ||
72 | ||
73 | // has no signature nodes | |
74 | CCFromJson(cond, R"!!( | |
75 | { "type": "threshold-sha-256", | |
76 | "threshold": 1, | |
77 | "subfulfillments": [ | |
39c9911e SS |
78 | { "type": "eval-sha-256", "code": "" }, |
79 | { "type": "eval-sha-256", "code": "" } | |
4c121ffd SS |
80 | ] |
81 | })!!"); | |
82 | ASSERT_FALSE(CCPubKey(cond).MayAcceptCryptoCondition()); | |
83 | } | |
84 | ||
85 | ||
8a8e10f0 SS |
86 | static bool CCVerify(const CMutableTransaction &mtxTo, const CC *cond) { |
87 | CAmount amount; | |
88 | ScriptError error; | |
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); | |
93 | }; | |
94 | ||
95 | ||
4c121ffd SS |
96 | TEST_F(CCTest, testVerifyCryptoCondition) |
97 | { | |
98 | CC *cond; | |
4c121ffd SS |
99 | CMutableTransaction mtxTo; |
100 | ||
4c121ffd | 101 | // ok |
e36af93b | 102 | cond = CCNewSecp256k1(notaryKey.GetPubKey()); |
4c121ffd SS |
103 | CCFromJson(cond, R"!!({ |
104 | "type": "secp256k1-sha-256", | |
e36af93b | 105 | "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" |
4c121ffd SS |
106 | })!!"); |
107 | CCSign(mtxTo, cond); | |
8a8e10f0 | 108 | ASSERT_TRUE(CCVerify(mtxTo, cond)); |
4c121ffd SS |
109 | |
110 | ||
111 | // has signature nodes | |
112 | CCFromJson(cond, R"!!({ | |
113 | "type": "threshold-sha-256", | |
114 | "threshold": 1, | |
115 | "subfulfillments": [ | |
116 | { "type": "preimage-sha-256", "preimage": "" }, | |
e36af93b | 117 | { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" } |
4c121ffd SS |
118 | ] |
119 | })!!"); | |
120 | cond->threshold = 2; | |
121 | CCSign(mtxTo, cond); | |
8a8e10f0 | 122 | ASSERT_TRUE(CCVerify(mtxTo, cond)); |
4c121ffd SS |
123 | |
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 | |
126 | cond->threshold = 1; | |
8a8e10f0 | 127 | ASSERT_FALSE(CCVerify(mtxTo, cond)); |
4c121ffd SS |
128 | |
129 | // here the signature is set wrong | |
130 | cond->threshold = 2; | |
8a8e10f0 | 131 | ASSERT_TRUE(CCVerify(mtxTo, cond)); |
4c121ffd | 132 | memset(cond->subconditions[1]->signature, 0, 32); |
8a8e10f0 | 133 | ASSERT_FALSE(CCVerify(mtxTo, cond)); |
4c121ffd SS |
134 | } |
135 | ||
39c9911e | 136 | extern Eval* EVAL_TEST; |
4c121ffd SS |
137 | |
138 | TEST_F(CCTest, testVerifyEvalCondition) | |
139 | { | |
39c9911e SS |
140 | |
141 | class EvalMock : public Eval | |
142 | { | |
143 | public: | |
144 | bool Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) | |
145 | { return cond->code[0] ? Valid() : Invalid(""); } | |
146 | }; | |
147 | ||
148 | EvalMock eval; | |
149 | EVAL_TEST = &eval; | |
150 | ||
151 | ||
4c121ffd | 152 | CC *cond; |
4c121ffd SS |
153 | CMutableTransaction mtxTo; |
154 | ||
4c121ffd | 155 | // ok |
39c9911e SS |
156 | cond = CCNewThreshold(2, { CCNewSecp256k1(notaryKey.GetPubKey()), CCNewEval({1}) }); |
157 | CCSign(mtxTo, cond); | |
8a8e10f0 | 158 | ASSERT_TRUE(CCVerify(mtxTo, cond)); |
4c121ffd | 159 | |
39c9911e | 160 | cond->subconditions[1]->code[0] = 0; |
8a8e10f0 | 161 | ASSERT_FALSE(CCVerify(mtxTo, cond)); |
4c121ffd SS |
162 | } |
163 | ||
164 | ||
165 | TEST_F(CCTest, testCryptoConditionsDisabled) | |
166 | { | |
167 | CC *cond; | |
168 | ScriptError error; | |
169 | CMutableTransaction mtxTo; | |
170 | ||
4c121ffd SS |
171 | // ok |
172 | CCFromJson(cond, R"!!({ | |
173 | "type": "secp256k1-sha-256", | |
e36af93b | 174 | "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" |
4c121ffd SS |
175 | })!!"); |
176 | CCSign(mtxTo, cond); | |
8a8e10f0 | 177 | ASSERT_TRUE(CCVerify(mtxTo, cond)); |
4c121ffd SS |
178 | |
179 | ASSETCHAINS_CC = 0; | |
8a8e10f0 | 180 | ASSERT_FALSE(CCVerify(mtxTo, cond)); |
4c121ffd | 181 | } |
e625be68 SS |
182 | |
183 | ||
184 | TEST_F(CCTest, testLargeCondition) | |
185 | { | |
186 | CC *cond; | |
187 | ScriptError error; | |
188 | CMutableTransaction mtxTo; | |
189 | ||
e625be68 SS |
190 | std::vector<CC*> ccs; |
191 | for (int i=0; i<18; i++) { | |
192 | ccs.push_back(CCNewSecp256k1(notaryKey.GetPubKey())); | |
193 | } | |
194 | cond = CCNewThreshold(16, ccs); | |
195 | CCSign(mtxTo, cond); | |
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()); | |
8a8e10f0 | 199 | ASSERT_TRUE(CCVerify(mtxTo, cond)); |
e625be68 | 200 | } |