44
55#include < primitives/pak.h>
66#include < pubkey.h>
7+ #include < dynafed.h>
78
89// ELEMENTS
910
@@ -33,73 +34,9 @@ class CSecp256k1Init {
3334static CSecp256k1Init instance_of_csecp256k1;
3435}
3536
36- CScript CPAKList::Magic ()
37- {
38- CScript scriptPubKey;
39- scriptPubKey.resize (6 );
40- scriptPubKey[0 ] = OP_RETURN;
41- scriptPubKey[1 ] = 0x04 ;
42- scriptPubKey[2 ] = 0xab ;
43- scriptPubKey[3 ] = 0x22 ;
44- scriptPubKey[4 ] = 0xaa ;
45- scriptPubKey[5 ] = 0xee ;
46- return scriptPubKey;
47- }
48-
49- std::vector<CScript> CPAKList::GenerateCoinbasePAKCommitments () const
50- {
51- std::vector<CScript> commitments;
52- CScript scriptPubKey = CPAKList::Magic ();
53-
54- for (unsigned int i = 0 ; i < m_offline_keys.size (); i++) {
55- CScript scriptCommitment (scriptPubKey);
56- unsigned char pubkey[33 ];
57- size_t outputlen = 33 ;
58- secp256k1_ec_pubkey_serialize (secp256k1_ctx_pak, pubkey, &outputlen, &m_offline_keys[i], SECP256K1_EC_COMPRESSED);
59- assert (outputlen == 33 );
60- scriptCommitment << std::vector<unsigned char >(pubkey, pubkey+outputlen);
61- secp256k1_ec_pubkey_serialize (secp256k1_ctx_pak, pubkey, &outputlen, &m_online_keys[i], SECP256K1_EC_COMPRESSED);
62- assert (outputlen == 33 );
63- scriptCommitment << std::vector<unsigned char >(pubkey, pubkey+outputlen);
64- commitments.push_back (scriptCommitment);
65- }
66-
67- return commitments;
68- }
69-
70- std::vector<CScript> CPAKList::GenerateCoinbasePAKReject () const
71- {
72- CScript scriptPubKey = CPAKList::Magic ();
73-
74- std::vector<unsigned char > reject;
75- reject.push_back (' R' );
76- reject.push_back (' E' );
77- reject.push_back (' J' );
78- reject.push_back (' E' );
79- reject.push_back (' C' );
80- reject.push_back (' T' );
81-
82- scriptPubKey << reject;
83-
84- std::vector<CScript> commitment;
85- commitment.push_back (scriptPubKey);
86- return commitment;
87- }
88-
89- void CPAKList::CreateCommitments (std::vector<CScript> &commitments) const
90- {
91- if (reject) {
92- commitments = GenerateCoinbasePAKReject ();
93- } else {
94- commitments = GenerateCoinbasePAKCommitments ();
95- }
96- }
97-
9837bool CPAKList::operator ==(const CPAKList &other) const
9938{
100- if (this ->reject != other.reject ) {
101- return false ;
102- } else if (this ->m_offline_keys .size () != other.m_offline_keys .size ()) {
39+ if (this ->m_offline_keys .size () != other.m_offline_keys .size ()) {
10340 return false ;
10441 } else {
10542 for (unsigned int i = 0 ; i < this ->m_offline_keys .size (); i++) {
@@ -112,7 +49,7 @@ bool CPAKList::operator==(const CPAKList &other) const
11249 return true ;
11350}
11451
115- bool CPAKList::FromBytes (CPAKList &paklist, std::vector<std::vector<unsigned char > >& offline_keys_bytes, std::vector<std::vector<unsigned char > >& online_keys_bytes, bool is_reject )
52+ bool CPAKList::FromBytes (CPAKList &paklist, const std::vector<std::vector<unsigned char > >& offline_keys_bytes, const std::vector<std::vector<unsigned char > >& online_keys_bytes)
11653{
11754 if (offline_keys_bytes.size () != online_keys_bytes.size ()
11855 || offline_keys_bytes.size () > SECP256K1_WHITELIST_MAX_N_KEYS) {
@@ -134,11 +71,11 @@ bool CPAKList::FromBytes(CPAKList &paklist, std::vector<std::vector<unsigned cha
13471 online_keys.push_back (pubkey2);
13572 }
13673
137- paklist = CPAKList (offline_keys, online_keys, is_reject );
74+ paklist = CPAKList (offline_keys, online_keys);
13875 return true ;
13976}
14077
141- void CPAKList::ToBytes (std::vector<std::vector<unsigned char > >& offline_keys, std::vector<std::vector<unsigned char > >& online_keys, bool &is_reject ) const
78+ void CPAKList::ToBytes (std::vector<std::vector<unsigned char > >& offline_keys, std::vector<std::vector<unsigned char > >& online_keys) const
14279{
14380 offline_keys.resize (0 );
14481 online_keys.resize (0 );
@@ -151,7 +88,6 @@ void CPAKList::ToBytes(std::vector<std::vector<unsigned char> >& offline_keys, s
15188 secp256k1_ec_pubkey_serialize (secp256k1_ctx_pak, pubkey, &outputlen, &m_online_keys[i], SECP256K1_EC_COMPRESSED);
15289 online_keys.push_back (std::vector<unsigned char >(pubkey, pubkey+outputlen));
15390 }
154- is_reject = reject;
15591}
15692
15793// Proof follows the OP_RETURN <genesis_block_hash> <destination_scriptpubkey>
@@ -243,3 +179,55 @@ bool ScriptHasValidPAKProof(const CScript& script, const uint256& genesis_hash)
243179
244180 return true ;
245181}
182+
183+ CPAKList CreatePAKListFromExtensionSpace (const std::vector<std::vector<unsigned char >>& extension_space)
184+ {
185+ std::vector<std::vector<unsigned char >> offline_keys;
186+ std::vector<std::vector<unsigned char >> online_keys;
187+ for (const auto & entry : extension_space) {
188+ // As soon as we find something that is possibly not 2 serialized pubkeys
189+ // we stop looking. CPAKList::FromBytes does pubkey validation itself.
190+ if (entry.size () != 66 ) {
191+ break ;
192+ }
193+ offline_keys.emplace_back (entry.begin (), entry.begin ()+33 );
194+ online_keys.emplace_back (entry.begin ()+33 , entry.end ());
195+ // Allow additional data, just ignore
196+ if (offline_keys.size () == SECP256K1_WHITELIST_MAX_N_KEYS) {
197+ break ;
198+ }
199+ }
200+ CPAKList paklist;
201+ if (!CPAKList::FromBytes (paklist, offline_keys, online_keys)) {
202+ return CPAKList ();
203+ }
204+ return paklist;
205+ }
206+
207+ CPAKList GetActivePAKList (const CBlockIndex* pblockindex, const Consensus::Params& params)
208+ {
209+ assert (pblockindex);
210+
211+ return CreatePAKListFromExtensionSpace (ComputeNextBlockFullCurrentParameters (pblockindex, params).m_extension_space );
212+ }
213+
214+ bool IsPAKValidOutput (const CTxOut& txout, const CPAKList& paklist)
215+ {
216+ const CChainParams& params = Params ();
217+ if (txout.scriptPubKey .IsPegoutScript (params.ParentGenesisBlockHash ()) &&
218+ txout.nAsset .IsExplicit () && txout.nAsset .GetAsset () == params.GetConsensus ().pegged_asset &&
219+ (!ScriptHasValidPAKProof (txout.scriptPubKey , params.ParentGenesisBlockHash (), paklist))) {
220+ return false ;
221+ }
222+ return true ;
223+ }
224+
225+ bool IsPAKValidTx (const CTransaction& tx, const CPAKList& paklist)
226+ {
227+ for (const auto & txout : tx.vout ) {
228+ if (!IsPAKValidOutput (txout, paklist)) {
229+ return false ;
230+ }
231+ }
232+ return true ;
233+ }
0 commit comments