Add blockchain event bridge service with smart contract event integration
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 2s
Integration Tests / test-service-integration (push) Failing after 15s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 2s
P2P Network Verification / p2p-verification (push) Successful in 2s
Python Tests / test-python (push) Successful in 12s
Security Scanning / security-scan (push) Successful in 41s
Systemd Sync / sync-systemd (push) Successful in 7s
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 2s
Integration Tests / test-service-integration (push) Failing after 15s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 2s
P2P Network Verification / p2p-verification (push) Successful in 2s
Python Tests / test-python (push) Successful in 12s
Security Scanning / security-scan (push) Successful in 41s
Systemd Sync / sync-systemd (push) Successful in 7s
- Phase 1: Core bridge service with gossip broker subscription - Phase 2: Smart contract event integration via eth_getLogs RPC endpoint - Add contract event subscriber for AgentStaking, PerformanceVerifier, Marketplace, Bounty, CrossChainBridge - Add contract event handlers in agent_daemon.py and marketplace.py - Add systemd service file for blockchain-event-bridge - Update blockchain node router.py with eth_getLogs endpoint - Add configuration for contract addresses - Add tests for contract subscriber and handlers (27 tests passing)
This commit is contained in:
@@ -1030,3 +1030,82 @@ async def force_sync(peer_data: dict) -> Dict[str, Any]:
|
||||
except Exception as e:
|
||||
_logger.error(f"Error forcing sync: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Failed to force sync: {str(e)}")
|
||||
|
||||
|
||||
class GetLogsRequest(BaseModel):
|
||||
"""Request model for eth_getLogs RPC endpoint."""
|
||||
address: Optional[str] = Field(None, description="Contract address to filter logs")
|
||||
from_block: Optional[int] = Field(None, description="Starting block height")
|
||||
to_block: Optional[int] = Field(None, description="Ending block height")
|
||||
topics: Optional[List[str]] = Field(None, description="Event topics to filter")
|
||||
|
||||
|
||||
class LogEntry(BaseModel):
|
||||
"""Single log entry from smart contract event."""
|
||||
address: str
|
||||
topics: List[str]
|
||||
data: str
|
||||
block_number: int
|
||||
transaction_hash: str
|
||||
log_index: int
|
||||
|
||||
|
||||
class GetLogsResponse(BaseModel):
|
||||
"""Response model for eth_getLogs RPC endpoint."""
|
||||
logs: List[LogEntry]
|
||||
count: int
|
||||
|
||||
|
||||
@router.post("/eth_getLogs", summary="Query smart contract event logs")
|
||||
async def get_logs(
|
||||
request: GetLogsRequest,
|
||||
chain_id: Optional[str] = None
|
||||
) -> GetLogsResponse:
|
||||
"""
|
||||
Query smart contract event logs using eth_getLogs-compatible endpoint.
|
||||
Filters Receipt model for logs matching contract address and event topics.
|
||||
"""
|
||||
chain_id = get_chain_id(chain_id)
|
||||
|
||||
with session_scope() as session:
|
||||
# Build query for receipts
|
||||
query = select(Receipt).where(Receipt.chain_id == chain_id)
|
||||
|
||||
# Filter by block range
|
||||
if request.from_block is not None:
|
||||
query = query.where(Receipt.block_height >= request.from_block)
|
||||
if request.to_block is not None:
|
||||
query = query.where(Receipt.block_height <= request.to_block)
|
||||
|
||||
# Execute query
|
||||
receipts = session.execute(query).scalars().all()
|
||||
|
||||
logs = []
|
||||
for receipt in receipts:
|
||||
# Extract event logs from receipt payload
|
||||
payload = receipt.payload or {}
|
||||
events = payload.get("events", [])
|
||||
|
||||
for event in events:
|
||||
# Filter by contract address if specified
|
||||
if request.address and event.get("address") != request.address:
|
||||
continue
|
||||
|
||||
# Filter by topics if specified
|
||||
if request.topics:
|
||||
event_topics = event.get("topics", [])
|
||||
if not any(topic in event_topics for topic in request.topics):
|
||||
continue
|
||||
|
||||
# Create log entry
|
||||
log_entry = LogEntry(
|
||||
address=event.get("address", ""),
|
||||
topics=event.get("topics", []),
|
||||
data=str(event.get("data", "")),
|
||||
block_number=receipt.block_height or 0,
|
||||
transaction_hash=receipt.receipt_id,
|
||||
log_index=event.get("logIndex", 0)
|
||||
)
|
||||
logs.append(log_entry)
|
||||
|
||||
return GetLogsResponse(logs=logs, count=len(logs))
|
||||
|
||||
Reference in New Issue
Block a user