GetPAKKeysFromCommitment utility function

This commit is contained in:
Gregory Sanders 2018-12-17 11:39:12 -05:00
parent bf66d77a8d
commit 86fbc2418f
2 changed files with 76 additions and 0 deletions

View file

@ -3342,6 +3342,75 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
return commitment;
}
// ELEMENTS
boost::optional<CPAKList> GetPAKKeysFromCommitment(const CTransaction& coinbase)
{
std::vector<std::vector<unsigned char> > offline_keys;
std::vector<std::vector<unsigned char> > online_keys;
bool is_reject = false;
for (unsigned int i = 0; i < coinbase.vout.size(); i++) {
const CScript& scriptPubKey = coinbase.vout[i].scriptPubKey;
// OP + push + 4 bytes + push + 33 bytes + push + 33 bytes
// or
// OP + push + 4 bytes + push + 6 bytes (REJECT)
CScript::const_iterator pc = scriptPubKey.begin();
std::vector<unsigned char> data;
opcodetype opcode;
if (!scriptPubKey.GetOp(pc, opcode, data) || opcode != OP_RETURN){
continue;
}
if (!scriptPubKey.GetOp(pc, opcode, data) || data.size() != 4 ||
data[0] != 0xab || data[1] != 0x22 || data[2] != 0xaa || data[3] != 0xee) {
continue;
}
if (!scriptPubKey.GetOp(pc, opcode, data)){
continue;
}
// Check for pak list reject signal
// Returns an empty list regardless of other commitments
if (data.size() == 6 && data[0] == 'R' && data[1] == 'E' && data[2] == 'J' && data[3] == 'E' && data[4] == 'C' && data[5] == 'T') {
is_reject = true;
continue;
}
// Check for offline key
if (data.size() != 33) {
continue;
}
// Check for online key
std::vector<unsigned char> data_online;
if (!scriptPubKey.GetOp(pc, opcode, data_online) || data_online.size() != 33) {
continue;
}
offline_keys.push_back(data);
online_keys.push_back(data_online);
}
if (is_reject) {
offline_keys.clear();
online_keys.clear();
}
if (!is_reject && offline_keys.size() == 0) {
return boost::none;
}
CPAKList paklist;
if (!CPAKList::FromBytes(paklist, offline_keys, online_keys, is_reject)) {
return boost::none;
} else {
return paklist;
}
}
/** Context-dependent validity checks.
* By "context", we mean only the previous block headers, but not the UTXO
* set; UTXO-related validity checks are done in ConnectBlock().

View file

@ -31,6 +31,9 @@
#include <atomic>
#include <boost/optional.hpp> // GetPAKKeysFromCommitment
#include <primitives/pak.h> // CPAKList
class CBlockIndex;
class CBlockTreeDB;
class CChainParams;
@ -426,6 +429,10 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
/** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */
std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
// ELEMENTS
/** Extract pak commitment from coinbase, if it exists. List must be ordered, but not necessarily consecutive in output index */
boost::optional<CPAKList> GetPAKKeysFromCommitment(const CTransaction& coinbase);
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
class CVerifyDB {
public: