Merge pull request #967 from miketout/dev-komodo
Fix index db iterators
This commit is contained in:
@@ -123,6 +123,16 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetKeyDataStream(CDataStream &ssKey) {
|
||||||
|
leveldb::Slice slKey = piter->key();
|
||||||
|
try {
|
||||||
|
ssKey = CDataStream(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
|
||||||
|
} catch(std::exception &e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int GetKeySize() {
|
unsigned int GetKeySize() {
|
||||||
return piter->key().size();
|
return piter->key().size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1636,15 +1636,13 @@ uint64_t komodo_ac_block_subsidy(int nHeight)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( nHeight == 1 )
|
if ( nHeight == 1 )
|
||||||
|
{
|
||||||
|
uint32_t magicExtra = ASSETCHAINS_STAKED ? ASSETCHAINS_MAGIC : (ASSETCHAINS_MAGIC & 0xffffff);
|
||||||
if ( ASSETCHAINS_LASTERA == 0 )
|
if ( ASSETCHAINS_LASTERA == 0 )
|
||||||
{
|
subsidy = ASSETCHAINS_SUPPLY * SATOSHIDEN + magicExtra;
|
||||||
if ( ASSETCHAINS_STAKED == 0 )
|
|
||||||
subsidy = ASSETCHAINS_SUPPLY * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff);
|
|
||||||
else subsidy = ASSETCHAINS_SUPPLY * SATOSHIDEN + ASSETCHAINS_MAGIC;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
subsidy += ASSETCHAINS_SUPPLY * SATOSHIDEN + (ASSETCHAINS_MAGIC & 0xffffff);
|
subsidy += ASSETCHAINS_SUPPLY * SATOSHIDEN + magicExtra;
|
||||||
|
}
|
||||||
return(subsidy);
|
return(subsidy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
266
src/main.cpp
266
src/main.cpp
@@ -2844,52 +2844,31 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||||||
for (unsigned int k = tx.vout.size(); k-- > 0;) {
|
for (unsigned int k = tx.vout.size(); k-- > 0;) {
|
||||||
const CTxOut &out = tx.vout[k];
|
const CTxOut &out = tx.vout[k];
|
||||||
|
|
||||||
if (out.scriptPubKey.IsPayToScriptHash()) {
|
vector<vector<unsigned char>> vSols;
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
CTxDestination vDest;
|
||||||
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
// undo receiving activity
|
int keyType = 1;
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
|
if ((Solver(out.scriptPubKey, txType, vSols) || ExtractDestination(out.scriptPubKey, vDest)) && txType != TX_MULTISIG) {
|
||||||
|
if (vDest.which())
|
||||||
// undo unspent index
|
{
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
|
CKeyID kid;
|
||||||
|
if (CBitcoinAddress(vDest).GetKeyID(kid))
|
||||||
|
{
|
||||||
|
vSols.push_back(vector<unsigned char>(kid.begin(), kid.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (txType == TX_SCRIPTHASH)
|
||||||
|
{
|
||||||
|
keyType = 2;
|
||||||
|
}
|
||||||
|
for (auto addr : vSols)
|
||||||
|
{
|
||||||
|
uint160 addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr);
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, hash, k, false), out.nValue));
|
||||||
|
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, hash, k), CAddressUnspentValue()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
|
||||||
|
|
||||||
// undo receiving activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// undo unspent index
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (out.scriptPubKey.IsPayToPublicKey()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
|
|
||||||
|
|
||||||
// undo receiving activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// undo unspent index
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (out.scriptPubKey.IsPayToCryptoCondition()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
|
|
||||||
|
|
||||||
// undo receiving activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// undo unspent index
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all outputs are available and match the outputs in the block itself
|
// Check that all outputs are available and match the outputs in the block itself
|
||||||
@@ -2934,49 +2913,36 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
|||||||
|
|
||||||
if (fAddressIndex) {
|
if (fAddressIndex) {
|
||||||
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
|
||||||
|
|
||||||
// undo spending activity
|
vector<vector<unsigned char>> vSols;
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
CTxDestination vDest;
|
||||||
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
|
int keyType = 1;
|
||||||
|
// some non-standard types, like time lock coinbases, don't solve, but do extract
|
||||||
|
if ((Solver(prevout.scriptPubKey, txType, vSols) || ExtractDestination(prevout.scriptPubKey, vDest)))
|
||||||
|
{
|
||||||
|
// if we failed to solve, and got a vDest, assume P2PKH or P2PK address returned
|
||||||
|
if (vDest.which())
|
||||||
|
{
|
||||||
|
CKeyID kid;
|
||||||
|
if (CBitcoinAddress(vDest).GetKeyID(kid))
|
||||||
|
{
|
||||||
|
vSols.push_back(vector<unsigned char>(kid.begin(), kid.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (txType == TX_SCRIPTHASH)
|
||||||
|
{
|
||||||
|
keyType = 2;
|
||||||
|
}
|
||||||
|
for (auto addr : vSols)
|
||||||
|
{
|
||||||
|
uint160 addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr);
|
||||||
|
// undo spending activity
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
||||||
|
|
||||||
// restore unspent index
|
// restore unspent index
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
|
||||||
|
|
||||||
// undo spending activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
|
||||||
|
|
||||||
// restore unspent index
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKey()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
|
|
||||||
|
|
||||||
// undo spending activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
|
||||||
|
|
||||||
// restore unspent index
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
|
|
||||||
|
|
||||||
// undo spending activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
|
|
||||||
|
|
||||||
// restore unspent index
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3269,45 +3235,47 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
|
|
||||||
const CTxIn input = tx.vin[j];
|
const CTxIn input = tx.vin[j];
|
||||||
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
||||||
uint160 hashBytes;
|
|
||||||
int addressType;
|
|
||||||
|
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
vector<vector<unsigned char>> vSols;
|
||||||
hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
|
CTxDestination vDest;
|
||||||
addressType = 2;
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
}
|
uint160 addrHash;
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
int keyType = 0;
|
||||||
hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
|
// some non-standard types, like time lock coinbases, don't solve, but do extract
|
||||||
addressType = 1;
|
if ((Solver(prevout.scriptPubKey, txType, vSols) || ExtractDestination(prevout.scriptPubKey, vDest)))
|
||||||
}
|
{
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKey()) {
|
keyType = 1;
|
||||||
hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
|
|
||||||
addressType = 1;
|
|
||||||
}
|
|
||||||
else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
|
|
||||||
hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
|
|
||||||
addressType = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hashBytes.SetNull();
|
|
||||||
addressType = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fAddressIndex && addressType > 0) {
|
// if we failed to solve, and got a vDest, assume P2PKH or P2PK address returned
|
||||||
// record spending activity
|
if (vDest.which())
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->GetHeight(), i, txhash, j, true), prevout.nValue * -1));
|
{
|
||||||
|
CKeyID kid;
|
||||||
|
if (CBitcoinAddress(vDest).GetKeyID(kid))
|
||||||
|
{
|
||||||
|
vSols.push_back(vector<unsigned char>(kid.begin(), kid.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (txType == TX_SCRIPTHASH)
|
||||||
|
{
|
||||||
|
keyType = 2;
|
||||||
|
}
|
||||||
|
for (auto addr : vSols)
|
||||||
|
{
|
||||||
|
addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr);
|
||||||
|
// record spending activity
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, txhash, j, true), prevout.nValue * -1));
|
||||||
|
|
||||||
// remove address from unspent index
|
// remove address from unspent index
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
|
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fSpentIndex) {
|
if (fSpentIndex) {
|
||||||
// add the spent index to determine the txid and input that spent an output
|
// add the spent index to determine the txid and input that spent an output
|
||||||
// and to find the amount and address from an input
|
// and to find the amount and address from an input
|
||||||
spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->GetHeight(), prevout.nValue, addressType, hashBytes)));
|
spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->GetHeight(), prevout.nValue, keyType, addrHash)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Add in sigops done by pay-to-script-hash inputs;
|
// Add in sigops done by pay-to-script-hash inputs;
|
||||||
// this is to prevent a "rogue miner" from creating
|
// this is to prevent a "rogue miner" from creating
|
||||||
@@ -3334,51 +3302,39 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
if (fAddressIndex) {
|
if (fAddressIndex) {
|
||||||
for (unsigned int k = 0; k < tx.vout.size(); k++) {
|
for (unsigned int k = 0; k < tx.vout.size(); k++) {
|
||||||
const CTxOut &out = tx.vout[k];
|
const CTxOut &out = tx.vout[k];
|
||||||
//fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
|
|
||||||
if (out.scriptPubKey.IsPayToScriptHash()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
|
||||||
|
|
||||||
// record receiving activity
|
uint160 addrHash;
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// record unspent output
|
vector<vector<unsigned char>> vSols;
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
|
CTxDestination vDest;
|
||||||
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
|
int keyType = 1;
|
||||||
|
// some non-standard types, like time lock coinbases, don't solve, but do extract
|
||||||
|
if ((Solver(out.scriptPubKey, txType, vSols) || ExtractDestination(out.scriptPubKey, vDest)) && txType != TX_MULTISIG)
|
||||||
|
{
|
||||||
|
// if we failed to solve, and got a vDest, assume P2PKH or P2PK address returned
|
||||||
|
if (vDest.which())
|
||||||
|
{
|
||||||
|
CKeyID kid;
|
||||||
|
if (CBitcoinAddress(vDest).GetKeyID(kid))
|
||||||
|
{
|
||||||
|
vSols.push_back(vector<unsigned char>(kid.begin(), kid.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (txType == TX_SCRIPTHASH)
|
||||||
|
{
|
||||||
|
keyType = 2;
|
||||||
|
}
|
||||||
|
for (auto addr : vSols)
|
||||||
|
{
|
||||||
|
addrHash = addr.size() == 20 ? uint160(addr) : Hash160(addr);
|
||||||
|
// record receiving activity
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(keyType, addrHash, pindex->GetHeight(), i, txhash, k, false), out.nValue));
|
||||||
|
|
||||||
|
// record unspent output
|
||||||
|
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(keyType, addrHash, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
|
||||||
|
|
||||||
// record receiving activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// record unspent output
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (out.scriptPubKey.IsPayToPublicKey()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
|
|
||||||
|
|
||||||
// record receiving activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// record unspent output
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (out.scriptPubKey.IsPayToCryptoCondition()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
|
|
||||||
|
|
||||||
// record receiving activity
|
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
|
|
||||||
|
|
||||||
// record unspent output
|
|
||||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
62
src/txdb.cpp
62
src/txdb.cpp
@@ -332,27 +332,21 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, int type,
|
|||||||
|
|
||||||
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
||||||
|
|
||||||
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
|
pcursor->Seek(make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash)));
|
||||||
ssKeySet << make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash));
|
|
||||||
pcursor->Seek(ssKeySet.str());
|
|
||||||
|
|
||||||
while (pcursor->Valid()) {
|
while (pcursor->Valid()) {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
try {
|
try {
|
||||||
std::vector<unsigned char> slKey = std::vector<unsigned char>();
|
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||||
pcursor->GetKey(slKey);
|
pair<char, CAddressUnspentKey> keyObj;
|
||||||
CDataStream ssKey(slKey, SER_DISK, CLIENT_VERSION);
|
pcursor->GetKey(keyObj);
|
||||||
char chType;
|
char chType = keyObj.first;
|
||||||
CAddressUnspentKey indexKey;
|
CAddressUnspentKey indexKey = keyObj.second;
|
||||||
ssKey >> chType;
|
|
||||||
ssKey >> indexKey;
|
|
||||||
if (chType == DB_ADDRESSUNSPENTINDEX && indexKey.hashBytes == addressHash) {
|
if (chType == DB_ADDRESSUNSPENTINDEX && indexKey.hashBytes == addressHash) {
|
||||||
try {
|
try {
|
||||||
std::vector<unsigned char> slValue = std::vector<unsigned char>();
|
|
||||||
pcursor->GetValue(slValue);
|
|
||||||
CDataStream ssValue(slValue, SER_DISK, CLIENT_VERSION);
|
|
||||||
CAddressUnspentValue nValue;
|
CAddressUnspentValue nValue;
|
||||||
ssValue >> nValue;
|
pcursor->GetValue(nValue);
|
||||||
unspentOutputs.push_back(make_pair(indexKey, nValue));
|
unspentOutputs.push_back(make_pair(indexKey, nValue));
|
||||||
pcursor->Next();
|
pcursor->Next();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
@@ -365,7 +359,6 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, int type,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,34 +382,27 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type,
|
|||||||
|
|
||||||
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
||||||
|
|
||||||
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
|
|
||||||
if (start > 0 && end > 0) {
|
if (start > 0 && end > 0) {
|
||||||
ssKeySet << make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorHeightKey(type, addressHash, start));
|
pcursor->Seek(make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorHeightKey(type, addressHash, start)));
|
||||||
} else {
|
} else {
|
||||||
ssKeySet << make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorKey(type, addressHash));
|
pcursor->Seek(make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorKey(type, addressHash)));
|
||||||
}
|
}
|
||||||
pcursor->Seek(ssKeySet.str());
|
|
||||||
|
|
||||||
while (pcursor->Valid()) {
|
while (pcursor->Valid()) {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
try {
|
try {
|
||||||
std::vector<unsigned char> slKey = std::vector<unsigned char>();
|
pair<char, CAddressIndexKey> keyObj;
|
||||||
pcursor->GetKey(slKey);
|
pcursor->GetKey(keyObj);
|
||||||
CDataStream ssKey(slKey, SER_DISK, CLIENT_VERSION);
|
char chType = keyObj.first;
|
||||||
char chType;
|
CAddressIndexKey indexKey = keyObj.second;
|
||||||
CAddressIndexKey indexKey;
|
|
||||||
ssKey >> chType;
|
|
||||||
ssKey >> indexKey;
|
|
||||||
if (chType == DB_ADDRESSINDEX && indexKey.hashBytes == addressHash) {
|
if (chType == DB_ADDRESSINDEX && indexKey.hashBytes == addressHash) {
|
||||||
if (end > 0 && indexKey.blockHeight > end) {
|
if (end > 0 && indexKey.blockHeight > end) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
std::vector<unsigned char> slValue = std::vector<unsigned char>();
|
|
||||||
pcursor->GetValue(slValue);
|
|
||||||
CDataStream ssValue(slValue, SER_DISK, CLIENT_VERSION);
|
|
||||||
CAmount nValue;
|
CAmount nValue;
|
||||||
ssValue >> nValue;
|
pcursor->GetValue(nValue);
|
||||||
|
|
||||||
addressIndex.push_back(make_pair(indexKey, nValue));
|
addressIndex.push_back(make_pair(indexKey, nValue));
|
||||||
pcursor->Next();
|
pcursor->Next();
|
||||||
@@ -584,20 +570,16 @@ bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned i
|
|||||||
|
|
||||||
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
||||||
|
|
||||||
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
|
pcursor->Seek(make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low)));
|
||||||
ssKeySet << make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low));
|
|
||||||
pcursor->Seek(ssKeySet.str());
|
|
||||||
|
|
||||||
while (pcursor->Valid()) {
|
while (pcursor->Valid()) {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
try {
|
try {
|
||||||
std::vector<unsigned char> slKey = std::vector<unsigned char>();
|
pair<char, CTimestampIndexKey> keyObj;
|
||||||
pcursor->GetKey(slKey);
|
pcursor->GetKey(keyObj);
|
||||||
CDataStream ssKey(slKey, SER_DISK, CLIENT_VERSION);
|
char chType = keyObj.first;
|
||||||
char chType;
|
CTimestampIndexKey indexKey = keyObj.second;
|
||||||
CTimestampIndexKey indexKey;
|
|
||||||
ssKey >> chType;
|
|
||||||
ssKey >> indexKey;
|
|
||||||
if (chType == DB_TIMESTAMPINDEX && indexKey.timestamp < high) {
|
if (chType == DB_TIMESTAMPINDEX && indexKey.timestamp < high) {
|
||||||
if (fActiveOnly) {
|
if (fActiveOnly) {
|
||||||
if (blockOnchainActive(indexKey.blockHash)) {
|
if (blockOnchainActive(indexKey.blockHash)) {
|
||||||
|
|||||||
@@ -134,63 +134,64 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
|
|||||||
for (unsigned int j = 0; j < tx.vin.size(); j++) {
|
for (unsigned int j = 0; j < tx.vin.size(); j++) {
|
||||||
const CTxIn input = tx.vin[j];
|
const CTxIn input = tx.vin[j];
|
||||||
const CTxOut &prevout = view.GetOutputFor(input);
|
const CTxOut &prevout = view.GetOutputFor(input);
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
vector<vector<unsigned char>> vSols;
|
||||||
CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, j, 1);
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
int keyType = 1;
|
||||||
mapAddress.insert(make_pair(key, delta));
|
|
||||||
inserted.push_back(key);
|
CTxDestination vDest;
|
||||||
|
if (Solver(prevout.scriptPubKey, txType, vSols) || ExtractDestination(prevout.scriptPubKey, vDest))
|
||||||
|
{
|
||||||
|
if (vDest.which())
|
||||||
|
{
|
||||||
|
uint160 hashBytes;
|
||||||
|
if (CBitcoinAddress(vDest).GetIndexKey(hashBytes, keyType))
|
||||||
|
{
|
||||||
|
vSols.push_back(vector<unsigned char>(hashBytes.begin(), hashBytes.end()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (txType == TX_SCRIPTHASH)
|
||||||
|
{
|
||||||
|
keyType = 2;
|
||||||
|
}
|
||||||
|
for (auto addr : vSols)
|
||||||
|
{
|
||||||
|
CMempoolAddressDeltaKey key(keyType, addr.size() == 20 ? uint160(addr) : Hash160(addr), txhash, j, true);
|
||||||
|
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
||||||
|
mapAddress.insert(make_pair(key, delta));
|
||||||
|
inserted.push_back(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
}
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
|
||||||
CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, j, 1);
|
|
||||||
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
|
||||||
mapAddress.insert(make_pair(key, delta));
|
|
||||||
inserted.push_back(key);
|
|
||||||
}
|
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKey()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
|
|
||||||
CMempoolAddressDeltaKey key(1, Hash160(hashBytes), txhash, j, 1);
|
|
||||||
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
|
||||||
mapAddress.insert(make_pair(key, delta));
|
|
||||||
inserted.push_back(key);
|
|
||||||
}
|
|
||||||
else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
|
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
|
|
||||||
CMempoolAddressDeltaKey key(1, Hash160(hashBytes), txhash, j, 1);
|
|
||||||
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
|
|
||||||
mapAddress.insert(make_pair(key, delta));
|
|
||||||
inserted.push_back(key);
|
|
||||||
} }
|
|
||||||
|
|
||||||
for (unsigned int k = 0; k < tx.vout.size(); k++) {
|
for (unsigned int k = 0; k < tx.vout.size(); k++) {
|
||||||
const CTxOut &out = tx.vout[k];
|
const CTxOut &out = tx.vout[k];
|
||||||
if (out.scriptPubKey.IsPayToScriptHash()) {
|
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
vector<vector<unsigned char>> vSols;
|
||||||
CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, 0);
|
CTxDestination vDest;
|
||||||
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
inserted.push_back(key);
|
int keyType = 1;
|
||||||
}
|
if ((Solver(out.scriptPubKey, txType, vSols) || ExtractDestination(out.scriptPubKey, vDest)) && txType != TX_MULTISIG)
|
||||||
else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
{
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
// if we failed to solve, and got a vDest, assume P2PKH or P2PK address returned
|
||||||
std::pair<addressDeltaMap::iterator,bool> ret;
|
if (vDest.which())
|
||||||
CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, 0);
|
{
|
||||||
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
uint160 hashBytes;
|
||||||
inserted.push_back(key);
|
if (CBitcoinAddress(vDest).GetIndexKey(hashBytes, keyType))
|
||||||
}
|
{
|
||||||
else if (out.scriptPubKey.IsPayToPublicKey()) {
|
vSols.push_back(vector<unsigned char>(hashBytes.begin(), hashBytes.end()));
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
|
}
|
||||||
std::pair<addressDeltaMap::iterator,bool> ret;
|
}
|
||||||
CMempoolAddressDeltaKey key(1, Hash160(hashBytes), txhash, k, 0);
|
else if (txType == TX_SCRIPTHASH)
|
||||||
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
{
|
||||||
inserted.push_back(key);
|
keyType = 2;
|
||||||
}
|
}
|
||||||
else if (out.scriptPubKey.IsPayToCryptoCondition()) {
|
for (auto addr : vSols)
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
|
{
|
||||||
std::pair<addressDeltaMap::iterator,bool> ret;
|
CMempoolAddressDeltaKey key(keyType, addr.size() == 20 ? uint160(addr) : Hash160(addr), txhash, k, 0);
|
||||||
CMempoolAddressDeltaKey key(1, Hash160(hashBytes), txhash, k, 0);
|
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
||||||
mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
|
inserted.push_back(key);
|
||||||
inserted.push_back(key);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,38 +239,46 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac
|
|||||||
for (unsigned int j = 0; j < tx.vin.size(); j++) {
|
for (unsigned int j = 0; j < tx.vin.size(); j++) {
|
||||||
const CTxIn input = tx.vin[j];
|
const CTxIn input = tx.vin[j];
|
||||||
const CTxOut &prevout = view.GetOutputFor(input);
|
const CTxOut &prevout = view.GetOutputFor(input);
|
||||||
uint160 addressHash;
|
|
||||||
int addressType;
|
|
||||||
|
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
vector<vector<unsigned char>> vSols;
|
||||||
addressHash = uint160(vector<unsigned char> (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
|
CTxDestination vDest;
|
||||||
addressType = 2;
|
txnouttype txType = TX_PUBKEYHASH;
|
||||||
}
|
int keyType = 1;
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
// some non-standard types, like time lock coinbases, don't solve, but do extract
|
||||||
addressHash = uint160(vector<unsigned char> (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
|
if ((Solver(prevout.scriptPubKey, txType, vSols) || ExtractDestination(prevout.scriptPubKey, vDest)) && txType != TX_MULTISIG)
|
||||||
addressType = 1;
|
{
|
||||||
}
|
// if we failed to solve, and got a vDest, assume P2PKH or P2PK address returned
|
||||||
else if (prevout.scriptPubKey.IsPayToPublicKey()) {
|
if (vDest.which())
|
||||||
addressHash = Hash160(vector<unsigned char> (prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
|
{
|
||||||
addressType = 1;
|
CKeyID kid;
|
||||||
}
|
if (CBitcoinAddress(vDest).GetKeyID(kid))
|
||||||
else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
|
{
|
||||||
addressHash = Hash160(vector<unsigned char> (prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
|
vSols.push_back(vector<unsigned char>(kid.begin(), kid.end()));
|
||||||
addressType = 1;
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (txType == TX_SCRIPTHASH)
|
||||||
addressHash.SetNull();
|
{
|
||||||
addressType = 0;
|
keyType = 2;
|
||||||
}
|
}
|
||||||
|
for (auto addr : vSols)
|
||||||
|
{
|
||||||
|
CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n);
|
||||||
|
CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, keyType, addr.size() == 20 ? uint160(addr) : Hash160(addr));
|
||||||
|
|
||||||
CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n);
|
mapSpent.insert(make_pair(key, value));
|
||||||
CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, addressType, addressHash);
|
inserted.push_back(key);
|
||||||
|
}
|
||||||
mapSpent.insert(make_pair(key, value));
|
}
|
||||||
inserted.push_back(key);
|
else
|
||||||
|
{
|
||||||
|
// don't know exactly how, but it was spent
|
||||||
|
CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n);
|
||||||
|
CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, 0, uint160());
|
||||||
|
|
||||||
|
mapSpent.insert(make_pair(key, value));
|
||||||
|
inserted.push_back(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapSpentInserted.insert(make_pair(txhash, inserted));
|
mapSpentInserted.insert(make_pair(txhash, inserted));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user