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

- 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:
aitbc
2026-04-23 10:58:00 +02:00
parent ab45a81bd7
commit 90edea2da2
29 changed files with 3704 additions and 0 deletions

View File

@@ -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))