Skip to content

Commit

Permalink
committee v4 forward compatibility patch
Browse files Browse the repository at this point in the history
  • Loading branch information
gkaempfer committed Jun 28, 2022
1 parent 3cc351b commit 478b072
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
5 changes: 5 additions & 0 deletions committee/committee/availability_gateway_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ def _send_request(self, send_method, uri, data=None):
raise BadRequest(res.status_code, res.text)
return res.text

async def order_tree_height(self) -> int:
uri = "/availability_gateway/order_tree_height"
answer = await self._send_request("GET", uri)
return int(answer)

async def get_batch_data(self, batch_id: int) -> Optional[StateUpdate]:
uri = f'/availability_gateway/get_batch_data?batch_id={batch_id}'
answer = self._send_request('GET', uri)
Expand Down
41 changes: 37 additions & 4 deletions committee/committee/committee.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from starkware.storage.merkle_tree import MerkleTree
from starkware.storage.storage import Storage

from .availability_gateway_client import AvailabilityGatewayClient
from .availability_gateway_client import AvailabilityGatewayClient, BadRequest
from .custom_validation import is_valid

logger = logging.getLogger(__package__)
Expand All @@ -44,7 +44,8 @@ def deserialize(cls, data: bytes) -> 'CommitteeBatchInfo':

class Committee:
def __init__(self, config: dict, private_key: str, storage: Storage,
merkle_storage: Storage, hash_func, availability_gateway):
merkle_storage: Storage, hash_func,
availability_gateway: AvailabilityGatewayClient):
self.storage = storage
self.merkle_storage = merkle_storage
self.hash_func = hash_func
Expand Down Expand Up @@ -145,11 +146,43 @@ async def compute_order_root(storage):
await self.storage.set_value(
self.committee_batch_info_key(batch_id), batch_info.serialize())

# In StarkEx version 4.5, the height of the order tree has changed. For an old committee
# (i.e. a committee from version 4.0 or below) to work with a version 4.5 backend, the order
# tree height must be checked against the availability gateway, and possibly changed.
# If the configured height doesn't match the height sent in response from the availability
# gateway, assert that the order tree is not validated (self.validate_orders must be False
# to swap order tree heights, otherwise the computed order root is incorrect anyway) and
# that the new height is the expected height in version 4.5 (which is 251).
# This will work when the committee is not validating orders, because in that case, the root
# provided by the availability gateway is the correct root (of the height-251 tree), so when
# the committee blindly signs this root along with the correct height, the claim will be
# approved.
# This patch will be deleted in the version 4.5 committee.
logger.info("Trying to fetch trades height from the availability gateway")
# If the API of order_tree_height exist in the Availability Gateway use it. Otherwise,
# stick with the configured configured_trades_height (this can happen if the SE
# Availability Gateway is using an old SE version whcih don't have the
# order_tree_height API).
trades_height = self.orders_merkle_height
try:
trades_height = await self.availability_gateway.order_tree_height()
if self.orders_merkle_height != trades_height:
assert not validate_orders, (
f"validate_orders is {validate_orders}, but configured trades height "
f"{self.orders_merkle_height} is not equal to response from the availability "
f"gateway ({trades_height}). This indicates that the root of the order "
f"tree was computed incorrectly and the claim will not be approved by the "
f"availability gateway, so there is no point in signing and sending the "
f"signature."
)
except BadRequest:
pass

logger.info(f'Signing batch with sequence number {batch_info.sequence_number}')

availability_claim = hash_availability_claim(
batch_info.vaults_root, self.vaults_merkle_height, batch_info.orders_root,
self.orders_merkle_height, batch_info.sequence_number)
trades_height, batch_info.sequence_number)
signature = eth.Account._sign_hash(availability_claim, self.account.key).signature.hex()
return signature, availability_claim.hex()

Expand Down Expand Up @@ -221,4 +254,4 @@ async def async_hash_func(x, y):


if __name__ == '__main__':
sys.exit(asyncio.run(main()))
sys.exit(asyncio.run(main()))
15 changes: 13 additions & 2 deletions committee/committee/committee_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,22 @@
from .committee import Committee


ORDER_TREE_HEIGHT = 63


class AvailabilityGatewayClientMock:
def __init__(self):
pass

async def order_tree_height(self) -> int:
return ORDER_TREE_HEIGHT


@pytest.fixture
def committee():
config = {
'VAULTS_MERKLE_HEIGHT': 31,
'ORDERS_MERKLE_HEIGHT': 63,
'ORDERS_MERKLE_HEIGHT': ORDER_TREE_HEIGHT,
'POLLING_INTERVAL': 1,
}

Expand All @@ -24,7 +35,7 @@ def committee():
storage=MockStorage(),
merkle_storage=MockStorage(),
hash_func=async_pedersen_hash_func,
availability_gateway=None)
availability_gateway=AvailabilityGatewayClientMock())


@pytest.fixture
Expand Down

0 comments on commit 478b072

Please sign in to comment.