From e85d165115377c10435c8c6bad89e6f7385ef60b Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Wed, 30 Mar 2016 16:42:37 -0400 Subject: [PATCH] main: sort address index utxos by height --- qa/rpc-tests/addressindex.py | 15 +++++++++++++++ src/main.cpp | 8 ++++---- src/main.h | 6 +++++- src/rpc/misc.cpp | 8 +++++++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/addressindex.py b/qa/rpc-tests/addressindex.py index 703f3029a..ad79c7416 100755 --- a/qa/rpc-tests/addressindex.py +++ b/qa/rpc-tests/addressindex.py @@ -192,6 +192,21 @@ class AddressIndexTest(BitcoinTestFramework): assert_equal(len(utxos2), 1) assert_equal(utxos2[0]["satoshis"], 5000000000) + # Check sorting of utxos + self.nodes[2].generate(150) + + txidsort1 = self.nodes[2].sendtoaddress(address2, 50) + self.nodes[2].generate(1) + txidsort2 = self.nodes[2].sendtoaddress(address2, 50) + self.nodes[2].generate(1) + self.sync_all() + + utxos3 = self.nodes[1].getaddressutxos({"addresses": [address2]}) + assert_equal(len(utxos3), 3) + assert_equal(utxos3[0]["height"], 114) + assert_equal(utxos3[1]["height"], 264) + assert_equal(utxos3[2]["height"], 265) + print "Passed\n" diff --git a/src/main.cpp b/src/main.cpp index 25470caee..418c2cfd5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2357,7 +2357,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1)); // restore unspent index - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey))); + 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()) { @@ -2367,7 +2367,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, 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))); + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight))); } else { continue; @@ -2676,7 +2676,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue)); // record unspent output - addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey))); + 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()+3, out.scriptPubKey.begin()+23); @@ -2685,7 +2685,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, 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))); + addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight))); } else { continue; diff --git a/src/main.h b/src/main.h index 67a259e9c..c19f32718 100644 --- a/src/main.h +++ b/src/main.h @@ -377,6 +377,7 @@ struct CAddressUnspentKey { struct CAddressUnspentValue { CAmount satoshis; CScript script; + int blockHeight; ADD_SERIALIZE_METHODS; @@ -384,11 +385,13 @@ struct CAddressUnspentValue { inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(satoshis); READWRITE(script); + READWRITE(blockHeight); } - CAddressUnspentValue(CAmount sats, CScript scriptPubKey) { + CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height) { satoshis = sats; script = scriptPubKey; + blockHeight = height; } CAddressUnspentValue() { @@ -398,6 +401,7 @@ struct CAddressUnspentValue { void SetNull() { satoshis = -1; script.clear(); + blockHeight = 0; } bool IsNull() const { diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 09956d225..037842e2f 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -542,8 +542,11 @@ bool getAddressesFromParams(const UniValue& params, std::vector a, + std::pair b) { + return a.second.blockHeight < b.second.blockHeight; } UniValue getaddressutxos(const UniValue& params, bool fHelp) @@ -579,6 +582,8 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp) } } + std::sort(unspentOutputs.begin(), unspentOutputs.end(), heightSort); + UniValue result(UniValue::VARR); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { @@ -589,6 +594,7 @@ UniValue getaddressutxos(const UniValue& params, bool fHelp) output.push_back(Pair("outputIndex", it->first.index)); output.push_back(Pair("script", HexStr(it->second.script.begin(), it->second.script.end()))); output.push_back(Pair("satoshis", it->second.satoshis)); + output.push_back(Pair("height", it->second.blockHeight)); result.push_back(output); }