idea165-commonsgrid-communi.../idea165_commonsgrid_communi.../governance.py

67 lines
2.4 KiB
Python

import json
import hashlib
import time
from typing import Dict, List
class GovernanceBlock:
def __init__(self, version: int, policy_blob: str, approvals: Dict[str, str], timestamp: float = None):
self.version = version
self.policy_blob = policy_blob
self.approvals = approvals # signer_id -> signature (simulated)
self.timestamp = timestamp or time.time()
self.block_hash = self.compute_hash()
def compute_hash(self) -> str:
m = hashlib.sha256()
m.update(str(self.version).encode())
m.update(self.policy_blob.encode())
m.update(json.dumps(self.approvals, sort_keys=True).encode())
m.update(str(self.timestamp).encode())
return m.hexdigest()
def to_dict(self) -> Dict:
return {
"version": self.version,
"policy_blob": self.policy_blob,
"approvals": self.approvals,
"timestamp": self.timestamp,
"block_hash": self.block_hash,
}
class GovernanceLedger:
def __init__(self, quorum: int = 1):
self.blocks: List[GovernanceBlock] = []
self.quorum = quorum
self._latest_hash = None
def append_block(self, policy_blob: str, approvals: Dict[str, str]) -> GovernanceBlock:
version = len(self.blocks) + 1
block = GovernanceBlock(version, policy_blob, approvals)
if not self._validate_approvals(approvals):
raise ValueError("Approvals do not meet quorum or have invalid signers")
self.blocks.append(block)
self._latest_hash = block.block_hash
return block
def _validate_approvals(self, approvals: Dict[str, str]) -> bool:
# Simple quorum check: number of approvals >= quorum
return len(approvals) >= self.quorum
def verify_chain(self) -> bool:
# Basic chain integrity: each block hash must equal the recomputed hash
for i, b in enumerate(self.blocks):
if b.block_hash != b.compute_hash():
return False
if i > 0 and self.blocks[i-1].block_hash != self.blocks[i].block_hash:
# In a real DAG/log, you'd verify hashes linking; here we ensure determinism
continue
return True
def last_block(self) -> GovernanceBlock:
return self.blocks[-1] if self.blocks else None
def to_list(self) -> List[Dict]:
return [b.to_dict() for b in self.blocks]