Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
liav-certora committed Jan 7, 2025
1 parent 2da7c16 commit db68698
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 22 deletions.
6 changes: 3 additions & 3 deletions Quorum/apis/governance/data_models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Optional
from typing import Optional
from pydantic import BaseModel, Field

from Quorum.utils.chain_enum import Chain
Expand Down Expand Up @@ -49,9 +49,9 @@ class BGDProposalData(BaseModel):
"""
ipfs: Optional[IPFSData] = None
proposal: Optional[ProposalData] = None
events: List[EventData] = Field(default_factory=list)
events: list[EventData] = Field(default_factory=list)


class PayloadAddresses(BaseModel):
chain: Chain
addresses: List[str]
addresses: list[str]
40 changes: 32 additions & 8 deletions Quorum/checks/proposal_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ class CustomerConfig(BaseModel):
customer: str
payload_addresses: list[PayloadAddresses]

def __str__(self):
s = f'Customer: {self.customer}\nChains and payloads:\n'
for pa in self.payload_addresses:
if len(pa.addresses) == 0:
continue
s += f'* {pa.chain}:\n'
for address in pa.addresses:
s += f'\t- {address}\n'
return s


class ProposalConfig(BaseModel):
customers_config: list[CustomerConfig]
Expand All @@ -38,12 +48,16 @@ def run_customer_proposal_validation(prop_config: ProposalConfig) -> None:
>>> run_batch(prop_config)
"""
for config in prop_config.customers_config:
pp.pprint('Run Preparation', pp.Colors.INFO, pp.Heading.HEADING_1)
ground_truth_config = ConfigLoader.load_customer_config(config.customer)

git_manager = GitManager(config.customer, ground_truth_config)
git_manager.clone_or_update()

price_feed_providers = ground_truth_config.get("price_feed_providers", [])
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

pp.pprint('Run Metadata', pp.Colors.INFO, pp.Heading.HEADING_2)
pp.pprint(str(config), pp.Colors.INFO)
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

for pa in config.payload_addresses:
proposals_check(
Expand All @@ -54,7 +68,6 @@ def run_customer_proposal_validation(prop_config: ProposalConfig) -> None:
)



def proposals_check(customer: str, chain: Chain, proposal_addresses: list[str], providers: list[PriceFeedProviderBase]) -> None:
"""
Check and compare source code files for given proposals.
Expand All @@ -69,34 +82,45 @@ def proposals_check(customer: str, chain: Chain, proposal_addresses: list[str],
"""
api = ChainAPI(chain)

pp.pretty_print(f"Processing customer {customer}, for chain: {chain}", pp.Colors.INFO)
for proposal_address in proposal_addresses:
pp.pretty_print(f"Processing proposal {proposal_address}", pp.Colors.INFO)
pp.pprint(f'Analyzing payload {proposal_address} on {chain}', pp.Colors.INFO, pp.Heading.HEADING_1)

try:
source_codes = api.get_source_code(proposal_address)
except ValueError as e:
except ValueError:
error_message = (
f"Payload address {proposal_address} is not verified on {chain.name} explorer.\n"
"We do not recommend to approve this proposal until the code is approved!\n"
"Try contacting the proposer and ask them to verify the contract.\n"
"No further checks are being performed on this payload."
)
pp.pretty_print(error_message, pp.Colors.FAILURE)
pp.pprint(error_message, pp.Colors.FAILURE)
# Skip further checks for this proposal
continue

