From 120245952b58605ccb77a96de1271fc48f054aa5 Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Wed, 19 Jun 2024 16:26:46 +0200 Subject: [PATCH] Port block storage --- src/common/args.cpp | 48 ++++- src/common/args.h | 5 + src/common/system.cpp | 9 + src/common/system.h | 32 +++ src/crypto/muhash.cpp | 8 +- src/crypto/muhash.h | 6 +- src/init/bitcoin-gui.cpp | 2 +- src/init/bitcoin-node.cpp | 2 +- src/init/common.cpp | 8 + src/logging.cpp | 3 +- src/logging.h | 4 +- src/node/blockstorage.h | 410 ++++++++++++++++++++++++++++++++++++++ src/pubkey.cpp | 16 ++ src/pubkey.h | 7 + 14 files changed, 542 insertions(+), 18 deletions(-) diff --git a/src/common/args.cpp b/src/common/args.cpp index a9108e5916..1a1e0671c7 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -35,7 +35,7 @@ #include #include -const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; +const char * const BITCOIN_CONF_FILENAME = "qtum.conf"; const char * const BITCOIN_SETTINGS_FILENAME = "settings.json"; ArgsManager gArgs; @@ -684,12 +684,12 @@ std::string HelpMessageOpt(const std::string &option, const std::string &message fs::path GetDefaultDataDir() { - // Windows: C:\Users\Username\AppData\Roaming\Bitcoin - // macOS: ~/Library/Application Support/Bitcoin - // Unix-like: ~/.bitcoin + // Windows: C:\Users\Username\AppData\Roaming\Qtum + // macOS: ~/Library/Application Support/Qtum + // Unix-like: ~/.qtum #ifdef WIN32 // Windows - return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin"; + return GetSpecialFolderPath(CSIDL_APPDATA) / "Qtum"; #else fs::path pathRet; char* pszHome = getenv("HOME"); @@ -699,10 +699,10 @@ fs::path GetDefaultDataDir() pathRet = fs::path(pszHome); #ifdef MAC_OSX // macOS - return pathRet / "Library/Application Support/Bitcoin"; + return pathRet / "Library/Application Support/Qtum"; #else // Unix-like - return pathRet / ".bitcoin"; + return pathRet / ".qtum"; #endif #endif } @@ -818,6 +818,40 @@ void ArgsManager::LogArgs() const logArgsPrefix("Command-line arg:", "", m_settings.command_line_options); } +std::map> ArgsManager::getArgsList(const std::vector& paramListType) const +{ + LOCK(cs_args); + // Get argument list + std::map args; + for (const auto& arg : m_settings.forced_settings) { + args[arg.first] = true; + } + for (const auto& arg : m_settings.command_line_options) { + args[arg.first] = true; + } + for (const auto& arg : m_settings.ro_config) { + for(const auto& confArg : arg.second) + args[confArg.first] = true; + } + + // Fill argument list with values + std::map> ret; + for (const auto& arg : args) { + std::string paramName = '-' + arg.first; + std::vector paramValue; + bool isList = std::find(std::begin(paramListType), std::end(paramListType), paramName) != std::end(paramListType); + if(isList) { + paramValue = GetArgs(paramName); + } + else { + paramValue.push_back(GetArg(paramName, "")); + } + ret[arg.first] = paramValue; + } + + return ret; +} + namespace common { #ifdef WIN32 WinCmdLineArgs::WinCmdLineArgs() diff --git a/src/common/args.h b/src/common/args.h index 6451b194d1..36b8f6ee0b 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -413,6 +413,11 @@ class ArgsManager */ void LogArgs() const; + /** + * Return config arguments + */ + std::map> getArgsList(const std::vector& paramListType) const; + private: /** * Get data directory path diff --git a/src/common/system.cpp b/src/common/system.cpp index 1fa53a5f34..24bfe03477 100644 --- a/src/common/system.cpp +++ b/src/common/system.cpp @@ -19,6 +19,7 @@ #include #include #endif +#include #ifdef HAVE_MALLOPT_ARENA_MAX #include @@ -105,6 +106,14 @@ int GetNumCores() return std::thread::hardware_concurrency(); } +bool CheckHex(const std::string& str) { + size_t data=0; + if(str.size() > 2 && (str.compare(0, 2, "0x") == 0 || str.compare(0, 2, "0X") == 0)){ + data=2; + } + return str.size() > data && str.find_first_not_of("0123456789abcdefABCDEF", data) == std::string::npos; +} + // Obtain the application startup time (used for uptime calculation) int64_t GetStartupTime() { diff --git a/src/common/system.h b/src/common/system.h index 83280d46ee..e5eb4835f8 100644 --- a/src/common/system.h +++ b/src/common/system.h @@ -13,6 +13,12 @@ #include #include +#ifndef WIN32 +#include +#include +#include +#endif + // Application startup time (used for uptime calculation) int64_t GetStartupTime(); @@ -31,4 +37,30 @@ void runCommand(const std::string& strCommand); */ int GetNumCores(); +#ifdef WIN32 +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else + +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // It's unclear if it's even possible to change thread priorities on Linux, + // but we really and truly need it for the generation threads. +#ifdef PRIO_THREAD + setpriority(PRIO_THREAD, 0, nPriority); +#else + setpriority(PRIO_PROCESS, 0, nPriority); +#endif +} +#endif + +bool CheckHex(const std::string& str); + #endif // BITCOIN_COMMON_SYSTEM_H diff --git a/src/crypto/muhash.cpp b/src/crypto/muhash.cpp index 9c35b0689d..8fa4665ade 100644 --- a/src/crypto/muhash.cpp +++ b/src/crypto/muhash.cpp @@ -275,7 +275,7 @@ void Num3072::Divide(const Num3072& a) if (this->IsOverflow()) this->FullReduce(); } -Num3072::Num3072(const unsigned char (&data)[BYTE_SIZE]) { +Num3072::Num3072(const unsigned char (&data)[DATA_BYTE_SIZE]) { for (int i = 0; i < LIMBS; ++i) { if (sizeof(limb_t) == 4) { this->limbs[i] = ReadLE32(data + 4 * i); @@ -285,7 +285,7 @@ Num3072::Num3072(const unsigned char (&data)[BYTE_SIZE]) { } } -void Num3072::ToBytes(unsigned char (&out)[BYTE_SIZE]) { +void Num3072::ToBytes(unsigned char (&out)[DATA_BYTE_SIZE]) { for (int i = 0; i < LIMBS; ++i) { if (sizeof(limb_t) == 4) { WriteLE32(out + i * 4, this->limbs[i]); @@ -296,7 +296,7 @@ void Num3072::ToBytes(unsigned char (&out)[BYTE_SIZE]) { } Num3072 MuHash3072::ToNum3072(Span in) { - unsigned char tmp[Num3072::BYTE_SIZE]; + unsigned char tmp[Num3072::DATA_BYTE_SIZE]; uint256 hashed_in{(HashWriter{} << in).GetSHA256()}; static_assert(sizeof(tmp) % ChaCha20Aligned::BLOCKLEN == 0); @@ -316,7 +316,7 @@ void MuHash3072::Finalize(uint256& out) noexcept m_numerator.Divide(m_denominator); m_denominator.SetToOne(); // Needed to keep the MuHash object valid - unsigned char data[Num3072::BYTE_SIZE]; + unsigned char data[Num3072::DATA_BYTE_SIZE]; m_numerator.ToBytes(data); out = (HashWriter{} << data).GetSHA256(); diff --git a/src/crypto/muhash.h b/src/crypto/muhash.h index cb53e1743e..3de62d99dc 100644 --- a/src/crypto/muhash.h +++ b/src/crypto/muhash.h @@ -18,7 +18,7 @@ class Num3072 Num3072 GetInverse() const; public: - static constexpr size_t BYTE_SIZE = 384; + static constexpr size_t DATA_BYTE_SIZE = 384; #ifdef __SIZEOF_INT128__ typedef unsigned __int128 double_limb_t; @@ -45,10 +45,10 @@ class Num3072 void Divide(const Num3072& a); void SetToOne(); void Square(); - void ToBytes(unsigned char (&out)[BYTE_SIZE]); + void ToBytes(unsigned char (&out)[DATA_BYTE_SIZE]); Num3072() { this->SetToOne(); }; - Num3072(const unsigned char (&data)[BYTE_SIZE]); + Num3072(const unsigned char (&data)[DATA_BYTE_SIZE]); SERIALIZE_METHODS(Num3072, obj) { diff --git a/src/init/bitcoin-gui.cpp b/src/init/bitcoin-gui.cpp index aceff1e40f..da67115d7c 100644 --- a/src/init/bitcoin-gui.cpp +++ b/src/init/bitcoin-gui.cpp @@ -16,7 +16,7 @@ namespace init { namespace { -const char* EXE_NAME = "bitcoin-gui"; +const char* EXE_NAME = "qtum-gui"; class BitcoinGuiInit : public interfaces::Init { diff --git a/src/init/bitcoin-node.cpp b/src/init/bitcoin-node.cpp index 97b8dc1161..18eb24c9ed 100644 --- a/src/init/bitcoin-node.cpp +++ b/src/init/bitcoin-node.cpp @@ -16,7 +16,7 @@ namespace init { namespace { -const char* EXE_NAME = "bitcoin-node"; +const char* EXE_NAME = "qtum-node"; class BitcoinNodeInit : public interfaces::Init { diff --git a/src/init/common.cpp b/src/init/common.cpp index 0800cd93d8..64650375ea 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ void AddLoggingArgs(ArgsManager& argsman) void SetLoggingOptions(const ArgsManager& args) { LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile"); + LogInstance().m_file_pathVM = AbsPathForConfigVal(args, args.GetPathArg("-debugvmlogfile", DEFAULT_DEBUGVMLOGFILE)); LogInstance().m_file_path = AbsPathForConfigVal(args, args.GetPathArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false)); LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); @@ -57,6 +59,8 @@ void SetLoggingOptions(const ArgsManager& args) #endif LogInstance().m_log_sourcelocations = args.GetBoolArg("-logsourcelocations", DEFAULT_LOGSOURCELOCATIONS); LogInstance().m_always_print_category_level = args.GetBoolArg("-loglevelalways", DEFAULT_LOGLEVELALWAYS); + LogInstance().m_show_evm_logs = args.GetBoolArg("-showevmlogs", DEFAULT_SHOWEVMLOGS); + dev::g_logPost = [&](std::string const& s, char const* c){ LogInstance().LogPrintStr(s + '\n', c ? c : "", "", 0, BCLog::ALL, BCLog::Level::Debug, true); }; fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS); } @@ -121,6 +125,10 @@ bool StartLogging(const ArgsManager& args) fs::PathToString(LogInstance().m_file_path))); } +////////////////////////////////////////////////////////////////////// // qtum + dev::g_logPost(std::string("\n\n\n\n\n\n\n\n\n\n"), NULL); +////////////////////////////////////////////////////////////////////// + if (!LogInstance().m_log_timestamps) LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime())); LogPrintf("Default data directory %s\n", fs::PathToString(GetDefaultDataDir())); diff --git a/src/logging.cpp b/src/logging.cpp index 42f100ded6..801474ff7b 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -15,6 +15,7 @@ #include const char * const DEFAULT_DEBUGLOGFILE = "debug.log"; +const char * const DEFAULT_DEBUGVMLOGFILE = "vm.log"; constexpr auto MAX_USER_SETABLE_SEVERITY_LEVEL{BCLog::Level::Info}; BCLog::Logger& LogInstance() @@ -414,7 +415,7 @@ std::string BCLog::Logger::GetLogPrefix(BCLog::LogFlags category, BCLog::Level l return s; } -void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) +void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level, bool useVMLog) { StdLockGuard scoped_lock(m_cs); std::string str_prefixed = LogEscapeMessage(str); diff --git a/src/logging.h b/src/logging.h index e8ba2d3ecb..3b092a06ee 100644 --- a/src/logging.h +++ b/src/logging.h @@ -123,14 +123,16 @@ namespace BCLog { bool m_log_threadnames = DEFAULT_LOGTHREADNAMES; bool m_log_sourcelocations = DEFAULT_LOGSOURCELOCATIONS; bool m_always_print_category_level = DEFAULT_LOGLEVELALWAYS; + bool m_show_evm_logs = DEFAULT_SHOWEVMLOGS; fs::path m_file_path; + fs::path m_file_pathVM; std::atomic m_reopen_file{false}; std::string GetLogPrefix(LogFlags category, Level level) const; /** Send a string to the log output */ - void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level); + void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level, bool useVMLog = false); /** Returns whether logs will be written to any output */ bool Enabled() const diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index e94674cb99..c76f437be7 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -19,6 +19,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -38,12 +43,25 @@ class BlockValidationState; class CBlockUndo; class Chainstate; class ChainstateManager; +//////////////////////////////////// //qtum +class ChainstateManager; +struct CHeightTxIndexKey; +struct CHeightTxIndexIteratorKey; +struct CAddressIndexKey; +struct CAddressUnspentKey; +struct CAddressUnspentValue; +struct CMempoolAddressDeltaKey; +struct CTimestampIndexKey; +struct CTimestampBlockIndexKey; +struct CTimestampBlockIndexValue; +//////////////////////////////////// namespace Consensus { struct Params; } namespace util { class SignalInterrupt; } // namespace util +using valtype = std::vector; namespace kernel { /** Access to the block database (blocks/index/) */ @@ -384,4 +402,396 @@ class BlockManager void ImportBlocks(ChainstateManager& chainman, std::vector vImportFiles); } // namespace node +//////////////////////////////////////////////////////////// // qtum +struct CHeightTxIndexIteratorKey { + unsigned int height; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 4; + } + template + void Serialize(Stream& s) const { + ser_writedata32be(s, height); + } + template + void Unserialize(Stream& s) { + height = ser_readdata32be(s); + } + + CHeightTxIndexIteratorKey(unsigned int _height) { + height = _height; + } + + CHeightTxIndexIteratorKey() { + SetNull(); + } + + void SetNull() { + height = 0; + } +}; + +struct CHeightTxIndexKey { + unsigned int height; + dev::h160 address; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 24; + } + template + void Serialize(Stream& s) const { + ser_writedata32be(s, height); + s << address.asBytes(); + } + template + void Unserialize(Stream& s) { + height = ser_readdata32be(s); + valtype tmp; + s >> tmp; + address = dev::h160(tmp); + } + + CHeightTxIndexKey(unsigned int _height, dev::h160 _address) { + height = _height; + address = _address; + } + + CHeightTxIndexKey() { + SetNull(); + } + + void SetNull() { + height = 0; + address.clear(); + } +}; + +struct CTimestampIndexIteratorKey { + unsigned int timestamp; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 4; + } + template + void Serialize(Stream& s) const { + ser_writedata32be(s, timestamp); + } + template + void Unserialize(Stream& s) { + timestamp = ser_readdata32be(s); + } + + CTimestampIndexIteratorKey(unsigned int time) { + timestamp = time; + } + + CTimestampIndexIteratorKey() { + SetNull(); + } + + void SetNull() { + timestamp = 0; + } +}; + +struct CTimestampIndexKey { + unsigned int timestamp; + uint256 blockHash; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 36; + } + template + void Serialize(Stream& s) const { + ser_writedata32be(s, timestamp); + blockHash.Serialize(s); + } + template + void Unserialize(Stream& s) { + timestamp = ser_readdata32be(s); + blockHash.Unserialize(s); + } + + CTimestampIndexKey(unsigned int time, uint256 hash) { + timestamp = time; + blockHash = hash; + } + + CTimestampIndexKey() { + SetNull(); + } + + void SetNull() { + timestamp = 0; + blockHash.SetNull(); + } +}; + +struct CTimestampBlockIndexKey { + uint256 blockHash; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 32; + } + + template + void Serialize(Stream& s) const { + blockHash.Serialize(s); + } + + template + void Unserialize(Stream& s) { + blockHash.Unserialize(s); + } + + CTimestampBlockIndexKey(uint256 hash) { + blockHash = hash; + } + + CTimestampBlockIndexKey() { + SetNull(); + } + + void SetNull() { + blockHash.SetNull(); + } +}; + +struct CTimestampBlockIndexValue { + unsigned int ltimestamp; + size_t GetSerializeSize(int nType, int nVersion) const { + return 4; + } + + template + void Serialize(Stream& s) const { + ser_writedata32be(s, ltimestamp); + } + + template + void Unserialize(Stream& s) { + ltimestamp = ser_readdata32be(s); + } + + CTimestampBlockIndexValue (unsigned int time) { + ltimestamp = time; + } + + CTimestampBlockIndexValue() { + SetNull(); + } + + void SetNull() { + ltimestamp = 0; + } +}; + +struct CAddressUnspentKey { + uint8_t type; + uint256 hashBytes; + uint256 txhash; + size_t index; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 69; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + txhash.Serialize(s); + ser_writedata32(s, index); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + txhash.Unserialize(s); + index = ser_readdata32(s); + } + + CAddressUnspentKey(unsigned int addressType, uint256 addressHash, uint256 txid, size_t indexValue) { + type = addressType; + hashBytes = addressHash; + txhash = txid; + index = indexValue; + } + + CAddressUnspentKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + txhash.SetNull(); + index = 0; + } +}; + +struct CAddressUnspentValue { + CAmount satoshis; + CScript script; + int blockHeight; + bool coinStake; + + SERIALIZE_METHODS(CAddressUnspentValue, obj) { READWRITE(obj.satoshis, *(CScriptBase*)(&obj.script), obj.blockHeight, obj.coinStake); } + + CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height, bool isStake) { + satoshis = sats; + script = scriptPubKey; + blockHeight = height; + coinStake = isStake; + } + + CAddressUnspentValue() { + SetNull(); + } + + void SetNull() { + satoshis = -1; + script.clear(); + blockHeight = 0; + coinStake = false; + } + + bool IsNull() const { + return (satoshis == -1); + } +}; + +struct CAddressIndexKey { + uint8_t type; + uint256 hashBytes; + int blockHeight; + unsigned int txindex; + uint256 txhash; + size_t index; + bool spending; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 78; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + // Heights are stored big-endian for key sorting in LevelDB + ser_writedata32be(s, blockHeight); + ser_writedata32be(s, txindex); + txhash.Serialize(s); + ser_writedata32(s, index); + char f = spending; + ser_writedata8(s, f); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + blockHeight = ser_readdata32be(s); + txindex = ser_readdata32be(s); + txhash.Unserialize(s); + index = ser_readdata32(s); + char f = ser_readdata8(s); + spending = f; + } + + CAddressIndexKey(unsigned int addressType, uint256 addressHash, int height, int blockindex, + uint256 txid, size_t indexValue, bool isSpending) { + type = addressType; + hashBytes = addressHash; + blockHeight = height; + txindex = blockindex; + txhash = txid; + index = indexValue; + spending = isSpending; + } + + CAddressIndexKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + blockHeight = 0; + txindex = 0; + txhash.SetNull(); + index = 0; + spending = false; + } + +}; + +struct CAddressIndexIteratorHeightKey { + uint8_t type; + uint256 hashBytes; + int blockHeight; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 37; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + ser_writedata32be(s, blockHeight); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + blockHeight = ser_readdata32be(s); + } + + CAddressIndexIteratorHeightKey(unsigned int addressType, uint256 addressHash, int height) { + type = addressType; + hashBytes = addressHash; + blockHeight = height; + } + + CAddressIndexIteratorHeightKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + blockHeight = 0; + } +}; + +struct CAddressIndexIteratorKey { + uint8_t type; + uint256 hashBytes; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 33; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + } + + CAddressIndexIteratorKey(unsigned int addressType, uint256 addressHash) { + type = addressType; + hashBytes = addressHash; + } + + CAddressIndexIteratorKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + } +}; +//////////////////////////////////////////////////////////// #endif // BITCOIN_NODE_BLOCKSTORAGE_H diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 11e1b4abb5..06ff16c858 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -281,6 +281,22 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector& vchS return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey); } +bool CPubKey::RecoverLaxDER(const uint256 &hash, const std::vector& vchSig, uint8_t recid, bool fComp) { + secp256k1_ecdsa_signature sig; + if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) { + return false; + } + + std::vector strictVchSig(65); + strictVchSig[0] = recid | (fComp ? 4 : 0); + strictVchSig[0] += 27; + if(!secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_static, strictVchSig.data()+1, &sig)) { + return false; + } + + return RecoverCompact(hash, strictVchSig); +} + bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector& vchSig) { if (vchSig.size() != COMPACT_SIGNATURE_SIZE) return false; diff --git a/src/pubkey.h b/src/pubkey.h index 15d7e7bc07..5b37c101a2 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -114,6 +114,10 @@ class CPubKey const unsigned char* begin() const { return vch; } const unsigned char* end() const { return vch + size(); } const unsigned char& operator[](unsigned int pos) const { return vch[pos]; } + std::vector getvch() const + { + return std::vector(begin(), end()); + } //! Comparator implementation. friend bool operator==(const CPubKey& a, const CPubKey& b) @@ -217,6 +221,9 @@ class CPubKey */ static bool CheckLowS(const std::vector& vchSig); + //! Recover public key from a lax DER signature + bool RecoverLaxDER(const uint256 &hash, const std::vector& vchSig, uint8_t recid, bool fComp); + //! Recover a public key from a compact signature. bool RecoverCompact(const uint256& hash, const std::vector& vchSig);