Skip to content

Commit 86fbc24

Browse files
committed
GetPAKKeysFromCommitment utility function
1 parent bf66d77 commit 86fbc24

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/validation.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,6 +3342,75 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
33423342
return commitment;
33433343
}
33443344

3345+
// ELEMENTS
3346+
boost::optional<CPAKList> GetPAKKeysFromCommitment(const CTransaction& coinbase)
3347+
{
3348+
std::vector<std::vector<unsigned char> > offline_keys;
3349+
std::vector<std::vector<unsigned char> > online_keys;
3350+
bool is_reject = false;
3351+
for (unsigned int i = 0; i < coinbase.vout.size(); i++) {
3352+
const CScript& scriptPubKey = coinbase.vout[i].scriptPubKey;
3353+
3354+
// OP + push + 4 bytes + push + 33 bytes + push + 33 bytes
3355+
// or
3356+
// OP + push + 4 bytes + push + 6 bytes (REJECT)
3357+
3358+
CScript::const_iterator pc = scriptPubKey.begin();
3359+
std::vector<unsigned char> data;
3360+
opcodetype opcode;
3361+
3362+
if (!scriptPubKey.GetOp(pc, opcode, data) || opcode != OP_RETURN){
3363+
continue;
3364+
}
3365+
3366+
if (!scriptPubKey.GetOp(pc, opcode, data) || data.size() != 4 ||
3367+
data[0] != 0xab || data[1] != 0x22 || data[2] != 0xaa || data[3] != 0xee) {
3368+
continue;
3369+
}
3370+
3371+
if (!scriptPubKey.GetOp(pc, opcode, data)){
3372+
continue;
3373+
}
3374+
3375+
// Check for pak list reject signal
3376+
// Returns an empty list regardless of other commitments
3377+
if (data.size() == 6 && data[0] == 'R' && data[1] == 'E' && data[2] == 'J' && data[3] == 'E' && data[4] == 'C' && data[5] == 'T') {
3378+
is_reject = true;
3379+
continue;
3380+
}
3381+
3382+
// Check for offline key
3383+
if (data.size() != 33) {
3384+
continue;
3385+
}
3386+
3387+
// Check for online key
3388+
std::vector<unsigned char> data_online;
3389+
if (!scriptPubKey.GetOp(pc, opcode, data_online) || data_online.size() != 33) {
3390+
continue;
3391+
}
3392+
3393+
offline_keys.push_back(data);
3394+
online_keys.push_back(data_online);
3395+
}
3396+
if (is_reject) {
3397+
offline_keys.clear();
3398+
online_keys.clear();
3399+
}
3400+
if (!is_reject && offline_keys.size() == 0) {
3401+
return boost::none;
3402+
}
3403+
CPAKList paklist;
3404+
if (!CPAKList::FromBytes(paklist, offline_keys, online_keys, is_reject)) {
3405+
return boost::none;
3406+
} else {
3407+
return paklist;
3408+
}
3409+
}
3410+
3411+
3412+
3413+
33453414
/** Context-dependent validity checks.
33463415
* By "context", we mean only the previous block headers, but not the UTXO
33473416
* set; UTXO-related validity checks are done in ConnectBlock().

src/validation.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131

3232
#include <atomic>
3333

34+
#include <boost/optional.hpp> // GetPAKKeysFromCommitment
35+
#include <primitives/pak.h> // CPAKList
36+
3437
class CBlockIndex;
3538
class CBlockTreeDB;
3639
class CChainParams;
@@ -426,6 +429,10 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
426429
/** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */
427430
std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
428431

432+
// ELEMENTS
433+
/** Extract pak commitment from coinbase, if it exists. List must be ordered, but not necessarily consecutive in output index */
434+
boost::optional<CPAKList> GetPAKKeysFromCommitment(const CTransaction& coinbase);
435+
429436
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
430437
class CVerifyDB {
431438
public:

0 commit comments

Comments
 (0)