Automated maintenance update - Mo 30 Mär 2026 07:52:40 CEST
All checks were successful
CLI Tests / test-cli (push) Successful in 1m30s
Documentation Validation / validate-docs (push) Successful in 26s
Integration Tests / test-service-integration (push) Successful in 1m0s
Python Tests / test-python (push) Successful in 1m16s
Security Scanning / security-scan (push) Successful in 1m3s

This commit is contained in:
2026-03-30 07:52:40 +02:00
parent 430120e94c
commit 5775b51969
9 changed files with 1942 additions and 87 deletions

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Load genesis accounts into the blockchain database"""
import json
import sys
from pathlib import Path
# Add the src directory to the path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
from aitbc_chain.database import session_scope
from aitbc_chain.models import Account
from aitbc_chain.config import settings
def load_genesis_accounts(genesis_path: str = "data/devnet/genesis.json"):
"""Load accounts from genesis file into database"""
# Read genesis file
genesis_file = Path(genesis_path)
if not genesis_file.exists():
print(f"Error: Genesis file not found at {genesis_path}")
return False
with open(genesis_file) as f:
genesis = json.load(f)
chain_id = genesis.get("chain_id", settings.chain_id)
# Load accounts
with session_scope() as session:
for account_data in genesis.get("allocations", []):
address = account_data["address"]
balance = account_data["balance"]
nonce = account_data.get("nonce", 0)
# Check if account already exists
existing = session.query(Account).filter_by(chain_id=chain_id, address=address).first()
if existing:
existing.balance = balance
existing.nonce = nonce
print(f"Updated account {address}: balance={balance}")
else:
account = Account(chain_id=chain_id, address=address, balance=balance, nonce=nonce)
session.add(account)
print(f"Created account {address}: balance={balance}")
session.commit()
print("\\nGenesis accounts loaded successfully!")
return True
if __name__ == "__main__":
if len(sys.argv) > 1:
genesis_path = sys.argv[1]
else:
genesis_path = "data/devnet/genesis.json"
success = load_genesis_accounts(genesis_path)
sys.exit(0 if success else 1)

View File

@@ -17,11 +17,24 @@ from ..mempool import get_mempool
from ..metrics import metrics_registry
from ..models import Account, Block, Receipt, Transaction
from ..logger import get_logger
from ..contracts.agent_messaging_contract import messaging_contract
_logger = get_logger(__name__)
router = APIRouter()
# Global variable to store the PoA proposer
_poa_proposer = None
def set_poa_proposer(proposer):
"""Set the global PoA proposer instance"""
global _poa_proposer
_poa_proposer = proposer
def get_poa_proposer():
"""Get the global PoA proposer instance"""
return _poa_proposer
def get_chain_id(chain_id: str = None) -> str:
"""Get chain_id from parameter or use default from settings"""
if chain_id is None:
@@ -130,6 +143,87 @@ async def get_block(height: int) -> Dict[str, Any]:
}
@router.post("/transaction", summary="Submit transaction")
async def submit_transaction(tx_data: dict) -> Dict[str, Any]:
"""Submit a new transaction to the mempool"""
from ..mempool import get_mempool
from ..models import Transaction
try:
mempool = get_mempool()
# Create transaction data as dictionary
tx_data_dict = {
"chain_id": tx_data.get("chain_id", "ait-mainnet"),
"from": tx_data["from"],
"to": tx_data["to"],
"amount": tx_data["amount"],
"fee": tx_data.get("fee", 10),
"nonce": tx_data.get("nonce", 0),
"payload": tx_data.get("payload", "0x"),
"signature": tx_data.get("signature")
}
# Add to mempool
tx_hash = mempool.add(tx_data_dict)
return {
"success": True,
"transaction_hash": tx_hash,
"message": "Transaction submitted to mempool"
}
except Exception as e:
_logger.error("Failed to submit transaction", extra={"error": str(e)})
raise HTTPException(status_code=400, detail=f"Failed to submit transaction: {str(e)}")
@router.get("/mempool", summary="Get pending transactions")
async def get_mempool(chain_id: str = None, limit: int = 100) -> Dict[str, Any]:
"""Get pending transactions from mempool"""
from ..mempool import get_mempool
try:
mempool = get_mempool()
pending_txs = mempool.get_pending_transactions(chain_id=chain_id, limit=limit)
return {
"success": True,
"transactions": pending_txs,
"count": len(pending_txs)
}
except Exception as e:
_logger.error("Failed to get mempool", extra={"error": str(e)})
raise HTTPException(status_code=500, detail=f"Failed to get mempool: {str(e)}")
@router.get("/accounts/{address}", summary="Get account information")
async def get_account(address: str) -> Dict[str, Any]:
"""Get account information including balance"""
from ..models import Account
try:
with session_scope() as session:
account = session.exec(select(Account).where(Account.address == address)).first()
if account is None:
return {
"address": address,
"balance": 0,
"nonce": 0,
"exists": False
}
return {
"address": account.address,
"balance": account.balance,
"nonce": account.nonce,
"exists": True
}
except Exception as e:
_logger.error("Failed to get account", extra={"error": str(e), "address": address})
raise HTTPException(status_code=500, detail=f"Failed to get account: {str(e)}")
@router.get("/blocks-range", summary="Get blocks in height range")
# Working contract endpoints
async def get_messaging_contract_state() -> Dict[str, Any]:
@@ -213,8 +307,7 @@ async def moderate_message(message_id: str, moderation_data: dict) -> Dict[str,
moderation_data.get("action"),
moderation_data.get("reason", "")
)
EOF && echo "✅ Messaging contract endpoints added" && echo -e "\n2. Restarting blockchain node to load new endpoints:" && systemctl restart aitbc-blockchain-node && sleep 5 && echo "✅ Blockchain node restarted" && echo -e "\n3. Testing messaging endpoints:" && echo " Testing forum topics endpoint:" && curl -s http://localhost:8006/rpc/messaging/topics | jq .total_topics && echo -e "\n Testing message search endpoint:" && curl -s "http://localhost:8006/rpc/messaging/messages/search?query=test" | jq .total_matches
from .contracts.agent_messaging_contract import messaging_contract
@router.get("/rpc/messaging/topics", summary="Get forum topics")
async def get_forum_topics(limit: int = 50, offset: int = 0, sort_by: str = "last_activity") -> Dict[str, Any]:
"""Get list of forum topics"""
@@ -270,9 +363,6 @@ async def post_message(message_data: dict) -> Dict[str, Any]:
message_data.get("message_type", "post"),
message_data.get("parent_message_id")
)
EOF && echo "✅ Added working endpoints" && echo -e "\n6. Restarting node with fixed configuration:" && systemctl restart aitbc-blockchain-node && sleep 5 && echo "✅ Node restarted" && echo -e "\n7. Testing fixed endpoints:" && curl -s http://localhost:8006/rpc/messaging/topics | jq .success && echo -e "\n8. Creating test topic:" && curl -s -X POST http://localhost:8006/rpc/messaging/topics/create \
-H "Content-Type: application/json" \
-d '{"agent_id": "test_agent", "agent_address": "ait1test_agent", "title": "Fixed Test Topic", "description": "Testing after fixes", "tags": ["test"]}' | jq .topic_id
# Agent messaging contract endpoints
@router.get("/rpc/messaging/topics", summary="Get forum topics")
@@ -302,6 +392,3 @@ async def post_message(message_data: dict) -> Dict[str, Any]:
message_data.get("message_type", "post"),
message_data.get("parent_message_id")
)
EOF && echo "✅ Added clean endpoints" && echo -e "\n5. Restarting node:" && systemctl restart aitbc-blockchain-node && sleep 5 && echo "✅ Node restarted" && echo -e "\n6. Testing messaging contract:" && curl -s http://localhost:8006/rpc/messaging/topics | jq .success && echo -e "\n7. Creating test topic:" && curl -s -X POST http://localhost:8006/rpc/messaging/topics/create \
-H "Content-Type: application/json" \
-d '{"agent_id": "test_agent", "agent_address": "ait1test_agent", "title": "Working Test Topic", "description": "Testing after syntax fix", "tags": ["test"]}' | jq .topic_id