From 11b882879a449f23e29b619c6e3e50a1d1c4cbc3 Mon Sep 17 00:00:00 2001 From: Sergey Rozhnov Date: Fri, 25 May 2018 11:09:13 +0400 Subject: [PATCH] predictable result sorting for `claim_list` and `claim_list_mine` --- CHANGELOG.md | 1 + lbrynet/daemon/Daemon.py | 8 +++- .../unit/daemon/test_claims_comparator.py | 43 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 lbrynet/tests/unit/daemon/test_claims_comparator.py diff --git a/CHANGELOG.md b/CHANGELOG.md index b94d5fd44..e8590e6ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ at anytime. * download blockchain headers from s3 before starting the wallet when the local height is more than `s3_headers_depth` (a config setting) blocks behind * track successful reflector uploads in sqlite to minimize how many streams are attempted by auto re-reflect * increase the default `auto_re_reflect_interval` to a day + * predictable result sorting for `claim_list` and `claim_list_mine` ### Added * virtual kademlia network and mock udp transport for dht integration tests diff --git a/lbrynet/daemon/Daemon.py b/lbrynet/daemon/Daemon.py index 43c67e0d7..77f4790d2 100644 --- a/lbrynet/daemon/Daemon.py +++ b/lbrynet/daemon/Daemon.py @@ -163,6 +163,11 @@ class AlwaysSend(object): return d +def sort_claim_results(claims): + claims.sort(key=lambda d: (d['height'], d['name'], d['claim_id'], d['txid'], d['nout'])) + return claims + + class Daemon(AuthJSONRPCServer): """ LBRYnet daemon, a jsonrpc interface to lbry functions @@ -2330,7 +2335,8 @@ class Daemon(AuthJSONRPCServer): } """ - claims = yield self.session.wallet.get_claims_for_name(name) + claims = yield self.session.wallet.get_claims_for_name(name) # type: dict + sort_claim_results(claims['claims']) defer.returnValue(claims) @defer.inlineCallbacks diff --git a/lbrynet/tests/unit/daemon/test_claims_comparator.py b/lbrynet/tests/unit/daemon/test_claims_comparator.py new file mode 100644 index 000000000..4a4333aba --- /dev/null +++ b/lbrynet/tests/unit/daemon/test_claims_comparator.py @@ -0,0 +1,43 @@ +import unittest + +from lbrynet.daemon.Daemon import sort_claim_results + + +class ClaimsComparatorTest(unittest.TestCase): + def test_sort_claim_results_when_sorted_by_claim_id(self): + results = [{"height": 1, "name": "res", "claim_id": "ccc", "nout": 0, "txid": "fdsafa"}, + {"height": 1, "name": "res", "claim_id": "aaa", "nout": 0, "txid": "w5tv8uorgt"}, + {"height": 1, "name": "res", "claim_id": "bbb", "nout": 0, "txid": "aecfaewcfa"}] + self.run_test(results, 'claim_id', ['aaa', 'bbb', 'ccc']) + + def test_sort_claim_results_when_sorted_by_height(self): + results = [{"height": 1, "name": "res", "claim_id": "ccc", "nout": 0, "txid": "aecfaewcfa"}, + {"height": 3, "name": "res", "claim_id": "ccc", "nout": 0, "txid": "aecfaewcfa"}, + {"height": 2, "name": "res", "claim_id": "ccc", "nout": 0, "txid": "aecfaewcfa"}] + self.run_test(results, 'height', [1, 2, 3]) + + def test_sort_claim_results_when_sorted_by_name(self): + results = [{"height": 1, "name": "res1", "claim_id": "ccc", "nout": 0, "txid": "aecfaewcfa"}, + {"height": 1, "name": "res3", "claim_id": "ccc", "nout": 0, "txid": "aecfaewcfa"}, + {"height": 1, "name": "res2", "claim_id": "ccc", "nout": 0, "txid": "aecfaewcfa"}] + self.run_test(results, 'name', ['res1', 'res2', 'res3']) + + def test_sort_claim_results_when_sorted_by_txid(self): + results = [{"height": 1, "name": "res1", "claim_id": "ccc", "nout": 2, "txid": "111"}, + {"height": 1, "name": "res1", "claim_id": "ccc", "nout": 1, "txid": "222"}, + {"height": 1, "name": "res1", "claim_id": "ccc", "nout": 3, "txid": "333"}] + self.run_test(results, 'txid', ['111', '222', '333']) + + def test_sort_claim_results_when_sorted_by_nout(self): + results = [{"height": 1, "name": "res1", "claim_id": "ccc", "nout": 2, "txid": "aecfaewcfa"}, + {"height": 1, "name": "res1", "claim_id": "ccc", "nout": 1, "txid": "aecfaewcfa"}, + {"height": 1, "name": "res1", "claim_id": "ccc", "nout": 3, "txid": "aecfaewcfa"}] + self.run_test(results, 'nout', [1, 2, 3]) + + def run_test(self, results, field, expected): + actual = sort_claim_results(results) + self.assertEqual(expected, [r[field] for r in actual]) + + +if __name__ == '__main__': + unittest.main()