refactor: cleanup spentindex structs, use fixed-length integers

This commit is contained in:
Kittywhiskers Van Gogh 2023-09-18 22:47:33 +05:30
parent 98e61857fe
commit 5c34da0675
4 changed files with 176 additions and 194 deletions

View File

@ -214,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 == AddressType::P2PK) {
in.pushKV("address", EncodeDestination(PKHash(spentInfo.addressHash)));
} else if (spentInfo.addressType == AddressType::P2SH) {
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) {
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)));
}
}
}
@ -249,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);

View File

@ -655,7 +655,7 @@ static bool getAddressesFromParams(const UniValue& params, std::vector<std::pair
static bool heightSort(std::pair<CAddressUnspentKey, CAddressUnspentValue> a,
std::pair<CAddressUnspentKey, CAddressUnspentValue> b) {
return a.second.blockHeight < b.second.blockHeight;
return a.second.m_block_height < b.second.m_block_height;
}
static bool timestampSort(std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> a,
@ -786,16 +786,16 @@ static UniValue getaddressutxos(const JSONRPCRequest& request)
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) {
UniValue output(UniValue::VOBJ);
std::string address;
if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) {
if (!getAddressFromIndex(it->first.m_address_type, it->first.m_address_bytes, address)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
}
output.pushKV("address", address);
output.pushKV("txid", it->first.txhash.GetHex());
output.pushKV("outputIndex", (int)it->first.index);
output.pushKV("script", HexStr(it->second.script));
output.pushKV("satoshis", it->second.satoshis);
output.pushKV("height", it->second.blockHeight);
output.pushKV("txid", it->first.m_tx_hash.GetHex());
output.pushKV("outputIndex", (int)it->first.m_tx_index);
output.pushKV("script", HexStr(it->second.m_tx_script));
output.pushKV("satoshis", it->second.m_amount);
output.pushKV("height", it->second.m_block_height);
result.push_back(output);
}
@ -871,16 +871,16 @@ static UniValue getaddressdeltas(const JSONRPCRequest& request)
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
std::string address;
if (!getAddressFromIndex(it->first.type, it->first.hashBytes, address)) {
if (!getAddressFromIndex(it->first.m_address_type, it->first.m_address_bytes, address)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unknown address type");
}
UniValue delta(UniValue::VOBJ);
delta.pushKV("satoshis", it->second);
delta.pushKV("txid", it->first.txhash.GetHex());
delta.pushKV("index", (int)it->first.index);
delta.pushKV("blockindex", (int)it->first.txindex);
delta.pushKV("height", it->first.blockHeight);
delta.pushKV("txid", it->first.m_tx_hash.GetHex());
delta.pushKV("index", (int)it->first.m_tx_index);
delta.pushKV("blockindex", (int)it->first.m_block_tx_pos);
delta.pushKV("height", it->first.m_block_height);
delta.pushKV("address", address);
result.push_back(delta);
}
@ -939,7 +939,7 @@ static UniValue getaddressbalance(const JSONRPCRequest& request)
if (it->second > 0) {
received += it->second;
}
if (it->first.txindex == 0 && nHeight - it->first.blockHeight < COINBASE_MATURITY) {
if (it->first.m_block_tx_pos == 0 && nHeight - it->first.m_block_height < COINBASE_MATURITY) {
balance_immature += it->second;
} else {
balance_spendable += it->second;
@ -1013,8 +1013,8 @@ static UniValue getaddresstxids(const JSONRPCRequest& request)
UniValue result(UniValue::VARR);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
int height = it->first.blockHeight;
std::string txid = it->first.txhash.GetHex();
int height = it->first.m_block_height;
std::string txid = it->first.m_tx_hash.GetHex();
if (addresses.size() > 1) {
txids.insert(std::make_pair(height, txid));
@ -1078,9 +1078,9 @@ static UniValue getspentinfo(const JSONRPCRequest& request)
}
UniValue obj(UniValue::VOBJ);
obj.pushKV("txid", value.txid.GetHex());
obj.pushKV("index", (int)value.inputIndex);
obj.pushKV("height", value.blockHeight);
obj.pushKV("txid", value.m_tx_hash.GetHex());
obj.pushKV("index", (int)value.m_tx_index);
obj.pushKV("height", value.m_block_height);
return obj;
}

View File

@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// 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.
@ -16,71 +17,69 @@
struct CSpentIndexKey {
public:
uint256 txid;
unsigned int outputIndex;
uint256 m_tx_hash;
uint32_t m_tx_index{0};
public:
CSpentIndexKey(uint256 t, unsigned int i) {
txid = t;
outputIndex = i;
}
CSpentIndexKey() {
SetNull();
}
CSpentIndexKey(uint256 txout_hash, uint32_t txout_index) :
m_tx_hash{txout_hash}, m_tx_index{txout_index} {};
void SetNull() {
txid.SetNull();
outputIndex = 0;
m_tx_hash.SetNull();
m_tx_index = 0;
}
public:
SERIALIZE_METHODS(CSpentIndexKey, obj)
{
READWRITE(obj.txid, obj.outputIndex);
READWRITE(obj.m_tx_hash, obj.m_tx_index);
}
};
struct CSpentIndexValue {
public:
uint256 txid;
unsigned int inputIndex;
int blockHeight;
CAmount satoshis;
int addressType;
uint160 addressHash;
uint256 m_tx_hash;
uint32_t m_tx_index{0};
int32_t m_block_height{0};
CAmount m_amount{0};
int32_t m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
public:
CSpentIndexValue(uint256 t, unsigned int i, int h, CAmount s, int type, uint160 a) {
txid = t;
inputIndex = i;
blockHeight = h;
satoshis = s;
addressType = type;
addressHash = a;
}
CSpentIndexValue() {
SetNull();
}
CSpentIndexValue(uint256 txin_hash, uint32_t txin_index, int32_t block_height, CAmount amount, int32_t address_type,
uint160 address_bytes) :
m_tx_hash{txin_hash},
m_tx_index{txin_index},
m_block_height{block_height},
m_amount{amount},
m_address_type{address_type},
m_address_bytes{address_bytes} {};
void SetNull() {
txid.SetNull();
inputIndex = 0;
blockHeight = 0;
satoshis = 0;
addressType = AddressType::UNKNOWN;
addressHash.SetNull();
m_tx_hash.SetNull();
m_tx_index = 0;
m_block_height = 0;
m_amount = 0;
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
}
bool IsNull() const {
return txid.IsNull();
return m_tx_hash.IsNull();
}
public:
SERIALIZE_METHODS(CSpentIndexValue, obj)
{
READWRITE(obj.txid, obj.inputIndex, obj.blockHeight, obj.satoshis, obj.addressType, obj.addressHash);
READWRITE(obj.m_tx_hash, obj.m_tx_index, obj.m_block_height, obj.m_amount, obj.m_address_type, obj.m_address_bytes);
}
};
@ -88,7 +87,7 @@ struct CSpentIndexKeyCompare
{
bool operator()(const CSpentIndexKey& a, const CSpentIndexKey& b) const {
auto to_tuple = [](const CSpentIndexKey& obj) {
return std::tie(obj.txid, obj.outputIndex);
return std::tie(obj.m_tx_hash, obj.m_tx_index);
};
return to_tuple(a) < to_tuple(b);
}
@ -101,19 +100,17 @@ struct CSpentIndexTxInfo
struct CTimestampIndexIteratorKey {
public:
unsigned int timestamp;
uint32_t m_time;
public:
CTimestampIndexIteratorKey(unsigned int time) {
timestamp = time;
}
CTimestampIndexIteratorKey() {
SetNull();
}
CTimestampIndexIteratorKey(uint32_t time) : m_time{time} {};
void SetNull() {
timestamp = 0;
m_time = 0;
}
public:
@ -123,33 +120,31 @@ public:
template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata32be(s, timestamp);
ser_writedata32be(s, m_time);
}
template<typename Stream>
void Unserialize(Stream& s) {
timestamp = ser_readdata32be(s);
m_time = ser_readdata32be(s);
}
};
struct CTimestampIndexKey {
public:
unsigned int timestamp;
uint256 blockHash;
uint32_t m_block_time;
uint256 m_block_hash;
public:
CTimestampIndexKey(unsigned int time, uint256 hash) {
timestamp = time;
blockHash = hash;
}
CTimestampIndexKey() {
SetNull();
}
CTimestampIndexKey(uint32_t block_time, uint256 block_hash) :
m_block_time{block_time}, m_block_hash{block_hash} {};
void SetNull() {
timestamp = 0;
blockHash.SetNull();
m_block_time = 0;
m_block_hash.SetNull();
}
public:
@ -159,41 +154,37 @@ public:
template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata32be(s, timestamp);
blockHash.Serialize(s);
ser_writedata32be(s, m_block_time);
m_block_hash.Serialize(s);
}
template<typename Stream>
void Unserialize(Stream& s) {
timestamp = ser_readdata32be(s);
blockHash.Unserialize(s);
m_block_time = ser_readdata32be(s);
m_block_hash.Unserialize(s);
}
};
struct CAddressUnspentKey {
public:
unsigned int type;
uint160 hashBytes;
uint256 txhash;
size_t index;
uint32_t m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
uint256 m_tx_hash;
size_t m_tx_index{0};
public:
CAddressUnspentKey(unsigned int addressType, uint160 addressHash, uint256 txid, size_t indexValue) {
type = addressType;
hashBytes = addressHash;
txhash = txid;
index = indexValue;
}
CAddressUnspentKey() {
SetNull();
}
CAddressUnspentKey(uint32_t address_type, uint160 address_bytes, uint256 tx_hash, size_t tx_index) :
m_address_type{address_type}, m_address_bytes{address_bytes}, m_tx_hash{tx_hash}, m_tx_index{tx_index} {};
void SetNull() {
type = AddressType::UNKNOWN;
hashBytes.SetNull();
txhash.SetNull();
index = 0;
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
m_tx_hash.SetNull();
m_tx_index = 0;
}
public:
@ -203,89 +194,85 @@ public:
template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, type);
hashBytes.Serialize(s);
txhash.Serialize(s);
ser_writedata32(s, index);
ser_writedata8(s, m_address_type);
m_address_bytes.Serialize(s);
m_tx_hash.Serialize(s);
ser_writedata32(s, m_tx_index);
}
template<typename Stream>
void Unserialize(Stream& s) {
type = ser_readdata8(s);
hashBytes.Unserialize(s);
txhash.Unserialize(s);
index = ser_readdata32(s);
m_address_type = ser_readdata8(s);
m_address_bytes.Unserialize(s);
m_tx_hash.Unserialize(s);
m_tx_index = ser_readdata32(s);
}
};
struct CAddressUnspentValue {
public:
CAmount satoshis;
CScript script;
int blockHeight;
CAmount m_amount{-1};
CScript m_tx_script;
int32_t m_block_height;
public:
CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height) {
satoshis = sats;
script = scriptPubKey;
blockHeight = height;
}
CAddressUnspentValue() {
SetNull();
}
CAddressUnspentValue(CAmount amount, CScript tx_script, int32_t block_height) :
m_amount{amount}, m_tx_script{tx_script}, m_block_height{block_height} {};
void SetNull() {
satoshis = -1;
script.clear();
blockHeight = 0;
m_amount = -1;
m_tx_script.clear();
m_block_height = 0;
}
bool IsNull() const {
return (satoshis == -1);
return (m_amount == -1);
}
public:
SERIALIZE_METHODS(CAddressUnspentValue, obj)
{
READWRITE(obj.satoshis, obj.script, obj.blockHeight);
READWRITE(obj.m_amount, obj.m_tx_script, obj.m_block_height);
}
};
struct CAddressIndexKey {
public:
unsigned int type;
uint160 hashBytes;
int blockHeight;
unsigned int txindex;
uint256 txhash;
size_t index;
bool is_spent;
uint32_t 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;
size_t m_tx_index{0};
bool m_tx_spent{false};
public:
CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex,
uint256 txid, size_t indexValue, bool isSpending) {
type = addressType;
hashBytes = addressHash;
blockHeight = height;
txindex = blockindex;
txhash = txid;
index = indexValue;
is_spent = isSpending;
}
CAddressIndexKey() {
SetNull();
}
CAddressIndexKey(uint32_t address_type, uint160 address_bytes, int32_t block_height, uint32_t block_tx_pos, uint256 tx_hash,
size_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() {
type = AddressType::UNKNOWN;
hashBytes.SetNull();
blockHeight = 0;
txindex = 0;
txhash.SetNull();
index = 0;
is_spent = false;
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:
@ -295,48 +282,46 @@ public:
template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, type);
hashBytes.Serialize(s);
ser_writedata8(s, m_address_type);
m_address_bytes.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 = is_spent;
ser_writedata32be(s, m_block_height);
ser_writedata32be(s, m_block_tx_pos);
m_tx_hash.Serialize(s);
ser_writedata32(s, m_tx_index);
char f = m_tx_spent;
ser_writedata8(s, f);
}
template<typename Stream>
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);
m_address_type = 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);
char f = ser_readdata8(s);
is_spent = f;
m_tx_spent = f;
}
};
struct CAddressIndexIteratorKey {
public:
unsigned int type;
uint160 hashBytes;
uint32_t m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
public:
CAddressIndexIteratorKey(unsigned int addressType, uint160 addressHash) {
type = addressType;
hashBytes = addressHash;
}
CAddressIndexIteratorKey() {
SetNull();
}
CAddressIndexIteratorKey(uint32_t address_type, uint160 address_bytes) :
m_address_type{address_type}, m_address_bytes{address_bytes} {};
void SetNull() {
type = AddressType::UNKNOWN;
hashBytes.SetNull();
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
}
public:
@ -346,38 +331,35 @@ public:
template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, type);
hashBytes.Serialize(s);
ser_writedata8(s, m_address_type);
m_address_bytes.Serialize(s);
}
template<typename Stream>
void Unserialize(Stream& s) {
type = ser_readdata8(s);
hashBytes.Unserialize(s);
m_address_type = ser_readdata8(s);
m_address_bytes.Unserialize(s);
}
};
struct CAddressIndexIteratorHeightKey {
public:
unsigned int type;
uint160 hashBytes;
int blockHeight;
uint32_t m_address_type{AddressType::UNKNOWN};
uint160 m_address_bytes;
int32_t m_block_height{0};
public:
CAddressIndexIteratorHeightKey(unsigned int addressType, uint160 addressHash, int height) {
type = addressType;
hashBytes = addressHash;
blockHeight = height;
}
CAddressIndexIteratorHeightKey() {
SetNull();
}
CAddressIndexIteratorHeightKey(uint32_t 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() {
type = AddressType::UNKNOWN;
hashBytes.SetNull();
blockHeight = 0;
m_address_type = AddressType::UNKNOWN;
m_address_bytes.SetNull();
m_block_height = 0;
}
public:
@ -387,16 +369,16 @@ public:
template<typename Stream>
void Serialize(Stream& s) const {
ser_writedata8(s, type);
hashBytes.Serialize(s);
ser_writedata32be(s, blockHeight);
ser_writedata8(s, m_address_type);
m_address_bytes.Serialize(s);
ser_writedata32be(s, m_block_height);
}
template<typename Stream>
void Unserialize(Stream& s) {
type = ser_readdata8(s);
hashBytes.Unserialize(s);
blockHeight = ser_readdata32be(s);
m_address_type = ser_readdata8(s);
m_address_bytes.Unserialize(s);
m_block_height = ser_readdata32be(s);
}
};

View File

@ -275,7 +275,7 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, int type,
while (pcursor->Valid()) {
std::pair<char,CAddressUnspentKey> key;
if (pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.hashBytes == addressHash) {
if (pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.m_address_bytes == addressHash) {
CAddressUnspentValue nValue;
if (pcursor->GetValue(nValue)) {
unspentOutputs.push_back(std::make_pair(key.second, nValue));
@ -319,8 +319,8 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type,
while (pcursor->Valid()) {
std::pair<char,CAddressIndexKey> key;
if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.hashBytes == addressHash) {
if (end > 0 && key.second.blockHeight > end) {
if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.m_address_bytes == addressHash) {
if (end > 0 && key.second.m_block_height > end) {
break;
}
CAmount nValue;
@ -359,8 +359,8 @@ bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned i
while (pcursor->Valid()) {
std::pair<char, CTimestampIndexKey> key;
if (pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.timestamp <= high) {
hashes.push_back(key.second.blockHash);
if (pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.m_block_time <= high) {
hashes.push_back(key.second.m_block_hash);
pcursor->Next();
} else {
break;