]> Git Repo - VerusCoin.git/blame - src/pbaas/notarization.h
PBaaS updates
[VerusCoin.git] / src / pbaas / notarization.h
CommitLineData
b2a98c42
MT
1/********************************************************************
2 * (C) 2019 Michael Toutonghi
3 *
4 * Distributed under the MIT software license, see the accompanying
5 * file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 *
7 * This defines the public blockchains as a service (PBaaS) notarization protocol, VerusLink.
8 * VerusLink is a new distributed consensus protocol that enables multiple public blockchains
9 * to operate as a decentralized ecosystem of chains, which can interact and easily engage in cross
10 * chain transactions.
11 *
12 * In all notarization services, there is notarizing chain and a chain paying notarization rewards. They are not the same.
13 * The notarizing chain earns the right to submit notarizations onto the paying chain, which uses provable Verus chain power
14 * of each chain combined with a confirmation process to validate the correct version of one chain to another and vice versa.
15 * Generally, the paying chain will be Verus, and the notarizing chain will be the PBaaS chain started with a root of Verus
16 * notarization.
17 *
18 * On each chain, notarizations spend the output of the prior transaction that spent the notarization output, which has some spending
19 * rules that create a thread of one attempted notarization per block, each of them properly representing the current chain, whether
20 * the prior transaction represents a valid representation of the other chain or not. In order to move the notarization forward,
21 * it must also be accepted onto the paying chain, then referenced to move confirmed notarization forward again on the current chain.
22 * All notarization threads are started with a chain definition on the paying chain, or at block 1 on the PBaaS chain.
23 *
24 * Every notarization besides the chain definition is initiated on the PBaaS chain as an effort to create a notarization that is accepted
25 * and confirmed on the paying chain by first being accepted by a Verus miner before a more valuable
26 * notarization is completed and available for acceptance, then being confirmed by multiple cross notarizations.
27 *
28 * A notarization submission is earned when a block is won by staking or mining on the PBaaS chain. The miner puts a notarization
29 * of the paying chain into the block mined, spending the notarization thread. In order for the miner to have a transaction output to spend from,
30 * all PBaaS chains have a block 1 output of a small, transferable amount of Verus, which is only used as a notarization thread.
31 *
32 * After "n" blocks, currently 8, from the block won, the earned notarization may be submitted, proving the last notarization and
33 * including an MMR root that is 8 blocks after the asserted winning block, which must also be proven along with at least one staked block.
34 * Once accepted and confirmed, the notarization transaction itself may be used to spend from the pool of notarization rewards,
35 * with an output that pays 50% to the notary and 50% to the block miner/staker recipient on the paying chain.
36 *
37 * A notarizaton must be either the first in the chain or refer to a prior notarization with which it agrees. If it skips existing
38 * notarizations, referring to a prior notarization as valid, that is the same as asserting that the skipped notarizations are invalid.
39 * In that case, the notarization and 2 after it must prove one additional block since the notarization skipped.
40 *
41 * The intent is to make it extremely improbable cryptographically to achieve full confirmation of any notarization unless an alternate
42 * fork actually represents a valid chain with a majority of combined work and stake, even if more than the majority of notarizers are
43 * attempting to notarize an invalid chain.
44 *
45 * to accept an earned notarization as valid on the Verus blockchain, it must prove a transaction on the alternate chain, which is
46 * either the original chain definition transaction, which CAN and MUST be proven ONLY in block 1, or the latest notarization transaction
47 * on the alternate chain that represents an accurate MMR for the accepting chain.
48 * In addition, any accepted notarization must fullfill the following requirements:
49 * 1) Must prove either a PoS block from the alternate chain or a merge mined
50 * block that is owned by the submitter and exactly 8 blocks behind the submitted MMR, which is used for proof.
51 * 2) must prove a chain definition tx and be block 1 or contain a notarization tx, which asserts a previous, valid MMR for this
52 * chain and properly proves objects using that MMR, as well as has the proper notarization thread inputs and outputs.
53 * 3) must spend the notarization thread to the specified chainID in a fee free transaction with notarization thread input and output
54 *
55 * to agree with a previous notarization, we must:
56 * 1) agree that at the indicated block height, the MMR root is the root claimed, and is a correct representation of the best chain.
57 *
58 */
59
60#ifndef NOTARIZATION_H
61#define NOTARIZATION_H
62
63#include "pbaas/pbaas.h"
64#include "key_io.h"
65
66// This is the data for a PBaaS notarization transaction, either of a PBaaS chain into the Verus chain, or the Verus
67// chain into a PBaaS chain.
68
69// Part of a transaction with an opret that contains only the hashes and proofs, without the source
70// headers, transactions, and objects. This type of notarizatoin is mined into a block by the miner, and is created on the PBaaS
71// chain.
72class CPBaaSNotarization
73{
74public:
75 static const int FINAL_CONFIRMATIONS = 10;
76 static const int CURRENT_VERSION = PBAAS_VERSION;
77 uint32_t nVersion; // PBAAS version
78 uint160 chainID; // chain being notarized
79 CAmount rewardPerBlock; // amount to pay per reward, cannot be changed under normal circumstances
80
81 uint32_t notarizationHeight; // height of the notarization we certify
82 uint256 mmrRoot; // latest MMR root of the notarization height
83 uint256 compactPower; // compact power of the block height notarization to compare
84
85 uint256 prevNotarization; // txid of the prior notarization on this chain that we agree with, even those not accepted yet
86 int32_t prevHeight;
87 uint256 crossNotarization; // hash of last notarization transaction on the other chain, which is the first tx object in the opret input
88 int32_t crossHeight;
89
90 COpRetProof opRetProof; // hashes and types of all objects in our opret, enabling reconstruction without the opret on notarized chain
91
9f0c14b2 92 std::vector<CNodeData> nodes; // network nodes
b2a98c42
MT
93
94 CPBaaSNotarization() : nVersion(PBAAS_VERSION_INVALID) { }
95
96 CPBaaSNotarization(uint32_t version,
97 uint160 chainid,
98 CAmount rewardperblock,
99 int32_t notarizationheight,
100 uint256 MMRRoot,
101 uint256 compactpower,
102 uint256 prevnotarization,
103 int32_t prevheight,
104 uint256 crossnotarization,
105 int32_t crossheight,
106 COpRetProof orp,
9f0c14b2 107 std::vector<CNodeData> &Nodes) :
b2a98c42
MT
108 nVersion(version),
109 chainID(chainid),
110 rewardPerBlock(rewardperblock),
111
112 notarizationHeight(notarizationheight),
113 mmrRoot(MMRRoot),
114 compactPower(compactpower),
115
116 prevNotarization(prevnotarization),
117 prevHeight(prevheight),
118 crossNotarization(crossnotarization),
119 crossHeight(crossheight),
120
121 opRetProof(orp),
122
9f0c14b2 123 nodes(Nodes)
b2a98c42
MT
124 { }
125
126 CPBaaSNotarization(const std::vector<unsigned char> &asVector)
127 {
128 ::FromVector(asVector, *this);
129 }
130
131 CPBaaSNotarization(const CTransaction &tx, bool validate = false);
132
133 ADD_SERIALIZE_METHODS;
134
135 template <typename Stream, typename Operation>
136 inline void SerializationOp(Stream& s, Operation ser_action) {
137 READWRITE(VARINT(nVersion));
138 READWRITE(chainID);
139 READWRITE(rewardPerBlock);
140 READWRITE(notarizationHeight);
141 READWRITE(mmrRoot);
142 READWRITE(compactPower);
143 READWRITE(prevNotarization);
144 READWRITE(prevHeight);
145 READWRITE(crossNotarization);
146 READWRITE(crossHeight);
147 READWRITE(opRetProof);
9f0c14b2 148 READWRITE(nodes);
b2a98c42
MT
149 }
150
151 std::vector<unsigned char> AsVector()
152 {
153 return ::AsVector(*this);
154 }
155
156 bool IsValid()
157 {
158 return !mmrRoot.IsNull();
159 }
160
161 UniValue ToUniValue() const
162 {
163 UniValue obj(UniValue::VOBJ);
164 obj.push_back(Pair("version", (int64_t)nVersion));
165 obj.push_back(Pair("chainid", chainID.GetHex()));
166 obj.push_back(Pair("rewardperblock", rewardPerBlock));
167 obj.push_back(Pair("notarizationheight", (int64_t)notarizationHeight));
168 obj.push_back(Pair("mmrroot", mmrRoot.GetHex()));
169 obj.push_back(Pair("work", ((UintToArith256(compactPower) << 128) >> 128).ToString()));
170 obj.push_back(Pair("stake", (UintToArith256(compactPower) >> 128).ToString()));
171 obj.push_back(Pair("prevnotarization", prevNotarization.GetHex()));
172 obj.push_back(Pair("prevheight", prevHeight));
173 obj.push_back(Pair("crossnotarization", crossNotarization.GetHex()));
174 obj.push_back(Pair("crossheight", rewardPerBlock));
9f0c14b2
MT
175 UniValue nodesUni(UniValue::VARR);
176 for (auto node : nodes)
b2a98c42 177 {
9f0c14b2 178 nodesUni.push_back(node.ToUniValue());
b2a98c42 179 }
9f0c14b2 180 obj.push_back(Pair("nodes", nodesUni));
b2a98c42
MT
181 return obj;
182 }
183};
184
185class CNotarizationFinalization
186{
187public:
188 int32_t confirmedInput;
189
190 CNotarizationFinalization() : confirmedInput(-1) {}
191 CNotarizationFinalization(int32_t nIn) : confirmedInput(nIn) {}
192 CNotarizationFinalization(std::vector<unsigned char> vch)
193 {
194 ::FromVector(vch, *this);
195 }
196 CNotarizationFinalization(const CTransaction &tx, bool validate=false);
197
198 ADD_SERIALIZE_METHODS;
199
200 template <typename Stream, typename Operation>
201 inline void SerializationOp(Stream& s, Operation ser_action) {
202 READWRITE(confirmedInput);
203 }
204
205 bool IsValid()
206 {
207 return confirmedInput != -1;
208 }
209
210 std::vector<unsigned char> AsVector()
211 {
212 return ::AsVector(*this);
213 }
214};
215
216class CChainNotarizationData
217{
218public:
219 static const int CURRENT_VERSION = PBAAS_VERSION;
220 uint32_t version;
221 int32_t startBlock;
222 int32_t endBlock;
223
224 std::vector<std::pair<uint256, CPBaaSNotarization>> vtx;
225 int32_t lastConfirmed; // last confirmed notarization
226 std::vector<std::vector<int32_t>> forks; // chains that represent alternate branches from the last confirmed notarization
227 int32_t bestChain; // index in forks of the chain, beginning with the last confirmed notarization, that has the most power
228
229 CChainNotarizationData() : version(0), startBlock(0), endBlock(0), lastConfirmed(-1) {}
230
231 CChainNotarizationData(uint32_t ver, int32_t start, int32_t end,
232 std::vector<std::pair<uint256, CPBaaSNotarization>> txes,
233 int32_t lastConf,
234 std::vector<std::vector<int32_t>> &Forks,
235 int32_t Best) :
236 version(ver), startBlock(start), endBlock(end),
237 vtx(txes), lastConfirmed(lastConf), bestChain(Best), forks(Forks) {}
238
239 CChainNotarizationData(std::vector<unsigned char> vch)
240 {
241 ::FromVector(vch, *this);
242 }
243
244 ADD_SERIALIZE_METHODS;
245
246 template <typename Stream, typename Operation>
247 inline void SerializationOp(Stream& s, Operation ser_action) {
248 READWRITE(version);
249 READWRITE(startBlock);
250 READWRITE(endBlock);
251 READWRITE(vtx);
252 READWRITE(bestChain);
253 READWRITE(forks);
254 }
255
256 std::vector<unsigned char> AsVector()
257 {
258 return ::AsVector(*this);
259 }
260
261 bool IsValid()
262 {
263 // this needs an actual check
264 return version != 0;
265 }
266
267 bool IsConfirmed()
268 {
269 return lastConfirmed != -1;
270 }
271
272 UniValue ToUniValue() const
273 {
274 UniValue obj(UniValue::VOBJ);
275 obj.push_back(Pair("version", (int64_t)version));
276 obj.push_back(Pair("startblock", (int64_t)startBlock));
277 obj.push_back(Pair("endblock", (int64_t)endBlock));
278 UniValue notarizations(UniValue::VARR);
279 for (int64_t i = 0; i < vtx.size(); i++)
280 {
281 UniValue notarization(UniValue::VOBJ);
282 obj.push_back(Pair("index", i));
283 notarization.push_back(Pair("txid", vtx[i].first.GetHex()));
284 notarization.push_back(Pair("notarization", vtx[i].second.ToUniValue()));
285 notarizations.push_back(notarization);
286 }
287 obj.push_back(notarizations);
288 obj.push_back(Pair("lastconfirmed", (int64_t)version));
289 UniValue Forks(UniValue::VARR);
290 for (int64_t i = 0; i < forks.size(); i++)
291 {
292 UniValue Fork(UniValue::VARR);
293 for (int64_t j = 0; j < forks[i].size(); j++)
294 {
295 Fork.push_back((int64_t)forks[i][j]);
296 }
297 Forks.push_back(Pair("fork", Fork));
298 }
299 obj.push_back(Pair("forks", Forks));
300 return obj;
301 }
302};
303
2299bd95
MT
304bool CreateEarnedNotarization(CMutableTransaction &mnewTx, CTransaction &lastTx, CTransaction &crossTx, int32_t height, uint256 &prevMMR);
305
b2a98c42 306#endif
This page took 0.054754 seconds and 4 git commands to generate.