Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5faf29d
refactor: use scoped weak enum instead of bare values for address type
kwvg Sep 18, 2023
5950f7c
refactor: cleanup map comparison struct definitions
kwvg Sep 25, 2023
12fd357
refactor: use boolean for transaction state, rename variable
kwvg Sep 13, 2023
5397782
refactor: cleanup addressindex structs, use fixed-length integers
kwvg Sep 18, 2023
98e6185
refactor: add separators between members, functions and serialization
kwvg Sep 13, 2023
5c34da0
refactor: cleanup spentindex structs, use fixed-length integers
kwvg Sep 18, 2023
6a5e74e
refactor: use uint8_t for m_address_type
kwvg Sep 13, 2023
fc2d193
refactor: remove size_t usage in spentindex structs
kwvg Sep 13, 2023
ce3b5ac
docs: add BitPay copyright to file headers
kwvg Sep 14, 2023
cc2efac
refactor: move timestamp index out of spentindex
kwvg Sep 14, 2023
0cc321c
refactor: move CAddressIndex* out of spentindex
kwvg Sep 25, 2023
51203a8
refactor: use static_cast for (de)serializing bool
kwvg Sep 25, 2023
b29ef2e
refactor: deduplicate scriptPubKey trimming, index operations
kwvg Sep 14, 2023
f47021a
refactor: remove more code duplication from (dis)connect operations
kwvg Sep 24, 2023
b08a634
refactor: add missing headers to {address,timestamp}index
kwvg Sep 25, 2023
109f57c
refactor: use range-based loops instead of iterators
kwvg Sep 25, 2023
c65a10f
refactor: use structure binding in for loop in rpc/misc
kwvg Sep 25, 2023
f011c31
refactor: make AddressType a strong enum, remove uint8_t for address_…
kwvg Sep 25, 2023
93ddd3f
refactor: consolidate P2PK{H} types to P2PK_OR_P2PKH
kwvg Sep 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ BITCOIN_CORE_H = \
support/events.h \
support/lockedpool.h \
sync.h \
timestampindex.h \
threadsafety.h \
threadinterrupt.h \
timedata.h \
Expand Down Expand Up @@ -385,6 +386,7 @@ libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CP
libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_server_a_SOURCES = \
addrdb.cpp \
addressindex.cpp \
addrman.cpp \
banman.cpp \
batchedlogger.cpp \
Expand Down
43 changes: 43 additions & 0 deletions src/addressindex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2016 BitPay, Inc.
// Copyright (c) 2023 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <addressindex.h>

#include <key_io.h>
#include <hash.h>
#include <script/script.h>

template <typename T1>
inline std::vector<uint8_t> TrimScriptP2PKH(const T1& input) {
return std::vector<uint8_t>(input.begin() + 3, input.begin() + 23);
};

template <typename T1>
inline std::vector<uint8_t> TrimScriptP2SH(const T1& input) {
return std::vector<uint8_t>(input.begin() + 2, input.begin() + 22);
};

template <typename T1>
inline std::vector<uint8_t> TrimScriptP2PK(const T1& input) {
return std::vector<uint8_t>(input.begin() + 1, input.end() - 1);
};

bool AddressBytesFromScript(const CScript& script, AddressType& address_type, uint160& address_bytes) {
if (script.IsPayToScriptHash()) {
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(script));
} else if (script.IsPayToPublicKeyHash()) {
address_type = AddressType::P2PK_OR_P2PKH;
address_bytes = uint160(TrimScriptP2PKH(script));
} else if (script.IsPayToPublicKey()) {
address_type = AddressType::P2PK_OR_P2PKH;
address_bytes = Hash160(TrimScriptP2PK(script));
} else {
address_type = AddressType::UNKNOWN;
address_bytes.SetNull();
return false;
}
return true;
}
245 changes: 190 additions & 55 deletions src/addressindex.h
Original file line number Diff line number Diff line change
@@ -1,84 +1,219 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Copyright (c) 2016 BitPay, Inc.
// Copyright (c) 2023 The Dash Core developers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems as this file never has been in bitcoin so far as I see...

Probably need to remove Statoshi and Bitcoin Core from copyright.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume the copyrights were added in because they borrowed logic from Nakamoto-era code and beyond. I was surprised to find that their own copyright was missing so it was added in to make the original author of the code much more apparent.

// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_ADDRESSINDEX_H
#define BITCOIN_ADDRESSINDEX_H

#include <uint256.h>
#include <amount.h>
#include <serialize.h>
#include <uint256.h>
#include <util/underlying.h>

#include <chrono>
#include <tuple>

class CScript;

enum class AddressType : uint8_t {
P2PK_OR_P2PKH = 1,
P2SH = 2,

UNKNOWN = 0
};
template<> struct is_serializable_enum<AddressType> : std::true_type {};

