]>
Commit | Line | Data |
---|---|---|
e4f943d8 SS |
1 | #include "amount.h" |
2 | #include "chain.h" | |
3 | #include "chainparams.h" | |
4 | #include "checkpoints.h" | |
5 | #include "crosschain.h" | |
0df96a2f | 6 | #include "importcoin.h" |
e4f943d8 SS |
7 | #include "base58.h" |
8 | #include "consensus/validation.h" | |
9 | #include "cc/eval.h" | |
0df96a2f | 10 | #include "cc/utils.h" |
e4f943d8 SS |
11 | #include "main.h" |
12 | #include "primitives/transaction.h" | |
13 | #include "rpcserver.h" | |
14 | #include "sync.h" | |
15 | #include "util.h" | |
16 | #include "script/script.h" | |
17 | #include "script/script_error.h" | |
18 | #include "script/sign.h" | |
19 | #include "script/standard.h" | |
20 | ||
21 | #include <stdint.h> | |
e4f943d8 | 22 | #include <univalue.h> |
e4f943d8 SS |
23 | #include <regex> |
24 | ||
87d08c5a | 25 | |
e4f943d8 SS |
26 | using namespace std; |
27 | ||
28 | int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); | |
29 | int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height); | |
30 | struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); | |
31 | uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth); | |
32 | ||
33 | ||
34 | UniValue assetchainproof(const UniValue& params, bool fHelp) | |
35 | { | |
36 | uint256 hash; | |
37 | ||
38 | // parse params and get notarisation data for tx | |
39 | if ( fHelp || params.size() != 1) | |
40 | throw runtime_error("assetchainproof needs a txid"); | |
41 | ||
42 | hash = uint256S(params[0].get_str()); | |
43 | ||
44 | auto proof = GetAssetchainProof(hash); | |
45 | auto proofData = E_MARSHAL(ss << proof); | |
46 | return HexStr(proofData); | |
47 | } | |
48 | ||
49 | ||
50 | UniValue crosschainproof(const UniValue& params, bool fHelp) | |
51 | { | |
e4f943d8 SS |
52 | |
53 | } | |
54 | ||
55 | ||
e4f943d8 SS |
56 | UniValue height_MoM(const UniValue& params, bool fHelp) |
57 | { | |
58 | int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); | |
59 | if ( fHelp || params.size() != 1 ) | |
60 | throw runtime_error("height_MoM height\n"); | |
61 | LOCK(cs_main); | |
62 | height = atoi(params[0].get_str().c_str()); | |
63 | if ( height <= 0 ) | |
64 | { | |
65 | if ( chainActive.Tip() == 0 ) | |
66 | { | |
67 | ret.push_back(Pair("error",(char *)"no active chain yet")); | |
68 | return(ret); | |
69 | } | |
70 | height = chainActive.Tip()->nHeight; | |
71 | } | |
72 | //fprintf(stderr,"height_MoM height.%d\n",height); | |
73 | depth = komodo_MoM(¬arized_height,&MoM,&kmdtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&kmdstarti,&kmdendi); | |
74 | ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); | |
75 | ret.push_back(Pair("height",height)); | |
76 | ret.push_back(Pair("timestamp",(uint64_t)timestamp)); | |
77 | if ( depth > 0 ) | |
78 | { | |
79 | ret.push_back(Pair("depth",depth)); | |
80 | ret.push_back(Pair("notarized_height",notarized_height)); | |
81 | ret.push_back(Pair("MoM",MoM.GetHex())); | |
82 | ret.push_back(Pair("kmdtxid",kmdtxid.GetHex())); | |
83 | if ( ASSETCHAINS_SYMBOL[0] != 0 ) | |
84 | { | |
85 | ret.push_back(Pair("MoMoM",MoMoM.GetHex())); | |
86 | ret.push_back(Pair("MoMoMoffset",MoMoMoffset)); | |
87 | ret.push_back(Pair("MoMoMdepth",MoMoMdepth)); | |
88 | ret.push_back(Pair("kmdstarti",kmdstarti)); | |
89 | ret.push_back(Pair("kmdendi",kmdendi)); | |
90 | } | |
91 | } else ret.push_back(Pair("error",(char *)"no MoM for height")); | |
92 | ||
93 | return ret; | |
94 | } | |
95 | ||
96 | UniValue MoMoMdata(const UniValue& params, bool fHelp) | |
97 | { | |
98 | if ( fHelp || params.size() != 3 ) | |
99 | throw runtime_error("MoMoMdata symbol kmdheight ccid\n"); | |
100 | UniValue ret(UniValue::VOBJ); | |
101 | char* symbol = (char *)params[0].get_str().c_str(); | |
102 | int kmdheight = atoi(params[1].get_str().c_str()); | |
a748b1a2 | 103 | uint32_t ccid = atoi(params[2].get_str().c_str()); |
e4f943d8 SS |
104 | ret.push_back(Pair("coin",symbol)); |
105 | ret.push_back(Pair("kmdheight",kmdheight)); | |
a748b1a2 | 106 | ret.push_back(Pair("ccid", (int) ccid)); |
e4f943d8 SS |
107 | |
108 | uint256 destNotarisationTxid; | |
109 | std::vector<uint256> moms; | |
110 | uint256 MoMoM = CalculateProofRoot(symbol, ccid, kmdheight, moms, destNotarisationTxid); | |
111 | ||
112 | UniValue valMoms(UniValue::VARR); | |
113 | for (int i=0; i<moms.size(); i++) valMoms.push_back(moms[i].GetHex()); | |
114 | ret.push_back(Pair("MoMs", valMoms)); | |
115 | ret.push_back(Pair("notarization_hash", destNotarisationTxid.GetHex())); | |
116 | ret.push_back(Pair("MoMoM", MoMoM.GetHex())); | |
91d92922 | 117 | auto vmomomdata = E_MARSHAL(ss << MoMoM; ss << ((uint32_t)0)); |
e4f943d8 SS |
118 | ret.push_back(Pair("data", HexStr(vmomomdata))); |
119 | return ret; | |
120 | } | |
121 | ||
122 | ||
123 | UniValue calc_MoM(const UniValue& params, bool fHelp) | |
124 | { | |
125 | int32_t height,MoMdepth; uint256 MoM; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); | |
126 | if ( fHelp || params.size() != 2 ) | |
127 | throw runtime_error("calc_MoM height MoMdepth\n"); | |
128 | LOCK(cs_main); | |
129 | height = atoi(params[0].get_str().c_str()); | |
130 | MoMdepth = atoi(params[1].get_str().c_str()); | |
131 | if ( height <= 0 || MoMdepth <= 0 || MoMdepth >= height ) | |
132 | throw runtime_error("calc_MoM illegal height or MoMdepth\n"); | |
133 | //fprintf(stderr,"height_MoM height.%d\n",height); | |
134 | MoM = komodo_calcMoM(height,MoMdepth); | |
135 | ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); | |
136 | ret.push_back(Pair("height",height)); | |
137 | ret.push_back(Pair("MoMdepth",MoMdepth)); | |
138 | ret.push_back(Pair("MoM",MoM.GetHex())); | |
139 | return ret; | |
140 | } | |
0df96a2f SS |
141 | |
142 | ||
143 | UniValue migrate_converttoexport(const UniValue& params, bool fHelp) | |
144 | { | |
145 | if (fHelp || params.size() != 3) | |
146 | throw runtime_error( | |
c7bcf05d | 147 | "migrate_converttoexport rawTx dest_symbol export_amount\n" |
0df96a2f SS |
148 | "\nConvert a raw transaction to a cross-chain export.\n" |
149 | "If neccesary, the transaction should be funded using fundrawtransaction.\n" | |
150 | "Finally, the transaction should be signed using signrawtransaction\n" | |
0b485d3c SS |
151 | "The finished export transaction, plus the payouts, should be passed to " |
152 | "the \"migrate_createimporttransaction\" method on a KMD node to get the corresponding " | |
0df96a2f SS |
153 | "import transaction.\n" |
154 | ); | |
155 | ||
156 | if (ASSETCHAINS_CC < 2) | |
157 | throw runtime_error("-ac_cc < 2"); | |
158 | ||
159 | if (ASSETCHAINS_SYMBOL[0] == 0) | |
160 | throw runtime_error("Must be called on assetchain"); | |
161 | ||
162 | vector<uint8_t> txData(ParseHexV(params[0], "argument 1")); | |
163 | CMutableTransaction tx; | |
164 | if (!E_UNMARSHAL(txData, ss >> tx)) | |
165 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | |
166 | ||
167 | string targetSymbol = params[1].get_str(); | |
168 | if (targetSymbol.size() == 0 || targetSymbol.size() > 32) | |
169 | throw runtime_error("targetSymbol length must be >0 and <=32"); | |
170 | ||
c7bcf05d SS |
171 | CAmount burnAmount = AmountFromValue(params[2]); |
172 | if (burnAmount <= 0) | |
173 | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for export"); | |
0df96a2f | 174 | { |
c7bcf05d SS |
175 | CAmount needed = 0; |
176 | for (int i=0; i<tx.vout.size(); i++) needed += tx.vout[i].nValue; | |
0df96a2f | 177 | if (burnAmount < needed) |
c7bcf05d | 178 | throw runtime_error("export_amount too small"); |
0df96a2f SS |
179 | } |
180 | ||
181 | CTxOut burnOut = MakeBurnOutput(burnAmount, ASSETCHAINS_CC, targetSymbol, tx.vout); | |
182 | UniValue ret(UniValue::VOBJ); | |
0b485d3c | 183 | ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout)))); |
0df96a2f SS |
184 | tx.vout.clear(); |
185 | tx.vout.push_back(burnOut); | |
186 | ret.push_back(Pair("exportTx", HexStr(E_MARSHAL(ss << tx)))); | |
187 | return ret; | |
188 | } | |
189 | ||
190 | ||
191 | /* | |
192 | * The process to migrate funds | |
193 | * | |
194 | * Create a transaction on assetchain: | |
195 | * | |
196 | * generaterawtransaction | |
197 | * migrate_converttoexport | |
198 | * fundrawtransaction | |
199 | * signrawtransaction | |
200 | * | |
201 | * migrate_createimportransaction | |
202 | * migrate_completeimporttransaction | |
203 | */ | |
204 | ||
205 | UniValue migrate_createimporttransaction(const UniValue& params, bool fHelp) | |
206 | { | |
207 | if (fHelp || params.size() != 2) | |
0b485d3c SS |
208 | throw runtime_error("migrate_createimporttransaction burnTx payouts\n\n" |
209 | "Create an importTx given a burnTx and the corresponding payouts, hex encoded"); | |
0df96a2f SS |
210 | |
211 | if (ASSETCHAINS_CC < 2) | |
212 | throw runtime_error("-ac_cc < 2"); | |
213 | ||
214 | if (ASSETCHAINS_SYMBOL[0] == 0) | |
215 | throw runtime_error("Must be called on assetchain"); | |
216 | ||
217 | vector<uint8_t> txData(ParseHexV(params[0], "argument 1")); | |
218 | ||
219 | CTransaction burnTx; | |
220 | if (!E_UNMARSHAL(txData, ss >> burnTx)) | |
221 | throw runtime_error("Couldn't parse burnTx"); | |
222 | ||
223 | ||
224 | vector<CTxOut> payouts; | |
c7bcf05d | 225 | if (!E_UNMARSHAL(ParseHexV(params[1], "argument 2"), ss >> payouts)) |
0df96a2f SS |
226 | throw runtime_error("Couldn't parse payouts"); |
227 | ||
228 | uint256 txid = burnTx.GetHash(); | |
229 | TxProof proof = GetAssetchainProof(burnTx.GetHash()); | |
230 | ||
231 | CTransaction importTx = MakeImportCoinTransaction(proof, burnTx, payouts); | |
232 | return HexStr(E_MARSHAL(ss << importTx)); | |
233 | } | |
234 | ||
235 | ||
236 | UniValue migrate_completeimporttransaction(const UniValue& params, bool fHelp) | |
237 | { | |
238 | if (fHelp || params.size() != 1) | |
0b485d3c SS |
239 | throw runtime_error("migrate_completeimporttransaction importTx\n\n" |
240 | "Takes a cross chain import tx with proof generated on assetchain " | |
241 | "and extends proof to target chain proof root"); | |
0df96a2f SS |
242 | |
243 | if (ASSETCHAINS_SYMBOL[0] != 0) | |
244 | throw runtime_error("Must be called on KMD"); | |
245 | ||
246 | CTransaction importTx; | |
0b485d3c | 247 | if (!E_UNMARSHAL(ParseHexV(params[0], "argument 1"), ss >> importTx)) |
0df96a2f SS |
248 | throw runtime_error("Couldn't parse importTx"); |
249 | ||
0b485d3c | 250 | CompleteImportTransaction(importTx); |
0df96a2f SS |
251 | |
252 | return HexStr(E_MARSHAL(ss << importTx)); | |
253 | } |