From fa7bf712a164da7020d62d4b7b0ce9b015913fc9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 26 Jun 2018 04:40:32 -1100 Subject: [PATCH] Add support for pay2pubkey for -addressindex --- src/main.cpp | 66 ++++++++++++++++++++++++++++++++------- src/rpcblockchain.cpp | 26 ++++++++++++--- src/rpcmisc.cpp | 6 +++- src/rpcrawtransaction.cpp | 6 +++- src/script/script.cpp | 8 +++++ src/script/script.h | 1 + src/txmempool.cpp | 36 ++++++++++++++++----- 7 files changed, 123 insertions(+), 26 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6aed822e5..5a1cdcd10 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2429,8 +2429,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // undo unspent index addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue())); - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + } + else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); // undo receiving activity addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue)); @@ -2438,7 +2439,18 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // undo unspent index addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue())); - } else { + } + else if (out.scriptPubKey.IsPayToPublicKey()) { + vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + + // undo receiving activity + addressIndex.push_back(make_pair(CAddressIndexKey(3, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue)); + + // undo unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(3, uint160(hashBytes), hash, k), CAddressUnspentValue())); + + } + else { continue; } @@ -2502,8 +2514,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight))); - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34); + } + else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23); // undo spending activity addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); @@ -2511,7 +2524,18 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // 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 { + } + else if (prevout.scriptPubKey.IsPayToPublicKey()) { + vector hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34); + + // undo spending activity + addressIndex.push_back(make_pair(CAddressIndexKey(3, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); + + // restore unspent index + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(3, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight))); + + } + else { continue; } } @@ -2783,10 +2807,16 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (prevout.scriptPubKey.IsPayToScriptHash()) { hashBytes = uint160(vector (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22)); addressType = 2; - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - hashBytes = uint160(vector (prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34)); + } + else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { + hashBytes = uint160(vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); addressType = 1; - } else { + } + else if (prevout.scriptPubKey.IsPayToPublicKey()) { + hashBytes = uint160(vector (prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34)); + addressType = 3; + } + else { hashBytes.SetNull(); addressType = 0; } @@ -2842,8 +2872,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // record unspent output addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + } + else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); // record receiving activity addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); @@ -2851,7 +2882,18 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // record unspent output addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); - } else { + } + else if (out.scriptPubKey.IsPayToPublicKey()) { + vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + + // record receiving activity + addressIndex.push_back(make_pair(CAddressIndexKey(3, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); + + // record unspent output + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(3, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); + + } + else { continue; } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 0a47339fa..ca9a21278 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -172,9 +172,14 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) if (GetSpentIndex(spentKey, spentInfo)) { if (spentInfo.addressType == 1) { delta.push_back(Pair("address", CBitcoinAddress(CKeyID(spentInfo.addressHash)).ToString())); - } else if (spentInfo.addressType == 2) { + } + else if (spentInfo.addressType == 2) { delta.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); - } else { + } + else if (spentInfo.addressType == 3) { + xxx delta.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); + } + else { continue; } delta.push_back(Pair("satoshis", -1 * spentInfo.satoshis)); @@ -203,10 +208,21 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); delta.push_back(Pair("address", CBitcoinAddress(CScriptID(uint160(hashBytes))).ToString())); - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + } + else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); delta.push_back(Pair("address", CBitcoinAddress(CKeyID(uint160(hashBytes))).ToString())); - } else { + } + else if (out.scriptPubKey.IsPayToPublicKey()) { + CTxDestination address; + if (ExtractDestination(out.scriptPubKey, address)) + { + //vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + //xxx delta.push_back(Pair("address", CBitcoinAddress(CKeyID(uint160(hashBytes))).ToString())); + delta.push_back(Pair("address", address.ToString())); + } + } + else { continue; } diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 3cc18c6a6..67518c09c 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -603,7 +603,11 @@ bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &addr address = CBitcoinAddress(CScriptID(hash)).ToString(); } else if (type == 1) { address = CBitcoinAddress(CKeyID(hash)).ToString(); - } else { + } + else if (type == 3) { + xxx address = CBitcoinAddress(CKeyID(hash)).ToString(); + } + else { return false; } return true; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 91dff8bf9..ff6df3505 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -161,9 +161,13 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& in.push_back(Pair("valueSat", spentInfo.satoshis)); if (spentInfo.addressType == 1) { in.push_back(Pair("address", CBitcoinAddress(CKeyID(spentInfo.addressHash)).ToString())); - } else if (spentInfo.addressType == 2) { + } + else if (spentInfo.addressType == 2) { in.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); } + else if (spentInfo.addressType == 3) { + xxx in.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); + } } } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); diff --git a/src/script/script.cpp b/src/script/script.cpp index 160c57016..4cffc6c5a 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -229,6 +229,14 @@ bool CScript::IsPayToPublicKeyHash() const (*this)[24] == OP_CHECKSIG); } +bool CScript::IsPayToPublicKey() const +{ + // Extra-fast test for pay-to-pubkey CScripts: + return (this->size() == 35 && + (*this)[0] == 33 && + (*this)[34] == OP_CHECKSIG); +} + bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: diff --git a/src/script/script.h b/src/script/script.h index 864a92f1f..56d2ff0b6 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -567,6 +567,7 @@ public: unsigned int GetSigOpCount(const CScript& scriptSig) const; bool IsPayToPublicKeyHash() const; + bool IsPayToPublicKey() const; bool IsPayToScriptHash() const; bool IsPayToCryptoCondition() const; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index c7dafb5f4..67e79b5cf 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -137,13 +137,21 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC 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 hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34); + } + else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { + vector 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 hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34); + CMempoolAddressDeltaKey key(3, 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++) { @@ -153,13 +161,21 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC CMempoolAddressDeltaKey key(2, uint160(hashBytes), txhash, k, 0); mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); inserted.push_back(key); - } else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + } + else if (out.scriptPubKey.IsPayToPublicKeyHash()) { + vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); std::pair ret; CMempoolAddressDeltaKey key(1, uint160(hashBytes), txhash, k, 0); mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); inserted.push_back(key); } + else if (out.scriptPubKey.IsPayToPublicKey()) { + vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); + std::pair ret; + CMempoolAddressDeltaKey key(3, Hash160(hashBytes), txhash, k, 0); + mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue))); + inserted.push_back(key); + } } mapAddressInserted.insert(make_pair(txhash, inserted)); @@ -212,10 +228,16 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac if (prevout.scriptPubKey.IsPayToScriptHash()) { addressHash = uint160(vector (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22)); addressType = 2; - } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { - addressHash = uint160(vector (prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34)); + } + else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) { + addressHash = uint160(vector (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23)); addressType = 1; - } else { + } + else if (prevout.scriptPubKey.IsPayToPublicKey()) { + addressHash = Hash160(vector (prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34)); + addressType = 3; + } + else { addressHash.SetNull(); addressType = 0; }