struct CMempoolAddressDelta
{
std::chrono::seconds time;
CAmount amount;
uint256 prevhash;
unsigned int prevout;
public:
std::chrono::seconds m_time;
CAmount m_amount;
uint256 m_prev_hash;
uint32_t m_prev_out{0};

CMempoolAddressDelta(std::chrono::seconds t, CAmount a, uint256 hash, unsigned int out) {
time = t;
amount = a;
prevhash = hash;
prevout = out;
}
public:
CMempoolAddressDelta(std::chrono::seconds time, CAmount amount, uint256 prev_hash, uint32_t prev_out) :
m_time{time}, m_amount{amount}, m_prev_hash{prev_hash}, m_prev_out{prev_out} {}

CMempoolAddressDelta(std::chrono::seconds t, CAmount a) {
time = t;
amount = a;
prevhash.SetNull();
prevout = 0;
}
CMempoolAddressDelta(std::chrono::seconds time, CAmount amount) :
m_time{time}, m_amount{amount} {}
};

struct CMempoolAddressDeltaKey
{
int type;
uint160 addressBytes;
uint256 txhash;
unsigned int index;
int spending;

CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) {
type = addressType;
addressBytes = addressHash;
txhash = hash;
index = i;
spending = s;
}

CMempoolAddressDeltaKey(int addressType, uint160 addressHash) {
type = addressType;
addressBytes = addressHash;
txhash.SetNull();
index = 0;
spending = 0;
}
public:
AddressType m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
uint256 m_tx_hash;
uint32_t m_tx_index{0};
bool m_tx_spent{false};

public:
CMempoolAddressDeltaKey(AddressType address_type, uint160 address_bytes, uint256 tx_hash, uint32_t tx_index, bool tx_spent) :
m_address_type{address_type},
m_address_bytes{address_bytes},
m_tx_hash{tx_hash},
m_tx_index{tx_index},
m_tx_spent{tx_spent} {};

CMempoolAddressDeltaKey(AddressType address_type, uint160 address_bytes) :
m_address_type{address_type},
m_address_bytes{address_bytes} {};
};

struct CMempoolAddressDeltaKeyCompare
{
bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const {
if (a.type == b.type) {
if (a.addressBytes == b.addressBytes) {
if (a.txhash == b.txhash) {
if (a.index == b.index) {
return a.spending < b.spending;
} else {
return a.index < b.index;
}
} else {
return a.txhash < b.txhash;
}
} else {
return a.addressBytes < b.addressBytes;
}
} else {
return a.type < b.type;
}
auto to_tuple = [](const CMempoolAddressDeltaKey& obj) {
return std::tie(obj.m_address_type, obj.m_address_bytes, obj.m_tx_hash, obj.m_tx_index, obj.m_tx_spent);
};
return to_tuple(a) < to_tuple(b);
}
};

struct CAddressIndexKey {
public:
AddressType m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
int32_t m_block_height{0};
uint32_t m_block_tx_pos{0};
uint256 m_tx_hash;
uint32_t m_tx_index{0};
bool m_tx_spent{false};

public:
CAddressIndexKey() {
SetNull();
}

CAddressIndexKey(AddressType address_type, uint160 address_bytes, int32_t block_height, uint32_t block_tx_pos, uint256 tx_hash,
uint32_t tx_index, bool tx_spent) :
m_address_type{address_type},
m_address_bytes{address_bytes},
m_block_height{block_height},
m_block_tx_pos{block_tx_pos},
m_tx_hash{tx_hash},
m_tx_index{tx_index},
m_tx_spent{tx_spent} {};

void SetNull() {
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
m_block_height = 0;
m_block_tx_pos = 0;
m_tx_hash.SetNull();
m_tx_index = 0;
m_tx_spent = false;
}

public:
size_t GetSerializeSize(int nType, int nVersion) const {
return 66;
}

template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, ToUnderlying(m_address_type));
m_address_bytes.Serialize(s);
// Heights are stored big-endian for key sorting in LevelDB
ser_writedata32be(s, m_block_height);
ser_writedata32be(s, m_block_tx_pos);
m_tx_hash.Serialize(s);
ser_writedata32(s, m_tx_index);
ser_writedata8(s, static_cast<uint8_t>(m_tx_spent));
}

template<typename Stream>
void Unserialize(Stream& s) {
m_address_type = static_cast<AddressType>(ser_readdata8(s));
m_address_bytes.Unserialize(s);
m_block_height = ser_readdata32be(s);
m_block_tx_pos = ser_readdata32be(s);
m_tx_hash.Unserialize(s);
m_tx_index = ser_readdata32(s);
m_tx_spent = static_cast<bool>(ser_readdata8(s));
}
};

