Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

IS-1230: getPReps returns error with high end ranking. #521

Merged
merged 4 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions iconservice/prep/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,28 +910,41 @@ def handle_get_preps(self,
prep_count: int = preps.size(active_prep_only=True)
prep_list: list = []

if startRanking is None:
startRanking = 1
start_ranking = 1 if startRanking is None else startRanking

if endRanking is None:
endRanking = prep_count
end_ranking = max(start_ranking, prep_count)
else:
end_ranking = endRanking

if not self._verify_rankings(start_ranking, end_ranking):
raise InvalidParamsException(
f"Invalid ranking: startRanking({start_ranking}), "
f"endRanking({end_ranking})"
)

if prep_count > 0:
if not 1 <= startRanking <= endRanking:
raise InvalidParamsException(
f"Invalid ranking: startRanking({startRanking}), endRanking({endRanking})")
for i in range(start_ranking - 1, end_ranking):
if i >= prep_count:
break

for i in range(startRanking - 1, endRanking):
prep: 'PRep' = preps.get_by_index(i)
prep_list.append(prep.to_dict(PRepDictType.FULL))
prep: 'PRep' = preps.get_by_index(i)
prep_list.append(prep.to_dict(PRepDictType.FULL))

return {
"blockHeight": context.block.height,
"startRanking": startRanking,
"startRanking": start_ranking,
"totalDelegated": preps.total_delegated,
"totalStake": context.storage.iiss.get_total_stake(context),
"preps": prep_list
}

@classmethod
def _verify_rankings(cls, start_ranking: int, end_ranking: int) -> bool:
if not (isinstance(start_ranking, int) and isinstance(end_ranking, int)):
return False

return 0 < start_ranking <= end_ranking

def handle_get_prep_term(self, context: 'IconScoreContext') -> dict:
"""Provides the information on the current term
"""
Expand Down
217 changes: 217 additions & 0 deletions tests/integrate_test/iiss/prevote/test_prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,220 @@ def check_query_via_icx_sendtransaction(self, method: str, params: dict, expecte
func_name=method,
params=params)
return self.process_confirm_block_tx([tx], expected_status=expected_status)

def test_get_preps_normal(self):
Copy link
Member

@goldworm-icon goldworm-icon Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to add the following test-cases

  1. startRanking or endRanking are less than zero
  2. startRanking is larger than # of PReps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

append test case.

pass case

  • normal
  • over endRanking than prep count

else:

  • reverse
  • overflow
  • zero
  • negative

self.init_decentralized()

start_ranking = 1
end_ranking = 10

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
"endRanking": hex(end_ranking),
}
}
}
ret = self._query(query_request)
self.assertEqual(start_ranking, ret["startRanking"])
self.assertEqual(end_ranking, len(ret["preps"]))

def test_get_preps_over_start_ranking(self):
self.init_decentralized()

start_ranking = 10_000
end_ranking = 10_000 + 1

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
"endRanking": hex(end_ranking),
}
}
}
ret = self._query(query_request)
self.assertEqual(start_ranking, ret["startRanking"])
self.assertEqual(0, len(ret["preps"]))

def test_get_preps_over_end_ranking(self):
self.init_decentralized()

start_ranking = 1
end_ranking = 10_000
expected_prep_count = 22

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
"endRanking": hex(end_ranking),
}
}
}
ret = self._query(query_request)
self.assertEqual(start_ranking, ret["startRanking"])
self.assertEqual(expected_prep_count, len(ret["preps"]))

def test_get_preps_raise_start_zero(self):
self.init_decentralized()

start_ranking = 0
end_ranking = 10

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
"endRanking": hex(end_ranking),
}
}
}

with self.assertRaises(InvalidParamsException) as e:
self._query(query_request)

self.assertEqual(e.exception.args[0], f"Invalid ranking: startRanking({start_ranking}), endRanking({end_ranking})")

def test_get_preps_raise_end_zero(self):
self.init_decentralized()

end_ranking = 0

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"endRanking": hex(end_ranking),
}
}
}

with self.assertRaises(InvalidParamsException) as e:
self._query(query_request)

self.assertEqual(e.exception.args[0], f"Invalid ranking: startRanking(1), endRanking({end_ranking})")

def test_get_preps_raise_reverse(self):
self.init_decentralized()

start_ranking = 10
end_ranking = 2

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
"endRanking": hex(end_ranking),
}
}
}

with self.assertRaises(InvalidParamsException) as e:
self._query(query_request)

self.assertEqual(e.exception.args[0], f"Invalid ranking: startRanking({start_ranking}), endRanking({end_ranking})")

def test_get_preps_raise_only_one(self):
self.init_decentralized()

start_ranking = 10
end_ranking = 10

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
"endRanking": hex(end_ranking),
}
}
}

ret = self._query(query_request)
self.assertEqual(start_ranking, ret["startRanking"])
self.assertEqual(1, len(ret["preps"]))

def test_get_preps_negative_start(self):
self.init_decentralized()

start_ranking = -10
expected_prep_count = 22

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"startRanking": hex(start_ranking),
}
}
}

with self.assertRaises(InvalidParamsException) as e:
self._query(query_request)

self.assertEqual(
e.exception.args[0],
f"Invalid ranking: startRanking({start_ranking}), endRanking({expected_prep_count})"
)

def test_get_preps_negative_end(self):
self.init_decentralized()

end_ranking = -20

query_request = {
"version": self._version,
"from": self._admin,
"to": SYSTEM_SCORE_ADDRESS,
"dataType": "call",
"data": {
"method": PRepMethod.GET_PREPS,
"params": {
"endRanking": hex(end_ranking),
}
}
}

with self.assertRaises(InvalidParamsException) as e:
self._query(query_request)

self.assertEqual(e.exception.args[0], f"Invalid ranking: startRanking(1), endRanking({end_ranking})")
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def test_system_score_intercall_getPReps(self):
response = self.query_score(from_=self._accounts[0],
to_=self.score_addr,
func_name="call_getPReps",
params={"startRanking": hex(0), "endRanking": hex(0)})
params={"startRanking": hex(1), "endRanking": hex(100)})
self.assertTrue("blockHeight" in response, response)
self.assertTrue("startRanking" in response, response)
self.assertTrue("totalDelegated" in response, response)
Expand Down