Line data Source code
1 : // Copyright (c) 2018-2021 The Dash Core developers
2 : // Copyright (c) 2021-2022 The PIVX Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "evo/providertx.h"
7 :
8 : #include "bls/key_io.h"
9 : #include "key_io.h"
10 :
11 495 : std::string ProRegPL::MakeSignString() const
12 : {
13 495 : std::ostringstream ss;
14 :
15 1485 : ss << HexStr(scriptPayout) << "|";
16 990 : ss << strprintf("%d", nOperatorReward) << "|";
17 1485 : ss << EncodeDestination(keyIDOwner) << "|";
18 1485 : ss << EncodeDestination(keyIDVoting) << "|";
19 :
20 : // ... and also the full hash of the payload as a protection against malleability and replays
21 990 : ss << ::SerializeHash(*this).ToString();
22 :
23 495 : return ss.str();
24 : }
25 :
26 480 : std::string ProRegPL::ToString() const
27 : {
28 480 : CTxDestination dest;
29 480 : std::string payee = ExtractDestination(scriptPayout, dest) ?
30 960 : EncodeDestination(dest) : "unknown";
31 480 : return strprintf("ProRegPL(nVersion=%d, collateralOutpoint=%s, addr=%s, nOperatorReward=%f, ownerAddress=%s, operatorPubKey=%s, votingAddress=%s, scriptPayout=%s)",
32 2880 : nVersion, collateralOutpoint.ToStringShort(), addr.ToString(), (double)nOperatorReward / 100, EncodeDestination(keyIDOwner), bls::EncodePublic(Params(), pubKeyOperator), EncodeDestination(keyIDVoting), payee);
33 : }
34 :
35 77 : void ProRegPL::ToJson(UniValue& obj) const
36 : {
37 77 : obj.clear();
38 77 : obj.setObject();
39 77 : obj.pushKV("version", nVersion);
40 154 : obj.pushKV("collateralHash", collateralOutpoint.hash.ToString());
41 77 : obj.pushKV("collateralIndex", (int)collateralOutpoint.n);
42 154 : obj.pushKV("service", addr.ToString());
43 231 : obj.pushKV("ownerAddress", EncodeDestination(keyIDOwner));
44 154 : obj.pushKV("operatorPubKey", bls::EncodePublic(Params(), pubKeyOperator));
45 231 : obj.pushKV("votingAddress", EncodeDestination(keyIDVoting));
46 :
47 77 : CTxDestination dest1;
48 77 : if (ExtractDestination(scriptPayout, dest1)) {
49 231 : obj.pushKV("payoutAddress", EncodeDestination(dest1));
50 : }
51 154 : CTxDestination dest2;
52 77 : if (ExtractDestination(scriptOperatorPayout, dest2)) {
53 6 : obj.pushKV("operatorPayoutAddress", EncodeDestination(dest2));
54 : }
55 77 : obj.pushKV("operatorReward", (double)nOperatorReward / 100);
56 231 : obj.pushKV("inputsHash", inputsHash.ToString());
57 77 : }
58 :
59 1493 : bool ProRegPL::IsTriviallyValid(CValidationState& state) const
60 : {
61 1493 : if (nVersion == 0 || nVersion > ProRegPL::CURRENT_VERSION) {
62 0 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-version");
63 : }
64 1493 : if (nType != 0) {
65 2 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-type");
66 : }
67 1492 : if (nMode != 0) {
68 2 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-mode");
69 : }
70 :
71 5987 : if (keyIDOwner.IsNull() || keyIDVoting.IsNull()) {
72 3 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-null");
73 : }
74 1490 : if (!pubKeyOperator.IsValid()) {
75 0 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-key-invalid");
76 : }
77 : // we may support other kinds of scripts later, but restrict it for now
78 1490 : if (!scriptPayout.IsPayToPublicKeyHash()) {
79 2 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee");
80 : }
81 1489 : if (!scriptOperatorPayout.empty() && !scriptOperatorPayout.IsPayToPublicKeyHash()) {
82 0 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-payee");
83 : }
84 :
85 2982 : CTxDestination payoutDest;
86 1489 : if (!ExtractDestination(scriptPayout, payoutDest)) {
87 : // should not happen as we checked script types before
88 0 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-dest");
89 : }
90 : // don't allow reuse of payout key for other keys (don't allow people to put the payee key onto an online server)
91 4467 : if (payoutDest == CTxDestination(keyIDOwner) ||
92 2979 : payoutDest == CTxDestination(keyIDVoting)) {
93 3 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-reuse");
94 : }
95 :
96 1488 : if (nOperatorReward > 10000) {
97 3 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-reward");
98 : }
99 : return true;
100 : }
101 :
102 33 : std::string ProUpServPL::ToString() const
103 : {
104 33 : CTxDestination dest;
105 33 : std::string payee = ExtractDestination(scriptOperatorPayout, dest) ?
106 66 : EncodeDestination(dest) : "unknown";
107 33 : return strprintf("ProUpServPL(nVersion=%d, proTxHash=%s, addr=%s, operatorPayoutAddress=%s)",
108 99 : nVersion, proTxHash.ToString(), addr.ToString(), payee);
109 : }
110 :
111 0 : void ProUpServPL::ToJson(UniValue& obj) const
112 : {
113 0 : obj.clear();
114 0 : obj.setObject();
115 0 : obj.pushKV("version", nVersion);
116 0 : obj.pushKV("proTxHash", proTxHash.ToString());
117 0 : obj.pushKV("service", addr.ToString());
118 0 : CTxDestination dest;
119 0 : if (ExtractDestination(scriptOperatorPayout, dest)) {
120 0 : obj.pushKV("operatorPayoutAddress", EncodeDestination(dest));
121 : }
122 0 : obj.pushKV("inputsHash", inputsHash.ToString());
123 0 : }
124 :
125 115 : bool ProUpServPL::IsTriviallyValid(CValidationState& state) const
126 : {
127 115 : if (nVersion == 0 || nVersion > ProUpServPL::CURRENT_VERSION) {
128 3 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-version");
129 : }
130 : return true;
131 : }
132 :
133 51 : std::string ProUpRegPL::ToString() const
134 : {
135 51 : CTxDestination dest;
136 51 : std::string payee = ExtractDestination(scriptPayout, dest) ?
137 102 : EncodeDestination(dest) : "unknown";
138 51 : return strprintf("ProUpRegPL(nVersion=%d, proTxHash=%s, operatorPubKey=%s, votingAddress=%s, payoutAddress=%s)",
139 255 : nVersion, proTxHash.ToString(), bls::EncodePublic(Params(), pubKeyOperator), EncodeDestination(keyIDVoting), payee);
140 : }
141 :
142 0 : void ProUpRegPL::ToJson(UniValue& obj) const
143 : {
144 0 : obj.clear();
145 0 : obj.setObject();
146 0 : obj.pushKV("version", nVersion);
147 0 : obj.pushKV("proTxHash", proTxHash.ToString());
148 0 : obj.pushKV("votingAddress", EncodeDestination(keyIDVoting));
149 0 : CTxDestination dest;
150 0 : if (ExtractDestination(scriptPayout, dest)) {
151 0 : obj.pushKV("payoutAddress", EncodeDestination(dest));
152 : }
153 0 : obj.pushKV("operatorPubKey", bls::EncodePublic(Params(), pubKeyOperator));
154 0 : obj.pushKV("inputsHash", inputsHash.ToString());
155 0 : }
156 :
157 159 : bool ProUpRegPL::IsTriviallyValid(CValidationState& state) const
158 : {
159 159 : if (nVersion == 0 || nVersion > ProUpRegPL::CURRENT_VERSION) {
160 0 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-version");
161 : }
162 159 : if (nMode != 0) {
163 0 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-mode");
164 : }
165 :
166 159 : if (!pubKeyOperator.IsValid()) {
167 3 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-key-invalid");
168 : }
169 317 : if (keyIDVoting.IsNull()) {
170 0 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-voting-key-null");
171 : }
172 : // !TODO: enable other scripts
173 158 : if (!scriptPayout.IsPayToPublicKeyHash()) {
174 0 : return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee");
175 : }
176 :
177 : return true;
178 : }
179 :
180 22 : std::string ProUpRevPL::ToString() const
181 : {
182 22 : return strprintf("ProUpRevPL(nVersion=%d, proTxHash=%s, nReason=%d)",
183 44 : nVersion, proTxHash.ToString(), nReason);
184 : }
185 :
186 0 : void ProUpRevPL::ToJson(UniValue& obj) const
187 : {
188 0 : obj.clear();
189 0 : obj.setObject();
190 0 : obj.pushKV("version", nVersion);
191 0 : obj.pushKV("proTxHash", proTxHash.ToString());
192 0 : obj.pushKV("reason", (int)nReason);
193 0 : obj.pushKV("inputsHash", inputsHash.ToString());
194 0 : }
195 :
196 75 : bool ProUpRevPL::IsTriviallyValid(CValidationState& state) const
197 : {
198 75 : if (nVersion == 0 || nVersion > ProUpRevPL::CURRENT_VERSION) {
199 0 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-version");
200 : }
201 :
202 : // pl.nReason < ProUpRevPL::REASON_NOT_SPECIFIED is always `false` since
203 : // pl.nReason is unsigned and ProUpRevPL::REASON_NOT_SPECIFIED == 0
204 75 : if (nReason > ProUpRevPL::REASON_LAST) {
205 3 : return state.DoS(100, false, REJECT_INVALID, "bad-protx-reason");
206 : }
207 : return true;
208 : }
209 :
210 647707 : bool GetProRegCollateral(const CTransactionRef& tx, COutPoint& outRet)
211 : {
212 647707 : if (tx == nullptr) {
213 : return false;
214 : }
215 650722 : if (!tx->IsSpecialTx() || tx->nType != CTransaction::TxType::PROREG) {
216 646980 : return false;
217 : }
218 1454 : ProRegPL pl;
219 727 : if (!GetTxPayload(*tx, pl)) {
220 : return false;
221 : }
222 11095 : outRet = pl.collateralOutpoint.hash.IsNull() ? COutPoint(tx->GetHash(), pl.collateralOutpoint.n)
223 : : pl.collateralOutpoint;
224 727 : return true;
225 : }
226 :
227 :
|