# Diff check
pp.pprint('Check 1 - Comparing payload contract and imports with the source of truth',
pp.Colors.INFO, pp.Heading.HEADING_2)
missing_files = Checks.DiffCheck(customer, chain, proposal_address, source_codes).find_diffs()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# Review diff check
pp.pprint(f'Check 2 - Verifying missing files against customer review repo',
pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.ReviewDiffCheck(customer, chain, proposal_address, missing_files).find_diffs()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# Global variables check
pp.pprint('Check 3 - Global variables', pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.GlobalVariableCheck(customer, chain, proposal_address, missing_files).check_global_variables()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# Feed price check
pp.pprint('Check 4 - Explicit addresses validation', pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.PriceFeedCheck(customer, chain, proposal_address, missing_files, providers).verify_price_feed()

pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)

# New listing check
pp.pprint('Check 5 - First deposit for new listing', pp.Colors.INFO, pp.Heading.HEADING_2)
Checks.NewListingCheck(customer, chain, proposal_address, missing_files).new_listing_check()
pp.pprint(pp.SEPARATOR_LINE, pp.Colors.INFO)
6 changes: 3 additions & 3 deletions Quorum/entry_points/implementations/ipfs_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def run_ipfs_validator(args: argparse.Namespace):
)

if answer.incompatibilities:
pp.pretty_print("Found incompatibilities:", pp.Colors.FAILURE)
pp.pprint("Found incompatibilities:", pp.Colors.FAILURE)
for incompatibility in answer.incompatibilities:
pp.pretty_print(incompatibility, pp.Colors.FAILURE)
pp.pprint(incompatibility, pp.Colors.FAILURE)
else:
pp.pretty_print("LLM found no incompatibilities. Please Check manually.", pp.Colors.WARNING)
pp.pprint("LLM found no incompatibilities. Please Check manually.", pp.Colors.WARNING)
2 changes: 1 addition & 1 deletion Quorum/entry_points/implementations/setup_quorum.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def run_setup_quorum(args: argparse.Namespace):
OSError: If there are filesystem permission issues
shutil.Error: If file copy operations fail
"""
templates_dir = Path(__file__).parent.parent / 'templates'
templates_dir = Path(__file__).parent.parent.parent / 'templates'
target_dir = args.working_dir.resolve()

if not target_dir.exists():
Expand Down
2 changes: 1 addition & 1 deletion Quorum/utils/arg_validations.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ def load_config(config_path: str) -> dict[str, Any] | None:
config_data = json.load(file)
return config_data
except (FileNotFoundError, JSONDecodeError) as e:
pp.pretty_print(f"Failed to parse given config file {config_path}:\n{e}", pp.Colors.FAILURE)
pp.pprint(f"Failed to parse given config file {config_path}:\n{e}", pp.Colors.FAILURE)
3 changes: 0 additions & 3 deletions Quorum/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

GROUND_TRUTH_PATH = MAIN_PATH / "ground_truth.json"

if not GROUND_TRUTH_PATH.exists():
raise FileNotFoundError(f"Ground truth file not found at {GROUND_TRUTH_PATH}")

ANTHROPIC_API_KEY = os.getenv('ANTHROPIC_API_KEY')
if not ANTHROPIC_API_KEY:
pp.pprint(
Expand Down
9 changes: 7 additions & 2 deletions Quorum/utils/config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
import Quorum.utils.pretty_printer as pp
import Quorum.apis.price_feeds as price_feeds


SUPPORTED_PROVIDERS = set(price_feeds.PriceFeedProvider.__members__.values())

with open(config.GROUND_TRUTH_PATH) as f:
config_data = json.load(f)

def load_customer_config(customer: str) -> Dict[str, any]:
"""
Expand All @@ -20,6 +19,12 @@ def load_customer_config(customer: str) -> Dict[str, any]:
Returns:
Dict[str, any]: The customer configuration data.
"""
if not config.GROUND_TRUTH_PATH.exists():
raise FileNotFoundError(f"Ground truth file not found at {config.GROUND_TRUTH_PATH}")

with open(config.GROUND_TRUTH_PATH) as f:
config_data = json.load(f)

customer_config = config_data.get(customer)
if not customer_config:
pp.pprint(f"Customer {customer} not found in ground truth data.", pp.Colors.FAILURE)
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250107.002809.782834
20250107.120144.487580

0 comments on commit db68698

Please sign in to comment.