struct CAddressIndexIteratorKey {
public:
AddressType m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;

public:
CAddressIndexIteratorKey() {
SetNull();
}

CAddressIndexIteratorKey(AddressType address_type, uint160 address_bytes) :
m_address_type{address_type}, m_address_bytes{address_bytes} {};

void SetNull() {
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
}

public:
size_t GetSerializeSize(int nType, int nVersion) const {
return 21;
}

template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, ToUnderlying(m_address_type));
m_address_bytes.Serialize(s);
}

template<typename Stream>
void Unserialize(Stream& s) {
m_address_type = static_cast<AddressType>(ser_readdata8(s));
m_address_bytes.Unserialize(s);
}
};

struct CAddressIndexIteratorHeightKey {
public:
AddressType m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
int32_t m_block_height{0};

public:
CAddressIndexIteratorHeightKey() {
SetNull();
}

CAddressIndexIteratorHeightKey(AddressType address_type, uint160 address_bytes, int32_t block_height) :
m_address_type{address_type}, m_address_bytes{address_bytes}, m_block_height{block_height} {};

void SetNull() {
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
m_block_height = 0;
}

public:
size_t GetSerializeSize(int nType, int nVersion) const {
return 25;
}

template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, ToUnderlying(m_address_type));
m_address_bytes.Serialize(s);
ser_writedata32be(s, m_block_height);
}

template<typename Stream>
void Unserialize(Stream& s) {
m_address_type = static_cast<AddressType>(ser_readdata8(s));
m_address_bytes.Unserialize(s);
m_block_height = ser_readdata32be(s);
}
};

bool AddressBytesFromScript(const CScript& script, AddressType& address_type, uint160& address_bytes);

#endif // BITCOIN_ADDRESSINDEX_H
19 changes: 10 additions & 9 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <univalue.h>
#include <util/strencodings.h>

#include <addressindex.h>
#include <spentindex.h>

#include <evo/assetlocktx.h>
Expand Down Expand Up @@ -213,12 +214,12 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
auto it = ptxSpentInfo->mSpentInfo.find(spentKey);
if (it != ptxSpentInfo->mSpentInfo.end()) {
auto spentInfo = it->second;
in.pushKV("value", ValueFromAmount(spentInfo.satoshis));
in.pushKV("valueSat", spentInfo.satoshis);
if (spentInfo.addressType == 1) {
in.pushKV("address", EncodeDestination(PKHash(spentInfo.addressHash)));
} else if (spentInfo.addressType == 2) {
in.pushKV("address", EncodeDestination(ScriptHash(spentInfo.addressHash)));
in.pushKV("value", ValueFromAmount(spentInfo.m_amount));
in.pushKV("valueSat", spentInfo.m_amount);
if (spentInfo.m_address_type == AddressType::P2PK_OR_P2PKH) {
in.pushKV("address", EncodeDestination(PKHash(spentInfo.m_address_bytes)));
} else if (spentInfo.m_address_type == AddressType::P2SH) {
in.pushKV("address", EncodeDestination(ScriptHash(spentInfo.m_address_bytes)));
}
}
}
Expand Down Expand Up @@ -248,9 +249,9 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
auto it = ptxSpentInfo->mSpentInfo.find(spentKey);
if (it != ptxSpentInfo->mSpentInfo.end()) {
auto spentInfo = it->second;
out.pushKV("spentTxId", spentInfo.txid.GetHex());
out.pushKV("spentIndex", (int)spentInfo.inputIndex);
out.pushKV("spentHeight", spentInfo.blockHeight);
out.pushKV("spentTxId", spentInfo.m_tx_hash.GetHex());
out.pushKV("spentIndex", (int)spentInfo.m_tx_index);
out.pushKV("spentHeight", spentInfo.m_block_height);
}
}
vout.push_back(out);
Expand Down
10 changes: 5 additions & 5 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,8 +838,8 @@ static UniValue getblockhashes(const JSONRPCRequest& request)
}

UniValue result(UniValue::VARR);
for (std::vector<uint256>::const_iterator it=blockHashes.begin(); it!=blockHashes.end(); it++) {
result.push_back(it->GetHex());
for (const auto& hash : blockHashes) {
result.push_back(hash.GetHex());
}

return result;
Expand Down Expand Up @@ -1828,9 +1828,9 @@ static UniValue getchaintips(const JSONRPCRequest& request)
}
}

for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) {
if (setPrevs.erase(*it) == 0) {
setTips.insert(*it);
for (const auto& orphan : setOrphans) {
if (setPrevs.erase(orphan) == 0) {
setTips.insert(orphan);
}
}

Expand Down
Loading