From 1bd65a5c4bfebcc9a87a0f69b10b3711f8c79ec7 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/rpcmisc.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 8a8189c97..b4c7d8e24 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2132,7 +2132,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI 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()) { @@ -2142,7 +2142,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI 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; @@ -2523,7 +2523,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); @@ -2532,7 +2532,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 15ade067a..90ed55e92 100644 --- a/src/main.h +++ b/src/main.h @@ -399,6 +399,7 @@ struct CAddressUnspentKey { struct CAddressUnspentValue { CAmount satoshis; CScript script; + int blockHeight; ADD_SERIALIZE_METHODS; @@ -406,11 +407,13 @@ struct CAddressUnspentValue { inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(satoshis); READWRITE(*(CScriptBase*)(&script)); + READWRITE(blockHeight); } - CAddressUnspentValue(CAmount sats, CScript scriptPubKey) { + CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height) { satoshis = sats; script = scriptPubKey; + blockHeight = height; } CAddressUnspentValue() { @@ -420,6 +423,7 @@ struct CAddressUnspentValue { void SetNull() { satoshis = -1; script.clear(); + blockHeight = 0; } bool IsNull() const { diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 832d55f1a..ec0774660 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -431,8 +431,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) @@ -468,6 +471,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++) { @@ -478,6 +483,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); }